Deployment
Build for production
bun run build
bun run preview
bun run build compiles all .aihu SFCs through the Rust compiler, bundles with Vite/Rolldown, and validates against the per-package size budgets in .size-limit.json. bun run preview serves the production build locally to verify output before deploying.
`defineAihuConfig`
The app configuration lives in aihu.config.ts:
import { defineAihuConfig } from '@aihu/server'
export default defineAihuConfig({
build: {
target: 'universal',
outDir: 'dist',
sourcemap: false,
},
plugins: [],
})
Build target options: 'client' (browser bundle only), 'server' (server bundle only), 'universal' (both, default).
Cloudflare Workers
Use @aihu/adapter-cloudflare to deploy to Cloudflare Workers or Pages:
// aihu.config.ts
import { defineConfig } from '@aihu/app'
import { cloudflare } from '@aihu/adapter-cloudflare'
export default defineConfig({
adapter: cloudflare({ name: 'my-worker' }),
})
The adapter:
- Writes
_worker.jsto the Vite output directory (SPA mode — all page requests served from Cloudflare CDN via theASSETSbinding). - Optionally creates
wrangler.tomlin the project root if absent (never overwrites an existing one).
Adapter options:
| Option | Type | Default | Description |
|---|---|---|---|
name |
string |
from package.json |
Cloudflare Worker name in wrangler.toml |
mode |
'workers' | 'pages' |
'workers' |
Deployment target |
generateWrangler |
boolean |
true |
Write wrangler.toml if absent |
Deploy after build:
wrangler deploy --config wrangler.toml
For a manual Worker without the adapter, use @aihu/server's request router directly:
import { createRequestRouter, defineRoute, json } from '@aihu/server'
const router = createRequestRouter({
routes: [
defineRoute('/api/hello', () => json({ hello: 'world' })),
],
})
// Cloudflare Worker
export default { fetch: router }
Vercel
Use @aihu/adapter-vercel to deploy using the Vercel Build Output API v3:
// aihu.config.ts
import { defineConfig } from '@aihu/app'
import { vercel } from '@aihu/adapter-vercel'
export default defineConfig({
adapter: vercel(),
})
The adapter:
- Copies static assets to
.vercel/output/static/. - Writes an Edge Function entry (default) or Serverless Function entry.
- Emits
config.jsonwith the Build Output API v3 routes manifest.
Adapter options:
| Option | Type | Default | Description |
|---|---|---|---|
runtime |
'edge' | 'serverless' |
'edge' |
Vercel function runtime |
outputDir |
string |
'.vercel/output' |
Build Output API output directory |
nodeVersion |
string |
'nodejs18.x' |
Node.js version for serverless runtime |
Deploy after build:
vercel deploy --prebuilt
Bun server
Run aihu server-side on Bun using @aihu/server's fetch-API router:
import { createRequestRouter, defineRoute, json } from '@aihu/server'
import { createAgentReadinessRoutes } from '@aihu-plugin/agent-readiness'
const ar = createAgentReadinessRoutes({
name: 'My App',
endpoint: 'https://myapp.example.com/mcp',
summary: 'An aihu-powered app.',
})
const router = createRequestRouter({
routes: [
defineRoute('/llms.txt', ar.llmsTxt),
defineRoute('/.well-known/mcp/server-card.json', ar.mcpServerCard),
defineRoute('/robots.txt', ar.robotsTxt),
defineRoute('/api/hello', () => json({ hello: 'world' })),
],
})
Bun.serve({ fetch: router })
Deno
The same router works on Deno Deploy — aihu uses only Web Standard APIs (Fetch, ReadableStream, URL):
import { createRequestRouter, defineRoute, json } from '@aihu/server'
const router = createRequestRouter({
routes: [
defineRoute('/api/hello', () => json({ hello: 'world' })),
],
})
Deno.serve(router)
Node.js
aihu output is standard ESM. Any Node.js ≥20.18.0 runtime can serve an aihu application:
npm run build
node dist/server/entry.js
The server entry is generated by the universal build and uses @aihu/server's request router.
On supported Node platforms @aihu/server lazily loads a native Rust addon to render SSR. Edge runtimes (Cloudflare, Vercel Edge, Deno) automatically skip it and use the TypeScript fallback. To force the fallback on Node — e.g. on an unsupported platform or to debug a parity issue — set AIHU_NATIVE_SKIP=1 in the server environment.
`viteRouterIntegration()` at build time
The Vite plugin performs these steps at build time:
scanPages(dir)— discovers all.aihufiles undersrc/pages/.- For each page, reads the
.route.jsonsidecar emitted by the Rust compiler. - Assembles the route manifest into the
virtual:aihu-routesmodule. - Emits
dist/routes.jsonfor runtime consumption.
Route manifests are fully static after build — no filesystem scanning at runtime.