Build for production
Useforst build to compile Go output for deployment. Use forst run to compile and execute in one step.
Enable embedded invoke in ftconfig.json before building for production.
manifest.json.
.ts files into .forst/js/ as standalone JavaScript files. You do not need tsx at runtime when using compiled mode.
Where bundled modules live
Duringforst build, esbuild bundles each imported module into .forst/js/ under your project root. For example, legacy/payment.ts becomes .forst/js/legacy/payment.js.
The Go binary and manifest.json do not copy .forst/js/ beside the executable. Treat .forst/js/ as a separate deploy artifact.
The bridge resolves compiled .js files in this order.
FORST_BRIDGE_MODULES_DIRenvironment variablebridge.legacyModules.dirinftconfig.json- Default path
{FORST_ROOT}/.forst/js
FORST_BRIDGE_MODULES_DIR.
Choose how JavaScript runs
Setbridge.host in ftconfig.json to node, bun, or deno.
Run in bootstrap mode
Bootstrap mode is the default. Forst starts a dedicated JavaScript child process that runs@forst/runtime/dist/bootstrap.js.
Use bootstrap mode unless your JavaScript calls need to share memory with an existing web framework process.
.forst/node-bootstrap.sock.
Run in host mode
Use host mode when JavaScript calls must share memory with a running application. Examples include Prisma clients, global singletons, or routes inside Remix or Vite. Host mode runs RPC calls directly inside your application process.Preload register script
WhenhostMode is true, Go injects a preload script into your application process.
Signal readiness in custom entries
If your application needs time to initialize before accepting calls, importsignalForstAppReady.
Environment variables for socket RPC
Forst sets these variables automatically when spawning or attaching to the bridge.Keep host running during development
Duringforst dev, Forst keeps the bridge host process running while rebuilding Go code. This avoids restarting Vite or Remix every time you edit a .ft file.
The forst dev parent process starts the host. Each reloaded Go child attaches to FORST_BRIDGE_SOCKET using FORST_BRIDGE_ATTACH_ONLY=1.
Restrict allowed calls with manifests
Forst records every module and export your program can call during compilation. This allowlist is stored in the generated Go binary using theforst-node-manifest-v1 format.
At runtime, @forst/runtime checks every RPC request against the embedded manifest. Unregistered modules or exports are rejected immediately.
Only these RPC methods are allowed.
forst.node/initializeforst.node/callforst.node/callAsyncforst.node/genOpenforst.node/genNextforst.node/genNextBatchforst.node/genCloseforst.node/shutdown
.. or paths outside the project root are rejected.
How Forst maps TypeScript types
Forst reads TypeScript exports during compilation to verify signatures and generate Go wrapper code.
When a union contains unmappable types, Forst widens the type to
Object and emits a compiler warning.
Troubleshoot common errors
To see debug logs for spawn and RPC events, set
FORST_LOG_LEVEL=debug.
Migrate from implicit import policy
Older projects may have"importPolicy": "implicit" in ftconfig.json. Under implicit policy, any relative import can load .ts files without the js marker.
To migrate to explicit policy:
- Set
"importPolicy": "explicit"inftconfig.json. - Add
jsto every TypeScript import. - Rebuild and verify which binaries require JavaScript.
Caveats
forst/bridgertdependency: Generated Go code importsforst/bridgert. Yourgo.modmust resolve theforstmodule.- Whole program requirement: If any package in your import tree uses a JS import, the deployed binary requires a JavaScript runtime.
- Blocked calls: Unknown exports and message types are rejected by the bridge manifest.
- Type limits: Unmapped TypeScript unions widen to
Object.
Related
Bridge security
Dual allowlists, path jailing, and local socket isolation.
Import and call JavaScript
Import syntax, async promises, and generators.