Here is a claim most frameworks cannot make and Stone.js can: take one codebase, unchanged, and run it on a Node server, on AWS Lambda, and on the edge (Cloudflare, Deno, Bun, Vercel, Netlify). Not three builds of three apps. One domain, three runtimes.

The problem with "just deploy it elsewhere"

Moving a conventional app to a new runtime is rarely a deploy; it is a rework. The framework assumed a Node server, or a specific handler signature, or a bundler target, and that assumption is threaded through the code. Serverless cold starts, edge runtimes with Web APIs instead of Node APIs, a different request object, each one leaks into your logic.

The cost is lock-in: the runtime you picked on day one is the runtime you are married to, and re-platforming for cost, latency or reach means touching the domain.

Stone.js keeps the runtime out of the domain

Your domain never names a runtime. You declare the runtimes you want to support as adapters in the manifest, stacked together, and they coexist. Nothing is selected until the app runs, when Stone.js resolves exactly one, the contextual collapse.

Your domainwritten onceNodenode-http-adapterAWS Lambdaaws-lambda-adapterEdgefetch-adapterBrowserbrowser-adapter
One codebase at the centre. At run time the collapse picks the target’s adapter, so the same domain is served on Node, Lambda, the edge or the browser, unchanged.

The manifest, and only the manifest, changes

Stack the adapters. That is the whole of it: the handlers below are untouched, and there is no runtime-specific branch anywhere in your code.

app/Application.tsts
import { StoneApp } from '@stone-js/core'
import { Routing } from '@stone-js/router'
import { NodeHttp } from '@stone-js/node-http-adapter'
import { AwsLambdaHttp } from '@stone-js/aws-lambda-http-adapter'
import { Fetch } from '@stone-js/fetch-adapter'

@Routing()
@NodeHttp({ default: true })   // local dev and Node servers
@AwsLambdaHttp()               // AWS Lambda
@Fetch()                       // Cloudflare, Deno, Bun, Vercel, Netlify (Web standard)
@StoneApp({ name: 'tasks' })
export class Application {}

The same TaskController you would write for a plain Node app answers on all three. When the process starts, Stone.js picks the adapter whose platform it is running on (or the one marked default): started on Node it collapses to NodeHttp; on Lambda, to AwsLambdaHttp; on an edge runtime, the Web-standard Fetch handler serves it.

Deploy the same artifact, everywhere

You build once. The output runs as a Node server, is handed to Lambda as its handler, or is served through a Web fetch entry on the edge, the edge adapter ships the serveCloudflare, serveDeno, serveBun, serveVercel and serveNetlify helpers for exactly that. No fork, no per-target branch, no second codebase to keep in sync.

Why enterprises care

  • No lock-in. Re-platform for cost or latency without touching the domain.
  • One team, one codebase. The same app serves every environment; there is nothing to keep in sync.
  • Future runtimes are a package, not a rewrite. The next platform arrives as an adapter someone writes.

Run it

The Continuum Showcase starter is exactly this: one domain, served over HTTP, on the edge, as a CLI and as agent tools, with both paradigms side by side. Scaffold it, then read Adaptersand Superposition and collapse for the mechanics.