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
| Command | Description |
|---|---|
braidc junction new <name> | Scaffold a new Junction project with braid.toml, src/main.br, src/routes.br, and tests/ directory |
braidc junction dev | Start 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 run | Run the Junction app (reads braid.toml for entrypoint, uses junction.serve()) |
braidc junction routes | Print all registered routes with their HTTP methods and paths |
braidc junction check | Validate the project structure, braid.toml configuration, and syntax |
braidc junction test | Run 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.bxConfiguration
Command-Line Flags
The cli module parses arguments at startup. The following flags are available:
| Flag | Default | Description |
|---|---|---|
-p, --port | 8080 | TCP port to listen on |
-H, --host | 0.0.0.0 | Host address to bind to |
-w, --workers | 1 | Number of worker processes |
-l, --log-level | info | Log level (debug, info, warn, error) |
-e, --env | production | Environment name (development, staging, production) |
-c, --config | "" | Path to JSON config file |
-h, --help | Show help message | |
-v, --version | Show version |
braidc junction run --port 3000 --host 127.0.0.1 --log-level debug --env developmentJSON Config File
{
"port": 8080,
"host": "0.0.0.0",
"workers": 4,
"log_level": "info",
"env": "production"
}braidc junction run --config production.jsonProgrammatic 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() -> 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) -> Response {
return junction.json({"status": "ok"}, 200);
});Frontend server configuration options:
| Option | Default | Description |
|---|---|---|
root_dir | required | Root directory for static assets |
index_file | index.html | Default file for directory requests |
fallback_file | index.html | SPA fallback for unmatched paths |
cache_max_age | 3600 | Cache-Control max-age in seconds |
directory_listing | false | Enable directory index listing |
etag_enabled | true | Generate ETag headers for static files |
gzip_static | true | Serve 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_originsto specific domains, no wildcards in production - Rate limiting — Apply
rate_limit_middleware()with sensible limits per endpoint - Request size limit — Set
app.request_size_limitto prevent large payload attacks - CSRF protection — Enable
csrf_middleware(app)for state-changing endpoints - Input validation — Register JSON schemas with
register_schema()and validate withvalidate_request() - Sanitize inputs — Use
sanitize_input()for reflected values,prevent_sql_injection()for database queries - Session security — Ensure
secureandhttp_onlyflags aretrueon session cookies - Production logging — Set
--log-level warnorerrorto reduce noise, or use JSON output format - Bytecode build — Compile to
.bxfor faster startup and distribution - Workers — Set
--workersto 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).