Compile framework apps into a single native executable via Bun.
Supported: Next.js ยท Planned: React Router, SvelteKit, TanStack Start, Deno runtime
npm install kiln
# or
bun add kilnimport type { NextConfig } from "next";
const nextConfig: NextConfig = {
experimental: {
adapterPath: import.meta.resolve("kiln"),
},
};
export default nextConfig;next build && kiln./server # single file, no node_modules neededkiln [options] [-- bun-build-flags...]| Flag | Default | Description |
|---|---|---|
--project, -p |
. |
Project root directory |
--out, -o |
./server |
Output binary path |
--framework, -f |
(auto-detect) | Framework adapter to use |
--list-adapters |
Show registered adapters |
kiln -o ./server-linux --target bun-linux-x64
kiln -o ./server-arm --target bun-linux-arm64
kiln -o ./server-win.exe --target bun-windows-x64The Next.js adapter automatically detects packages that need to be transpiled (e.g., UI libraries in a monorepo). It looks for them in this order:
- Standard Next.js
transpilePackagesinnext.config.js(see docs) - Custom
nextConfig.nextRuntimeCompiler.transpilePackages - Environment variable
NEXT_RUNTIME_COMPILER_TRANSPILE_PACKAGES(comma-separated)
Example next.config.js:
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ['@repo/ui-components', '@repo/design-system'],
}
module.exports = nextConfigWhen assetPrefix is set, static assets (/_next/static/*) are assumed CDN-hosted and not embedded. public/* is always embedded.
Implement the FrameworkAdapter interface and register it:
import type { FrameworkAdapter } from "kiln";
import { registerAdapter } from "kiln";
const myAdapter: FrameworkAdapter = {
framework: "my-framework",
name: "My Framework",
detect: (dir) => existsSync(join(dir, "my-framework.config.ts")),
getStandaloneDir: (dir) => join(dir, "build/server"),
getDistDir: (dir) => join(dir, "build"),
getStaticAssetConfig: () => ({ dir: "client", urlPrefix: "/assets" }),
getStubs: () => [],
getBuildDefines: () => [],
generateServerEntry: (ctx) => `/* runtime entry code */`,
};
registerAdapter({ framework: "my-framework", create: () => myAdapter });import { compileApp, compileStandalone, generateEntryPoint } from "kiln";| Function | Description |
|---|---|
compileApp(opts) |
End-to-end: detect framework โ generate โ compile |
generateEntryPoint(opts) |
Generate asset map + server entry using adapter |
compileStandalone(opts) |
Run bun build --compile only |
The Next.js compilation logic in this project was heavily inspired by and derived from next-bun-compile. A huge thanks to the author for paving the way for running standalone Next.js apps natively in Bun!