AvelonDocs

Guide 11

Runtime

11. Runtime

Bun by default for everything that runs on your machine or in CI. Node for the deployed function runtime (D27). Node stays supported everywhere because the default must not become a requirement.

M0 verified Bun locally end to end: bun run --bun next build, production serving, routing middleware, and ISR revalidation all passed under Bun 1.3.14 with Next 16.2.12. Bun as the Vercel function runtime could not be verified against a live deployment, so it is an opt-in rather than the default until it is.


The matrix

StageRuntimeHow
installBunzero-config on Vercel
devBunbun run --bun next dev
buildBunbun run --bun next build
function runtimeNodeVercel default, no config
function runtime, opt-inBun{"bunVersion": "1.x"} in vercel.json, verify on a preview first
middlewareNodeNext 16 Proxy defaults to the Node runtime
testsBunbun test
CLIBunnative TypeScript, no transpile step, compiles to a single binary
// vercel.json — shipped default. Add "bunVersion": "1.x" to opt in to the Bun function runtime.
{
  "$schema": "https://openapi.vercel.sh/vercel.json"
}
// package.json
{
  "scripts": {
    "dev": "reeve route:sync && bun run --bun next dev",
    "build": "reeve route:sync && bun run --bun next build",
    "test": "bun test",
    "check": "reeve doctor"
  }
}

Known gaps on the Bun runtime

  • No automatic source maps.
  • No bytecode caching.
  • No request metrics on node:http and node:https. Metrics via fetch work on both runtimes.

None of these block v1. All three are worth stating in the docs, because "my stack traces got worse" is a support ticket you can prevent with one sentence.


Why Bun

  • Native TypeScript execution, so the CLI and generators have no transpile step and no tsx

dependency.

  • bun build --compile produces a single-binary CLI, which makes reeve installable without a

Node toolchain.

  • bun test is fast enough to run on save, which is the only property that decides whether tests

actually get written.

  • Install speed matters more than it should when a fleet of agents is running CI on every package.

The constraint

**@avelon/core and @avelon/orm may never import bun:*.** Enforced by the Bailiff rule no-bun-in-core.

Three reasons:

1. A self-hoster running Node must be able to use this. 2. Adapters other than Next may target runtimes where Bun is not available. 3. The day Bun and a deployment platform disagree about something you need, you want an exit that is a configuration change rather than a rewrite.

Bun-specific code is allowed in @avelon/cli (which is always run locally or in CI) and in driver packages that explicitly declare a Bun requirement in their capabilities.


Node fallback

Everything runs on Node 22 or later with tsx for the CLI. It is slower and it is supported. CI runs the full suite on both runtimes, because a Node incompatibility introduced quietly is far more expensive to find later than to prevent now.