Skip to content

Build Process

The web frontend build is handled by web/build.ts using Bun's built-in bundler.

Build Script

The build script (web/build.ts) compiles the TypeScript source into a single JavaScript bundle with the following steps:

  1. Read configuration: In dev mode, reads config/main.config.json (legacy fallback: main.config.json) for endpoint URLs. In release mode, uses fixed production values.
  2. Define constants: Injects build-time constants via Bun.build defines:
    • CERT_ISSUER — JWT issuer for token validation
    • CERT_AUDIENCE — JWT audience
    • SERVER_ENDPOINT — HTTP API base URL
    • SERVER_WS_ENDPOINT — WebSocket endpoint URL
    • VERSION — Build version string
    • BUILD_DATE — Build timestamp
  3. Bundle: Compiles src/web.ts and all imports into build/js/web.js with external sourcemaps

Build Modes

Development

bash
cd web
bun run dev

Reads endpoints from config/main.config.json (legacy fallback: project-root main.config.json). Uses concurrently to run:

  • nodemon watching src/ for changes → rebuilds on save
  • live-server on port 8090 serving build/

Production

bash
cd web
bun run build
# or from root:
bun build:server   # includes web build

In release mode (triggered by --release flag), the build script uses production values from the active brand instead of config file endpoint values. The HTTP and WebSocket endpoints are set to relative paths ("./" and "./ws") so the frontend works at any mount point — whether served at the domain root (/) or behind a reverse proxy subpath (e.g. /safecall/app/). The browser resolves these relative to the page URL at runtime.

Output Structure

web/build/
├── index.html              # Main HTML page
├── css/
│   ├── styles.css          # Custom styles
│   ├── bulma.min.css       # Bulma CSS framework
│   └── fontawesome.min.css # Font Awesome icons
└── js/
    └── web.js              # Bundled application

Server Embedding

The built web files are embedded into the server binary during the server build process:

  1. scripts/build/generators/embeds.ts reads all files from web/build/
  2. Generates server/src/static_embeds.ts with Base64-encoded file contents
  3. The server serves these embedded files for static asset routes (/, /css/*, /js/*, etc.)

This means the production server is a single self-contained binary with the web UI built in.

Security Note

The config file is never included in the web build. Only specific, non-sensitive values (endpoint URLs, JWT issuer/audience) are injected as build-time constants. Sensitive credentials (passwords, MQTT credentials, KISS credentials) remain server-side only.