@thexjs/adapter-vercel
v1.0.11
Published
Vercel Build Output API (v3) adapter for the x framework -- deploy @thexjs apps to Vercel with zero vercel.json config.
Maintainers
Readme
@thexjs/adapter-vercel
Vercel Build Output API v3 adapter for @thexjs
apps. Produces a .vercel/output/ tree directly -- no vercel.json required.
bun add -d @thexjs/adapter-vercel
x build --adapter vercel
vercel deploy --prebuiltWhat it produces
.vercel/output/
config.json routes: filesystem first, then fallback -> render
static/ HTML, CSS, island JS chunks (served via Vercel's CDN)
functions/render.func/
.vc-config.json runtime: nodejs20.x, handler: index.mjs
index.mjs standalone SSR + API bundleIf your app is 100% static (every page is mode = "static", no API routes, no server
actions), no function is emitted at all -- config.json only does filesystem routing.
How it works
- Runs
@thexjs/core's normalbuild()to prerender every static-mode page/content entry and compile island bundles -- this becomesstatic/. - Separately resolves every server-mode page, API route, layout, middleware file,
and server-action file at build time (reusing
@thexjs/core's own scanners), so nothing at request time depends on walking the filesystem or on a dynamicimport(path)of a.tsxfile -- both of those only work under Bun. - Transpiles each of those files from Bun-flavored TSX/TS into plain Node ESM, then
bundles them together with
@thexjs/coreand React into one standaloneindex.mjs. - Bridges Vercel's Node-style
(req, res)function invocation to@thexjs's Web-standardRequest/Responsehandler, streaming the response body through (sorenderToReadableStream-based SSR streams end-to-end, not just non-streaming pages).
Options
import { buildVercelOutput } from "@thexjs/adapter-vercel";
await buildVercelOutput({
projectRoot: process.cwd(),
pagesDir: "src/pages",
apiDir: "src/api",
layoutsDir: "src/layouts",
actionsDir: "src/actions",
contentDir: "content",
outputDir: ".vercel/output", // default
runtime: "nodejs20.x", // "nodejs18.x" | "nodejs20.x" | "nodejs22.x"
});Known limitations (follow-up work)
- ISR-style
revalidatecaching (in-memory in the long-running Bun dev/prod server) doesn't carry over to stateless serverless invocations -- use Vercel's ownCache-Control/CDN caching on the response instead. - Markdown
contentDirentries are always statically prerendered (matches@thexjs/core'sbuild()behavior today) -- there's no server-mode content route yet.
