Deploying
nola build compiles .tsi modules to JavaScript that runs directly in Node. Deploy the built files with your runtime dependencies and provider credentials.
What nola build emits
Section titled “What nola build emits”From the typescript-interop layout, npx nola-lang build --out dist writes:
dist/ nola.config.js # your config, bundled with a self-configuring wrapper src/ person.tsi.js # the lowered module person.tsi.js.map # source map back to src/person.tsi person.tsi.d.ts # types for consumers- The output mirrors the source tree:
src/person.tsibecomesdist/src/person.tsi.js. Views of cross-file types are emitted as<name>.tsi.jsand<name>.tsi.d.ts. Because a view re-exports./<name>.js, compile the underlying.tsmodule into the same output tree. - For application builds, the default
build.target: "app", each compiled module imports the bundleddist/nola.config.js. Importing a built module therefore configures the runtime. The build refuses to overwrite adist/nola.config.jsit did not generate. nola buildcompiles.tsifiles only. A plain.tsentry such assrc/main.tsneeds a separate compilation step, or you can write a JavaScript entry that imports the built module.
Running it
Section titled “Running it”For the typescript-interop template, create a JavaScript entry at the project root:
// entry.mjs — plain JavaScript, next to dist/import { extractPerson } from "./dist/src/person.tsi.js";
console.log(JSON.stringify(await extractPerson("Alice Smith, 32, is a staff engineer at Acme Corp.")));npx nola-lang build --out distnode entry.mjs # no --import, no loader: prints the extractionImporting ./dist/src/person.tsi.js also loads dist/nola.config.js. Set provider keys such as OPENAI_API_KEY in the process environment; the built application does not load .env automatically.
Relative file paths in the config, such as replay("./nola.replay.jsonl"), resolve against the working directory. Run from the project root or use absolute paths for files the application needs.
For a TypeScript entry, compile it separately with tsc and use the built .tsi.js path in the import. The neighboring .tsi.d.ts supplies its types. Make sure the import resolves from the emitted entry’s location. Direct .tsi imports need Nola’s loader or a bundler plugin; nola run handles them during development.
Libraries
Section titled “Libraries”Set build: { target: "lib" } in nola.config.ts to build a library. Its emitted modules omit the config import, leaving configuration to the consuming application through its loader, bundler plugin or built config.
Publish the .tsi.js and .tsi.d.ts files together. Declare @nola-lang/runtime and any providers the library imports as dependencies, using matching Nola package versions.
Bundlers and frameworks
Section titled “Bundlers and frameworks”For a bundled application, install the plugin for your build tool: @nola-lang/vite, @nola-lang/webpack, @nola-lang/rollup, @nola-lang/rolldown, @nola-lang/esbuild, @nola-lang/rspack or @nola-lang/next. The Next.js integration uses withNola and supports webpack and Turbopack.
The plugins compile .tsi and include the config in the server bundle. Nola inference runs server-side; client imports are rejected with NOLA4001 where the bundler can identify them, with a runtime check as a backstop. See the package READMEs for setup, including @nola-lang/vite and @nola-lang/next.
What never ships
Section titled “What never ships”For deployments using built output:
nola-langstays a devDependency. Deploy@nola-lang/runtimeand any provider packages the application imports.- The loader is unnecessary because the build has already compiled the Nola syntax. Running source through the loader requires Node; Bun and Deno are rejected with
NOLA3015. - Package versions should match across Nola dependencies. An incompatible runtime contract or duplicate runtime can prevent startup; see
NOLA3001andNOLA3002.
Next: Nola compared