BRAIDGROUP
RESEARCH & DEV
57. Framework Docs

Deployment and CLI

Junction applications are built, run, and managed entirely through the braidc junction CLI. Apps can be deployed as compiled bytecode (.bx) for portable execution, or run directly from source during development.

CLI Reference

CommandDescription
braidc junction new <name>Scaffold a new Junction project with braid.toml, src/main.br, src/routes.br, and tests/ directory
braidc junction devStart development server on port 8080 with watch mode (auto-reload on file changes)
braidc junction build -o <file>Compile the Junction app into a .bx bytecode artifact for distribution
braidc junction runRun the Junction app (reads braid.toml for entrypoint, uses junction.serve())
braidc junction routesPrint all registered routes with their HTTP methods and paths
braidc junction checkValidate the project structure, braid.toml configuration, and syntax
braidc junction testRun all tests in the tests/ directory

Build to Bytecode (.bx)

Compile the application to a portable bytecode artifact for production. The .bx file bundles the compiled Braid bytecode and can be executed by the Braid VM without recompilation.

braidc junction build -o myapp.bx braidc run myapp.bx

Configuration

Command-Line Flags

The cli module parses arguments at startup. The following flags are available:

FlagDefaultDescription
-p, --port8080TCP port to listen on
-H, --host0.0.0.0Host address to bind to
-w, --workers1Number of worker processes
-l, --log-levelinfoLog level (debug, info, warn, error)
-e, --envproductionEnvironment name (development, staging, production)
-c, --config""Path to JSON config file
-h, --helpShow help message
-v, --versionShow version
braidc junction run --port 3000 --host 127.0.0.1 --log-level debug --env development

JSON Config File

{
    "port": 8080,
    "host": "0.0.0.0",
    "workers": 4,
    "log_level": "info",
    "env": "production"
}
braidc junction run --config production.json

Programmatic Configuration

import lib.frameworks.junction.cli;

fn main() {
    let raw_args = ["--port", "9090", "--env", "staging"];
    let config = cli.parse_args(raw_args);
    let errors = cli.validate_config(config);
    if (std.collections.length(errors) > 0) {
        let i = 0;
        while (i < std.collections.length(errors)) {
            std.io.stderr(errors[i] + "
");
            i = i + 1;
        }
        return;
    }
    // config["port"] == 9090, config["env"] == "staging"
}

Environment Variables

Use environment variables in your app via std.io.getenv() for sensitive configuration:

fn load_config() -&gt; object {
    let port_str = std.io.getenv("PORT");
    let port = 8080;
    if (port_str != null && port_str != "") {
        port = int(port_str);
    }
    return {
        "port": port,
        "host": std.io.getenv("HOST") ?? "0.0.0.0",
        "log_level": std.io.getenv("LOG_LEVEL") ?? "info",
        "env": std.io.getenv("ENV") ?? "production"
    };
}

Static File Serving for SPAs

Junction serves SPAs with a fallback-to-index.html pattern via the frontend_serving module. Place the frontend middleware before the router so static files short-circuit API routes.

import lib.frameworks.junction.frontend_serving;

let frontend = frontend_serving.new_frontend_server("./public");
frontend_serving.set_fallback(frontend, "index.html");
frontend_serving.set_index(frontend, "index.html");

junction.use_middleware(app, frontend_serving.frontend_middleware(frontend));

// API routes catch anything the frontend middleware passes through
junction.route(app, "GET", "/api/health", fn(req: Request) -&gt; Response {
    return junction.json({"status": "ok"}, 200);
});

Frontend server configuration options:

OptionDefaultDescription
root_dirrequiredRoot directory for static assets
index_fileindex.htmlDefault file for directory requests
fallback_fileindex.htmlSPA fallback for unmatched paths
cache_max_age3600Cache-Control max-age in seconds
directory_listingfalseEnable directory index listing
etag_enabledtrueGenerate ETag headers for static files
gzip_statictrueServe precompressed .gz variants

Production Hardening Checklist

  • Enable security headers — use_middleware(app, apply_security_headers) sets CSP, HSTS, X-Frame-Options, and more
  • Configure CORS — Restrict allowed_origins to specific domains, no wildcards in production
  • Rate limiting — Apply rate_limit_middleware() with sensible limits per endpoint
  • Request size limit — Set app.request_size_limit to prevent large payload attacks
  • CSRF protection — Enable csrf_middleware(app) for state-changing endpoints
  • Input validation — Register JSON schemas with register_schema() and validate with validate_request()
  • Sanitize inputs — Use sanitize_input() for reflected values, prevent_sql_injection() for database queries
  • Session security — Ensure secure and http_only flags are true on session cookies
  • Production logging — Set --log-level warn or error to reduce noise, or use JSON output format
  • Bytecode build — Compile to .bx for faster startup and distribution
  • Workers — Set --workers to match CPU count for parallel request handling
  • Timeout middleware — Prevent slow requests from consuming resources with timeout_middleware(ms)
  • HTTPS — Deploy behind a reverse proxy (nginx, Caddy) that terminates TLS
  • Audit logging — Use emit_audit_event() for sensitive operations (auth, data changes)

Example Junction Apps

TrustLedger API

A trust-score evaluation API with audit event logging and API key authentication. Located at examples/junction_apps/trustledger_api/.

// src/main.br
let app = junction.create_app({
    name: "trustledger_api",
    version: "1.0.0",
    env: "production"
});
junction.use_middleware(app, junction.apply_security_headers);
trustledger_routes.setup(app);
junction.serve(app, 8080);

SentinelOps Control Plane

A multi-tenant control plane managing services, deployments, policies, risk evaluation, and audit trails. Located at examples/junction_apps/sentinelops_control_plane/.

// src/main.br
import config;
import errors;
import storage;
import auth;
import metrics;
import routes;

let app = junction.create_app({
    name: "sentinelops_control_plane",
    version: "1.0.0",
    env: "production"
});
junction.use_middleware(app, junction.apply_security_headers);
storage.setup_storage(app);
routes.setup(app);
junction.serve(app, 8080);

Both examples demonstrate the standard Junction patterns: app creation, middleware registration, route setup in a separate module, and serving with serve(app, port).