Deploy BAML with a Nuxt 4 (Nitro) server BAML on Vercel Functions
December 28, 2025
In this guide, you will learn how deploy a Nuxt 4 (Nitro) server that uses @boundaryml/baml on Vercel Functions.
Because BAML uses native Node bindings (via napi-rs), it can be cumbersome to configure Nitro properly to avoid bundling errors or ERR_MODULE_NOT_FOUND at runtime.
Why builds/runtime fail
@boundaryml/bamluses napi-rs and loads platform-specific.nodeat runtime via dynamicrequire()innative.js.- If bundled, Rollup/Vite tries to parse
.nodefiles (fails) or bakes absolute paths like/vercel/path0/...that don’t exist at runtime (/var/task), causingERR_MODULE_NOT_FOUND.
Solution
To avoid these issues, we want our bundler (Rollup) to treat BAML as external dependency. Then, we need to ensure Nitro includes the native binaries in the output so they can be resolved at runtime.
We want to configure Nitro as follows:
- Do NOT bundle BAML. Mark it external at the Rollup level.
- Rewrite any resolved paths back to a bare specifier so Node resolves them at runtime.
- Force Nitro’s file tracer to include BAML’s native packages in the serverless output.
Use this minimal config:
// nuxt.config.ts
export default defineNuxtConfig({
// your config
nitro: {
// Ensure BAML native binaries are traced into the server bundle
externals: {
traceInclude: [
'node_modules/@boundaryml/baml',
'node_modules/@boundaryml/baml-linux-x64-musl',
'node_modules/@boundaryml/baml-linux-x64-gnu',
// add arm if your Vercel project uses arm64 runtime:
// 'node_modules/@boundaryml/baml-linux-arm64-musl',
// 'node_modules/@boundaryml/baml-linux-arm64-gnu',
],
},
rollupConfig: {
// Keep BAML external (don’t bundle native bindings)
external: [/^@boundaryml\/baml/],
output: {
// Prevent absolute paths like /vercel/path0/... from being baked into the bundle
paths: (id: string) => {
if (id.includes('@boundaryml/baml')) {
const match = id.match(/@boundaryml\/baml(\/[^/]+)?$/)
if (match) return `@boundaryml/baml${match[1] || ''}`
}
return id
},
},
},
},
})
I haven't tested it, but it should work similar for other Nitro-based projects.
Key insights
Our implementation ensures:
- build: BAML stays external (not bundled)
- output: references are rewritten to bare specifiers (
@boundaryml/baml/native) - runtime: Node resolves module from
node_modules, and Nitro’s trace includes the correct.nodefiles
Additionally, you can:
- Avoid
nitro.externals.inlinefor BAML (bundling.nodecan result in ‘out of memory’ errors). - Avoid
vercel.jsonfunctions.includeFilesfor Nitro output; rely onexternals.traceIncludeinstead.
Troubleshooting
- Still seeing
ERR_MODULE_NOT_FOUND? Check which platform Vercel runs (x64 vs arm64, gnu vs musl) and add the matchingtraceIncludepaths. - Don’t use
externals.inlinefor BAML. - Ensure your build runs on Linux (Vercel does) so the correct platform binary is installed by pnpm during build.
This guide was partly generated with the help of an LLM.