Skip to content

feat(interop): support Bun and Deno as JavaScript bridge hosts - #190

Merged
haveyaseen merged 6 commits into
mainfrom
feat/js-interop-multi-host
Aug 23, 2026
Merged

feat(interop): support Bun and Deno as JavaScript bridge hosts#190
haveyaseen merged 6 commits into
mainfrom
feat/js-interop-multi-host

Conversation

@haveyaseen

@haveyaseen haveyaseen commented Aug 22, 2026

Copy link
Copy Markdown
Member

Projects can set javascript.host to bun or deno so the Node runtime bridge
spawns the chosen interpreter with host-specific argv, permissions, and RPC
transport. Bun and Deno bootstrap E2E tests run in CI via
test:bridge-host-e2e, with Deno pinned via .deno-version.

feat(interop)!: ship compiled legacy modules without tsx at runtime

Add javascript.legacyModules.format (compiled or typescript) and esbuild
precompile of legacy TypeScript into .forst/js at compile time. Production
defaults to compiled bundles, so deployed apps no longer require tsx unless
typescript format is explicitly chosen on Node. forst build -o copies
.forst/js beside the output binary.

BREAKING CHANGE: node.loader is deprecated; use javascript.legacyModules.format.
The default runtime mode is compiled JavaScript, not tsx-backed TypeScript source.
Set javascript.legacyModules.format to typescript to restore the previous behavior.

feat(imports): safe local names for node imports with LSP quickfixes

Node imports now derive and validate local binding names (reserved words,
invalid identifiers, collisions). The typechecker reports clear diagnostics
and the LSP offers quickfixes to apply suggested aliases. Examples and docs
use explicit import "./path" node syntax throughout.

Projects can set javascript.host to bun or deno so the Node runtime bridge
spawns the chosen interpreter with host-specific argv, permissions, and RPC
transport. Bun and Deno bootstrap E2E tests run in CI via
test:bridge-host-e2e, with Deno pinned via .deno-version.

feat(interop)!: ship compiled legacy modules without tsx at runtime

Add javascript.legacyModules.format (compiled or typescript) and esbuild
precompile of legacy TypeScript into .forst/js at compile time. Production
defaults to compiled bundles, so deployed apps no longer require tsx unless
typescript format is explicitly chosen on Node. forst build -o copies
.forst/js beside the output binary.

BREAKING CHANGE: node.loader is deprecated; use javascript.legacyModules.format.
The default runtime mode is compiled JavaScript, not tsx-backed TypeScript source.
Set javascript.legacyModules.format to typescript to restore the previous behavior.

feat(imports): safe local names for node imports with LSP quickfixes

Node imports now derive and validate local binding names (reserved words,
invalid identifiers, collisions). The typechecker reports clear diagnostics
and the LSP offers quickfixes to apply suggested aliases. Examples and docs
use explicit import "./path" node syntax throughout.
@mintlify

mintlify Bot commented Aug 22, 2026

Copy link
Copy Markdown

Preview deployment for your docs. Learn more about Mintlify Previews.

Project Status Preview Updated (UTC)
Forst 🟢 Ready View Preview Aug 22, 2026, 11:29 PM

💡 Tip: Enable Workflows to automatically generate PRs for you.

@coderabbitai

coderabbitai Bot commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

Important

Review skipped

Too many files!

This PR contains 431 files, which is 331 over the limit of 100.

To get a review, reduce the PR to 100 files or fewer by splitting it into smaller PRs or changing its base branch.

Upgrade to a paid plan to raise the limit.

Usage-priced reviews support at most 300 files.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: f77e6797-007c-4f2f-a6ac-5ab0a30eca7d

📥 Commits

Reviewing files that changed from the base of the PR and between 0627207 and e0b3a7d.

⛔ Files ignored due to path filters (4)
  • bun.lockb is excluded by !**/bun.lockb
  • examples/in/rfc/bridge-interop/remix-serve/bun.lock is excluded by !**/*.lock
  • forst/bridgert/go.sum is excluded by !**/*.sum
  • forst/bridgert/pb/wire.pb.go is excluded by !**/*.pb.go
📒 Files selected for processing (431)
  • .deno-version
  • .gitattributes
  • .github/actions/ci-go-bun-setup/action.yml
  • .github/workflows/lint-test-coverage.yml
  • .github/workflows/publish-packages.yml
  • .github/workflows/release.yml
  • .release-please-config.json
  • .release-please-manifest.json
  • CHANGELOG.md
  • README.md
  • ROADMAP.md
  • Taskfile.yml
  • docs/docs.json
  • docs/index.mdx
  • docs/installation.mdx
  • docs/interop/bridge.mdx
  • docs/interop/bridge/build-and-runtime.mdx
  • docs/interop/bridge/import-and-calls.mdx
  • docs/interop/bridge/security.mdx
  • docs/interop/go.mdx
  • docs/interop/invoke.mdx
  • docs/interop/invoke/call-forst.mdx
  • docs/interop/invoke/effect.mdx
  • docs/interop/invoke/generate-types.mdx
  • docs/interop/invoke/security.mdx
  • docs/interop/invoke/testing.mdx
  • docs/interop/node.mdx
  • docs/interop/node/call-javascript.mdx
  • docs/interop/node/invoke-security.mdx
  • docs/language/ensure-and-narrowing.mdx
  • docs/language/errors-and-result.mdx
  • docs/language/providers.mdx
  • docs/language/shapes-and-constraints.mdx
  • docs/language/type-guards.mdx
  • docs/language/union-and-intersection-types.mdx
  • docs/quickstart.mdx
  • docs/resources/llms.mdx
  • docs/resources/roadmap.mdx
  • docs/why.mdx
  • docs/workflow/cli.mdx
  • docs/workflow/dev-server.mdx
  • docs/workflow/editor.mdx
  • examples/README.md
  • examples/in/forst-generate-ts-examples.json
  • examples/in/rfc/bridge-interop/README.md
  • examples/in/rfc/bridge-interop/async/README.md
  • examples/in/rfc/bridge-interop/async/ftconfig.json
  • examples/in/rfc/bridge-interop/async/legacy/events.ts
  • examples/in/rfc/bridge-interop/async/legacy/payment.ts
  • examples/in/rfc/bridge-interop/async/main.ft
  • examples/in/rfc/bridge-interop/ftconfig.json
  • examples/in/rfc/bridge-interop/generators/README.md
  • examples/in/rfc/bridge-interop/generators/ftconfig.json
  • examples/in/rfc/bridge-interop/generators/legacy/generators.ts
  • examples/in/rfc/bridge-interop/generators/main.ft
  • examples/in/rfc/bridge-interop/host/README.md
  • examples/in/rfc/bridge-interop/host/app/server.mjs
  • examples/in/rfc/bridge-interop/host/ftconfig.json
  • examples/in/rfc/bridge-interop/host/legacy/counter.ts
  • examples/in/rfc/bridge-interop/host/main.ft
  • examples/in/rfc/bridge-interop/legacy/payment.ts
  • examples/in/rfc/bridge-interop/main.ft
  • examples/in/rfc/bridge-interop/modules/README.md
  • examples/in/rfc/bridge-interop/modules/ftconfig.json
  • examples/in/rfc/bridge-interop/modules/legacy/api/checkout.ts
  • examples/in/rfc/bridge-interop/modules/legacy/services/constants.ts
  • examples/in/rfc/bridge-interop/modules/legacy/services/payment.ts
  • examples/in/rfc/bridge-interop/modules/legacy/services/pricing.ts
  • examples/in/rfc/bridge-interop/modules/legacy/services/tax.ts
  • examples/in/rfc/bridge-interop/modules/legacy/utils/money.ts
  • examples/in/rfc/bridge-interop/modules/main.ft
  • examples/in/rfc/bridge-interop/multi-package-dev/README.md
  • examples/in/rfc/bridge-interop/multi-package-dev/auth/auth.ft
  • examples/in/rfc/bridge-interop/multi-package-dev/ftconfig.json
  • examples/in/rfc/bridge-interop/multi-package-dev/go.mod
  • examples/in/rfc/bridge-interop/multi-package-dev/host.ts
  • examples/in/rfc/bridge-interop/multi-package-dev/main/main.ft
  • examples/in/rfc/bridge-interop/multi-package-dev/scripts/host.mjs
  • examples/in/rfc/bridge-interop/multi-package-dev/types/types.ft
  • examples/in/rfc/bridge-interop/promises/README.md
  • examples/in/rfc/bridge-interop/promises/ftconfig.json
  • examples/in/rfc/bridge-interop/promises/legacy/payment.ts
  • examples/in/rfc/bridge-interop/promises/main.ft
  • examples/in/rfc/bridge-interop/remix-serve/.forst-gomod/go.mod
  • examples/in/rfc/bridge-interop/remix-serve/.gitignore
  • examples/in/rfc/bridge-interop/remix-serve/README.md
  • examples/in/rfc/bridge-interop/remix-serve/app/entry.client.tsx
  • examples/in/rfc/bridge-interop/remix-serve/app/entry.server.tsx
  • examples/in/rfc/bridge-interop/remix-serve/app/lib/forst-client.ts
  • examples/in/rfc/bridge-interop/remix-serve/app/lib/log.server.ts
  • examples/in/rfc/bridge-interop/remix-serve/app/root.tsx
  • examples/in/rfc/bridge-interop/remix-serve/app/routes/_index.tsx
  • examples/in/rfc/bridge-interop/remix-serve/app/routes/api.health.tsx
  • examples/in/rfc/bridge-interop/remix-serve/e2e/client.test.ts
  • examples/in/rfc/bridge-interop/remix-serve/ftconfig.json
  • examples/in/rfc/bridge-interop/remix-serve/legacy/activity.ts
  • examples/in/rfc/bridge-interop/remix-serve/legacy/todos.ts
  • examples/in/rfc/bridge-interop/remix-serve/main/api.ft
  • examples/in/rfc/bridge-interop/remix-serve/main/main.ft
  • examples/in/rfc/bridge-interop/remix-serve/main/types.ft
  • examples/in/rfc/bridge-interop/remix-serve/package.json
  • examples/in/rfc/bridge-interop/remix-serve/tsconfig.json
  • examples/in/rfc/bridge-interop/remix-serve/vite.config.ts
  • examples/in/rfc/bridge-interop/sync/README.md
  • examples/in/rfc/bridge-interop/sync/ftconfig.json
  • examples/in/rfc/bridge-interop/sync/legacy/payment.ts
  • examples/in/rfc/bridge-interop/sync/main.ft
  • examples/in/rfc/embedded-invoke/README.md
  • examples/out/rfc/bridge-interop/async/main.go
  • examples/out/rfc/bridge-interop/async/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/generators/main.go
  • examples/out/rfc/bridge-interop/generators/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/host/main.go
  • examples/out/rfc/bridge-interop/host/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/main.go
  • examples/out/rfc/bridge-interop/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/modules/main.go
  • examples/out/rfc/bridge-interop/modules/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/multi-package-dev/auth/auth.gen.go
  • examples/out/rfc/bridge-interop/multi-package-dev/main.go
  • examples/out/rfc/bridge-interop/multi-package-dev/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/multi-package-dev/main_forst_1_invoke_server.gen.go
  • examples/out/rfc/bridge-interop/promises/main.go
  • examples/out/rfc/bridge-interop/promises/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/remix-serve/main.go
  • examples/out/rfc/bridge-interop/remix-serve/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/bridge-interop/remix-serve/main_forst_1_invoke_server.gen.go
  • examples/out/rfc/bridge-interop/sync/main.go
  • examples/out/rfc/bridge-interop/sync/main_forst_0_bridge_runtime.gen.go
  • examples/out/rfc/node-interop/async/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/generators/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/host/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/modules/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/multi-package-dev/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/promises/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/remix-serve/main_forst_0_node_runtime.gen.go
  • examples/out/rfc/node-interop/sync/main_forst_0_node_runtime.gen.go
  • forst/bridgert/bootstrap_socket_test.go
  • forst/bridgert/bridge_host_e2e_test.go
  • forst/bridgert/bun_host_test.go
  • forst/bridgert/call_async.go
  • forst/bridgert/call_async_test.go
  • forst/bridgert/call_sync.go
  • forst/bridgert/call_sync_test.go
  • forst/bridgert/client.go
  • forst/bridgert/client_test.go
  • forst/bridgert/codec.go
  • forst/bridgert/codec_test.go
  • forst/bridgert/compiled_modules_integration_test.go
  • forst/bridgert/configure.go
  • forst/bridgert/configure_modules_dir_test.go
  • forst/bridgert/configure_test.go
  • forst/bridgert/deno_host_test.go
  • forst/bridgert/errors.go
  • forst/bridgert/errors_test.go
  • forst/bridgert/frame.go
  • forst/bridgert/frame_test.go
  • forst/bridgert/generator.go
  • forst/bridgert/generator_bench_test.go
  • forst/bridgert/generator_integration_test.go
  • forst/bridgert/host.go
  • forst/bridgert/host_integration_test.go
  • forst/bridgert/host_invoke_auth_prepare.go
  • forst/bridgert/host_invoke_auth_relay.go
  • forst/bridgert/host_invoke_auth_relay_test.go
  • forst/bridgert/host_invoke_auth_setup.go
  • forst/bridgert/host_invoke_auth_setup_other.go
  • forst/bridgert/host_invoke_auth_setup_test.go
  • forst/bridgert/host_invoke_auth_setup_unix.go
  • forst/bridgert/host_js.go
  • forst/bridgert/host_lifecycle.go
  • forst/bridgert/host_lifecycle_js.go
  • forst/bridgert/host_lifecycle_setsid_test.go
  • forst/bridgert/host_lifecycle_test.go
  • forst/bridgert/host_lifecycle_unix.go
  • forst/bridgert/host_lifecycle_windows.go
  • forst/bridgert/host_test.go
  • forst/bridgert/host_unix.go
  • forst/bridgert/host_windows.go
  • forst/bridgert/host_worker_test.go
  • forst/bridgert/integration_test.go
  • forst/bridgert/manifest.go
  • forst/bridgert/manifest_test.go
  • forst/bridgert/marker.go
  • forst/bridgert/marker_test.go
  • forst/bridgert/node_interop_modules_test.go
  • forst/bridgert/pb/wire_pb_test.go
  • forst/bridgert/process.go
  • forst/bridgert/process_forward_test.go
  • forst/bridgert/process_terminate_test.go
  • forst/bridgert/process_wait_test.go
  • forst/bridgert/protocol.go
  • forst/bridgert/shutdown.go
  • forst/bridgert/spawn.go
  • forst/bridgert/spawn_hooks.go
  • forst/bridgert/spawn_hooks_test.go
  • forst/bridgert/spawn_test.go
  • forst/bridgert/supervisor.go
  • forst/bridgert/supervisor_death_test.go
  • forst/bridgert/supervisor_test.go
  • forst/bridgert/test_bridge_test.go
  • forst/bridgert/testdata/rpc/call_request.json
  • forst/bridgert/testdata/rpc/call_response.json
  • forst/bridgert/testdata/rpc/forbidden_error.json
  • forst/bridgert/testdata/rpc/initialize_request.json
  • forst/bridgert/testdata/rpc/initialize_response.json
  • forst/bridgert/testdata/rpc/method_not_found_error.json
  • forst/bridgert/testdata/rpc/ping_request.json
  • forst/bridgert/testdata/rpc/ping_response.json
  • forst/bridgert/testdata/rpc/shutdown_request.json
  • forst/bridgert/testdata/rpc/shutdown_response.json
  • forst/bridgert/tsx_loader.go
  • forst/bridgert/tsx_loader_test.go
  • forst/bridgert/wire_protocol.go
  • forst/cmd/forst/build_hostmode_integration_test.go
  • forst/cmd/forst/dev_server_runtime_embedded_test.go
  • forst/cmd/forst/embedded_invoke_goldens_test.go
  • forst/cmd/forst/generate_client_package.go
  • forst/cmd/forst/generate_layout_audit_test.go
  • forst/cmd/forst/golden_go_build_test.go
  • forst/cmd/forst/lsp/error_position.go
  • forst/cmd/forst/lsp/formatting.go
  • forst/cmd/forst/lsp/hover_completion.go
  • forst/cmd/forst/lsp/hover_completion_test.go
  • forst/cmd/forst/lsp/import_quickfix.go
  • forst/cmd/forst/lsp/import_quickfix_test.go
  • forst/cmd/forst/lsp/node_definition.go
  • forst/cmd/forst/lsp/node_definition_test.go
  • forst/cmd/forst/main.go
  • forst/cmd/forst/main_test.go
  • forst/cmd/forst/node_interop_goldens_test.go
  • forst/cmd/forst/node_interop_scaffold_test.go
  • forst/cmd/forst/update_examples_goldens_test.go
  • forst/internal/ast/import.go
  • forst/internal/bridgeinterop/index_types.go
  • forst/internal/bridgeinterop/index_v1.go
  • forst/internal/bridgeinterop/indexer.go
  • forst/internal/bridgeinterop/indexer_test.go
  • forst/internal/bridgeinterop/manifest_build.go
  • forst/internal/bridgeinterop/manifest_contract_test.go
  • forst/internal/bridgeinterop/manifest_v1.go
  • forst/internal/bridgeinterop/manifest_v1_test.go
  • forst/internal/bridgeinterop/needs_runtime.go
  • forst/internal/bridgeinterop/needs_runtime_test.go
  • forst/internal/bridgeinterop/node_index_resolver.go
  • forst/internal/bridgeinterop/node_index_resolver_test.go
  • forst/internal/bridgeinterop/precompile.go
  • forst/internal/bridgeinterop/precompile_test.go
  • forst/internal/bridgeinterop/resolution.go
  • forst/internal/bridgeinterop/resolution_test.go
  • forst/internal/bridgeinterop/type_mapping_reverse.go
  • forst/internal/bridgeinterop/type_mapping_reverse_test.go
  • forst/internal/codegen/layout/layout.go
  • forst/internal/codegen/layout/layout_test.go
  • forst/internal/compiler/args.go
  • forst/internal/compiler/args_test.go
  • forst/internal/compiler/build_program.go
  • forst/internal/compiler/compile_pipeline.go
  • forst/internal/compiler/compile_pipeline_invoke_test.go
  • forst/internal/compiler/compile_pipeline_node_interop_test.go
  • forst/internal/compiler/compile_pipeline_test.go
  • forst/internal/compiler/compile_profile_test.go
  • forst/internal/compiler/compiler.go
  • forst/internal/compiler/compiler_test.go
  • forst/internal/compiler/generate_go.go
  • forst/internal/compiler/module_providers.go
  • forst/internal/compiler/node_interop_modules_test.go
  • forst/internal/compiler/node_interop_sync_test.go
  • forst/internal/compiler/package.go
  • forst/internal/compiler/run_background.go
  • forst/internal/compiler/run_background_stopopts_test.go
  • forst/internal/compiler/run_background_test.go
  • forst/internal/compiler/watch.go
  • forst/internal/devserver/child_pid.go
  • forst/internal/devserver/host_invoke_auth.go
  • forst/internal/devserver/host_orchestrator.go
  • forst/internal/devserver/host_orchestrator_test.go
  • forst/internal/devserver/profile.go
  • forst/internal/devserver/profile_test.go
  • forst/internal/devserver/reload_monitor_test.go
  • forst/internal/devserver/reload_node_reattach_test.go
  • forst/internal/devserver/runtime.go
  • forst/internal/devserver/watch.go
  • forst/internal/ftconfig/bridge.go
  • forst/internal/ftconfig/bridge_test.go
  • forst/internal/ftconfig/ftconfig.go
  • forst/internal/ftconfig/ftconfig_test.go
  • forst/internal/goload/modroot.go
  • forst/internal/importlocal/binding.go
  • forst/internal/importlocal/binding_test.go
  • forst/internal/importlocal/derive.go
  • forst/internal/importlocal/derive_test.go
  • forst/internal/importlocal/format.go
  • forst/internal/importlocal/kind.go
  • forst/internal/importlocal/suggest.go
  • forst/internal/importlocal/suggest_format_test.go
  • forst/internal/importlocal/taken.go
  • forst/internal/importlocal/taken_test.go
  • forst/internal/importlocal/validate.go
  • forst/internal/importlocal/validate_test.go
  • forst/internal/modulecheck/find_forst_files_test.go
  • forst/internal/modulecheck/module_providers.go
  • forst/internal/modulecheck/stages.go
  • forst/internal/nodeinterop/indexer_test.go
  • forst/internal/parser/imports.go
  • forst/internal/parser/imports_test.go
  • forst/internal/printer/printer.go
  • forst/internal/programbuild/manifest.go
  • forst/internal/project/clean.go
  • forst/internal/transformer/go/invoke_shutdown_main.go
  • forst/internal/transformer/go/node_bridge.go
  • forst/internal/transformer/go/node_bridge_for.go
  • forst/internal/transformer/go/node_bridge_test.go
  • forst/internal/transformer/go/node_manifest.go
  • forst/internal/transformer/go/node_manifest_test.go
  • forst/internal/transformer/go/node_runtime_companion.go
  • forst/internal/transformer/go/transformer.go
  • forst/internal/transformer/ts/remix_serve_generate_test.go
  • forst/internal/typechecker/async_test.go
  • forst/internal/typechecker/bridge_call.go
  • forst/internal/typechecker/bridge_call_test.go
  • forst/internal/typechecker/bridge_imports.go
  • forst/internal/typechecker/bridge_runtime.go
  • forst/internal/typechecker/bridge_runtime_test.go
  • forst/internal/typechecker/go_interop.go
  • forst/internal/typechecker/import_locals.go
  • forst/internal/typechecker/import_locals_test.go
  • forst/internal/typechecker/node_call.go
  • forst/internal/typechecker/node_call_test.go
  • forst/internal/typechecker/node_field_hover_test.go
  • forst/internal/typechecker/node_hover.go
  • forst/internal/typechecker/node_hover_test.go
  • forst/internal/typechecker/node_imports_test.go
  • forst/internal/typechecker/node_interop_example_test.go
  • forst/internal/typechecker/node_interop_sync_test.go
  • forst/internal/typechecker/node_navigation.go
  • forst/internal/typechecker/node_navigation_test.go
  • forst/internal/typechecker/node_runtime.go
  • forst/internal/typechecker/node_runtime_test.go
  • forst/internal/typechecker/providers_engine.go
  • forst/internal/typechecker/typechecker.go
  • forst/invokeembed/embed.go
  • forst/invokeembed/embed_test.go
  • forst/nodert/host_js.go
  • package.json
  • packages/cli/CHANGELOG.md
  • packages/cli/README.md
  • packages/cli/src/invoke.ts
  • packages/cli/src/test-server.test.ts
  • packages/cli/src/test-server.ts
  • packages/runtime/CHANGELOG.md
  • packages/runtime/LICENSE
  • packages/runtime/README.md
  • packages/runtime/jsr.json
  • packages/runtime/package.json
  • packages/runtime/scripts/sync-jsr-version.mjs
  • packages/runtime/src/bootstrap.test.ts
  • packages/runtime/src/bootstrap.ts
  • packages/runtime/src/effect/layer.ts
  • packages/runtime/src/effect/opentelemetry.ts
  • packages/runtime/src/effect/resolve_layer.ts
  • packages/runtime/src/effect/run_process_main.ts
  • packages/runtime/src/effect/runtime.ts
  • packages/runtime/src/errors/cause.ts
  • packages/runtime/src/host.test.ts
  • packages/runtime/src/host.ts
  • packages/runtime/src/host/errors.ts
  • packages/runtime/src/host/register.cjs
  • packages/runtime/src/host/register.d.ts
  • packages/runtime/src/host/register.mjs
  • packages/runtime/src/host/register.test.ts
  • packages/runtime/src/index.ts
  • packages/runtime/src/indexer/cli.test.ts
  • packages/runtime/src/indexer/cli.ts
  • packages/runtime/src/indexer/emit-forst-index-v1.ts
  • packages/runtime/src/indexer/errors.ts
  • packages/runtime/src/indexer/project.ts
  • packages/runtime/src/manifest/schema.test.ts
  • packages/runtime/src/manifest/schema.ts
  • packages/runtime/src/policy/export_allowed.ts
  • packages/runtime/src/policy/manifest.ts
  • packages/runtime/src/policy/methods.ts
  • packages/runtime/src/policy/paths.ts
  • packages/runtime/src/rpc/dispatcher.ts
  • packages/runtime/src/rpc/errors.ts
  • packages/runtime/src/rpc/frame.ts
  • packages/runtime/src/rpc/frame_errors.ts
  • packages/runtime/src/rpc/proto_loop.ts
  • packages/runtime/src/rpc/protocol.ts
  • packages/runtime/src/rpc/server.ts
  • packages/runtime/src/rpc/socket_server.ts
  • packages/runtime/src/runtime/calls.ts
  • packages/runtime/src/runtime/export_value.ts
  • packages/runtime/src/runtime/generators.ts
  • packages/runtime/src/runtime/lifecycle.ts
  • packages/runtime/src/runtime/module_cache.ts
  • packages/runtime/test/bootstrap.socket.test.ts
  • packages/runtime/test/effect/layer.test.ts
  • packages/runtime/test/effect/opentelemetry.test.ts
  • packages/runtime/test/effect/runtime.test.ts
  • packages/runtime/test/errors/cause.test.ts
  • packages/runtime/test/fixtures/arrow-export.ts
  • packages/runtime/test/fixtures/async-payment.ts
  • packages/runtime/test/fixtures/generators.ts
  • packages/runtime/test/fixtures/payment-like.ts
  • packages/runtime/test/fixtures/re-export-barrel.ts
  • packages/runtime/test/fixtures/re-export-source.ts
  • packages/runtime/test/fixtures/sync-add.ts
  • packages/runtime/test/helpers/run-effect.ts
  • packages/runtime/test/policy/manifest.test.ts
  • packages/runtime/test/policy/methods.test.ts
  • packages/runtime/test/policy/paths.test.ts
  • packages/runtime/test/preload.ts
  • packages/runtime/test/rpc/dispatcher.test.ts
  • packages/runtime/test/rpc/frame.test.ts
  • packages/runtime/test/rpc/generators.test.ts
  • packages/runtime/test/rpc/proto_loop.test.ts
  • packages/runtime/test/rpc/server.test.ts
  • packages/runtime/test/rpc/socket_server.test.ts
  • packages/runtime/test/runtime/export_value.test.ts
  • packages/runtime/test/runtime/lifecycle.test.ts
  • packages/runtime/test/runtime/lifecycle_validation.test.ts
  • packages/runtime/test/runtime/module_cache.test.ts
  • packages/runtime/tsconfig.build.json
  • packages/runtime/tsconfig.json
  • packages/vscode-forst/CHANGELOG.md
  • scripts/assert-local-forst-packages.mjs
  • scripts/multipackage-dev-reload-e2e.sh
  • scripts/patch-remix-serve-standalone-deps.mjs
  • scripts/remix-serve-standalone-e2e.sh

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

…forst/runtime

Replace Node-branded interop vocabulary with host-neutral naming across syntax,
configuration, npm, Go packages, docs, and CI. Import opt-in is now the `js`
suffix; ftconfig uses a single `bridge` section; the script-side npm package is
`@forst/runtime` with `forst-runtime-bootstrap` and `forst-runtime-index` bins.

Rename `forst/nodert` to `forst/bridgert` and `internal/nodeinterop` to
`internal/bridgeinterop`. Rename examples to `bridge-interop`, move Forst→JS docs
under `/interop/bridge/`, and update release-please, publish workflows, and
Taskfile targets accordingly. Install esbuild in CI for compiled legacy-module
precompile tests; fix indexer interpreter selection so host-mode app binaries
(e.g. remix-serve) are not used for compile-time indexing.

BREAKING CHANGE: Migrate in one step — no compatibility shims remain.
1. Replace `import "./path" node` with `import "./path" js`.
2. Collapse `ftconfig.node` and `ftconfig.javascript` into `bridge` (use
   `bridge.legacyModules.format` instead of `node.loader`).
3. `npm install @forst/runtime` and remove `@forst/node-runtime`.
4. Rename deploy env vars `FORST_NODE_*` to `FORST_BRIDGE_*`.
5. Point bootstrap defaults to `node_modules/@forst/runtime/dist/bootstrap.js`.
6. Replace CLI flag `-require-no-node` with `-require-no-bridge`.
Compiled bridge modules now resolve from a configurable directory instead of
being tied to the Go binary path. Esbuild still writes bundles to `.forst/js`
under the project boundary at compile time. Runtime loads them from
`FORST_BRIDGE_MODULES_DIR`, `bridge.legacyModules.dir`, or the default
`{FORST_ROOT}/.forst/js`.

Manifest module IDs are relative to the compiled modules directory (for example
`legacy/payment.js`). Initialize RPC and spawn pass `modulesDir` separately
from `boundaryRoot`. The TypeScript runtime resolves `.js` modules under that
directory with the same path jail rules. Deno spawn includes the directory in
read permissions.

`forst build -o` records `compiledModulesDir` and related fields in
`manifest.json` and no longer copies `.forst/js` beside the binary. Missing
compiled module directories produce a clear error that names
`FORST_BRIDGE_MODULES_DIR`.

BREAKING CHANGE: Compiled module manifest IDs no longer use a `.forst/js/`
prefix. Deployments must ship the compiled modules tree separately and set
`FORST_BRIDGE_MODULES_DIR` or `bridge.legacyModules.dir` when it is not at the
default path under `FORST_ROOT`.
… GitHub links

Restructure the documentation navigation by splitting JavaScript interop into two clear sections: calling Forst from JavaScript under invoke docs and calling JavaScript from Forst under bridge docs. Set up redirects for legacy node interop paths.

Streamline the hand-written Go section in the Go interop guide while expanding the caveats section to cover generic APIs, interface satisfaction, unsafe usage, opaque structs, and sandbox limitations in detail.

Replace local task command references across all documentation pages with direct links to the corresponding example source files on GitHub.
Compiled legacy modules remap manifest exports to .js, but codegen still
passed .ts module IDs to bridgert and caused forbidden manifest errors at
runtime. BridgeCallTarget now carries a runtime ModuleID (.js when compiled)
and a SourceModuleID (.ts) for TypeScript index lookups and wrapper codegen.

Rename generated bridge companions and internal APIs from node to bridge
without deprecated aliases: forst_0_bridge_runtime.gen.go,
forstBridgeManifestJSON, forst_bridge_* wrappers, ForstBridgeWaitForShutdown,
CompileWithBridgeRuntime, NeedsBridgeRuntime, BridgeCallTarget, and related
compiler, typechecker, transformer, and bridgert symbols. Refresh
bridge-interop example goldens accordingly.

Harden bridgert tests by skipping Deno spawn hooks when deno is absent,
resetting supervisorCfg in test teardown, and clearing
FORST_BRIDGE_ATTACH_ONLY in the bootstrap death/respawn test.

BREAKING CHANGE: Generated bridge companion filenames and symbols use bridge
instead of node. Internal compiler and typechecker entry points and types
were renamed to Bridge* (for example CompileWithBridgeRuntime and
BridgeCallTarget); update any code or tests that referenced the old names.
… e2e

Default empty hostSocket resolution now uses .forst/bridge.sock to match
ftconfig, and the multipackage-dev reload e2e waits on bridge.sock.ready
instead of the obsolete node.sock.ready path.

Drop legacyNodeRuntimeOutputPath companion cleanup and the matching
gitattributes linguist rule; keep only the immediate prior bridge runtime
filename. Fix devserver tests after the Node→Bridge config rename by using
c.Bridge.HostMode and compiled legacy/counter.js in the reload reattach
fixture so host spawn without tsx can load modules under the default
compiled format.
@haveyaseen
haveyaseen marked this pull request as ready for review August 23, 2026 13:52
@haveyaseen
haveyaseen merged commit 608fb80 into main Aug 23, 2026
7 checks passed
@haveyaseen
haveyaseen deleted the feat/js-interop-multi-host branch August 23, 2026 16:12
@github-actions github-actions Bot mentioned this pull request Aug 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant