Build & Deploy

Build & deploy

x produces optimized production builds with static HTML export, a server entry point, and content collection rendering — all in a single command.

Build command

Run x build to produce a production build. The build output goes to a .x/ directory.

terminal
x build
[x] resolving routes...
[x] found 12 routes
[x] building static pages...
[x] building server bundle...
[x] rendering content collections...
[x] build complete in 1.2s

Output structure

The .x/ directory contains everything needed to deploy — static files, server bundle, and assets.

output tree
.x/
client/ // Client-side assets
assets/
*.js // Bundled JS
*.css // Extracted CSS
server/ // Server entry point
index.js // Bun server bundle
static/ // Prerendered HTML pages
index.html
about/index.html
blog/
hello-world/index.html
x.json // Build manifest

Static page export

Pages with mode = "static" are exported as HTML files in .x/static/. Each page is fully rendered at build time, including its loader output. For dynamic-static pages (static pages with dynamic params), x generates one HTML file per unique path.

Server entry

Server-rendered pages are bundled into .x/server/index.js. This file contains all server routes, API handlers, server functions, and middleware — everything needed to run the dynamic parts of your app.

Production server

Use x start to run the production server. It serves static files from .x/static/ and handles dynamic routes via the server bundle.

terminal
x start
[x] production server running at http://localhost:3000

Docker deployment

Deploy with a minimal Docker image using the official Bun runtime. The build output is self-contained.

Dockerfile
FROM oven/bun:1 AS buildWORKDIR /appCOPY package.json bun.lock .RUN bun installCOPY . .RUN x buildFROM oven/bun:1-slimWORKDIR /appCOPY --from=build /app/.x .xEXPOSE 3000CMD ["x", "start"]

Content collections in builds

During x build, content collections are scanned and rendered. Each markdown file becomes a static HTML page if its route uses static mode, or is available for server-rendered routes to consume.

Deploy to Vercel

Vercel doesn't run a long-lived Bun process, so it uses a different adapter: @thexjs/adapter-vercel builds a .vercel/output/ tree (Build Output API v3) directly — no vercel.json required.

terminal
bun add -d @thexjs/adapter-vercel
x build --adapter vercel
vercel deploy --prebuilt

If every page in your app uses mode = "static" (no API routes, no server actions), no function is emitted at all — just static files and filesystem routing. Server-mode pages, API routes, and server actions run inside a single bundled nodejs20.x function.