Bun fullstack dev server

Learn how to use ArkEnv in a Bun fullstack application.

Edit on GitHub

ArkEnv supports most Bun apps out of the box, no further configuration required.

However, some Bun apps use Bun's fullstack dev server (Bun.serve()) or Bun's bundler (Bun.build()). The Bun integration was built to support these use cases.

Continue reading if you're using Bun.serve() or Bun.build(). Otherwise, the Getting started guide is a good place to start.

Quickstart

Scaffold Bun integration in an existing project using the interactive CLI:

npx arkenv init
pnpm dlx arkenv init
yarn dlx arkenv init
bunx arkenv init

The CLI installs @arkenv/bun-plugin and creates your initial env.ts schema file.

Manual installation

If you prefer manual setup, install @arkenv/bun-plugin alongside your chosen validation engine.

ArkType engine

Install @arkenv/core, arktype, and the Bun plugin:

npm install @arkenv/core arktype
npm install -D @arkenv/bun-plugin
pnpm add @arkenv/core arktype
pnpm add -D @arkenv/bun-plugin
yarn add @arkenv/core arktype
yarn add --dev @arkenv/bun-plugin
bun install @arkenv/core arktype
bun install --dev @arkenv/bun-plugin

Standard Schema engine

If you aren't using ArkType, install @arkenv/standard:

npm install @arkenv/standard
npm install -D @arkenv/bun-plugin
pnpm add @arkenv/standard
pnpm add -D @arkenv/bun-plugin
yarn add @arkenv/standard
yarn add --dev @arkenv/bun-plugin
bun install @arkenv/standard
bun install --dev @arkenv/bun-plugin

Then, import the plugin from @arkenv/bun-plugin/standard.

Full-stack setup

When building a full-stack Bun application with client bundling, configure the plugin across your schema, dev server, and build script.

Define your schema

Create your schema in src/env.ts:

./src/env.ts
import  from "@arkenv/core";

export const  = ({
  : "string",
  : "string",
  : "boolean = false",
});

Configure dev server

Enable the plugin for development in bunfig.toml:

./bunfig.toml
[serve.static]
plugins = ["@arkenv/bun-plugin"]

Configure production build

Pass the plugin to Bun.build in your build script:

./build.ts
import  from "@arkenv/bun-plugin";

await .({
  : ["./src/index.tsx"],
  : "./dist",
  : [()],
});

Import { env } from "./env" in application code. Transform mode inlines public BUN_PUBLIC_ keys into the client bundle and protects server secrets.

Backend-only Bun

If your project runs exclusively on the server with no client bundling, skip the plugin and call @arkenv/core directly:

./src/env.ts
import  from "@arkenv/core";

export const  = ({
  : "string",
  : "number.port = 3000",
});

Client access

Import the validated env object from your schema module.

Do not read process.env directly

Reading process.env skips ArkEnv. Import { env } so public keys stay typed and coerced and server secrets stay out of the client bundle.

Types and options: @arkenv/bun-plugin.

SSR and bundling execution

Full-stack Bun applications separate server runtime execution from client bundle generation:

  • Server execution: Server entrypoints and backend APIs execute real @arkenv/core validation at startup, validating database URLs and backend secrets before serving traffic.
  • Client bundling: During Bun.build runs or [serve.static] requests, @arkenv/bun-plugin transforms env.ts imports in client code. It inlines BUN_PUBLIC_* values as static literals and replaces server keys with throwing runtime stubs. Browser bundles omit the validator engine.

Next steps