Introduction
Nola adds syntax to TypeScript for asking a language model for a typed value. You write .tsi files using TypeScript types, functions and control flow, with infer function and ask for inference. Nola compiles these files to plain TypeScript so they can work with the rest of your application.
export infer function analyzeUserRequest(userId: string, .message: string) { const ticketId = ask `ticket id mentioned in the message`: string; const isFraud = ask `does the message look fraudulent`: boolean; return { userId, ticketId, isFraud };}Plain TypeScript imports the .tsi file directly and awaits the result:
import { analyzeUserRequest } from "./analyze.tsi";
const result = await analyzeUserRequest("user-1", "Ticket TCK-4711: customer reports suspicious activity.");// → { userId: "user-1", ticketId: "TCK-4711", isFraud: true }.message is a contextual parameter: its value is available to every ask in this invocation. userId is a plain argument. Its name appears in the function signature shown to the model, but its value is not included automatically.
The two constructs
Section titled “The two constructs”infer functiondeclares a function that can use inference. Calling it returns a lazy, thenableIntent<T>; awaiting the intent runs the function. Parameters that start with a dot, such as.message, supply context to its asks.askresolves an intent the wayawaitresolves a promise. An extractor,ask `instruction`: T, asks the model for aT. A call intent, such asask fn`hint`(...), lets the model fill extractor arguments before running the function.ask with <name> …selects a named model fromnola.config.ts.
Why a language, not a library
Section titled “Why a language, not a library”Nola keeps the result type, request and context in your source code. It derives the response schema from the TypeScript type, validates the model’s reply at runtime and shares contextual parameters across asks in a function. You can use try/catch, loops and helper functions around an ask as you would around other asynchronous work.
This requires Nola’s compiler, loader or bundler plugin, and editor support for .tsi. Why Nola explains that tradeoff; the comparison pages show the same tasks in Nola, BAML, the Vercel AI SDK and LangGraph.
What ships
Section titled “What ships”| Piece | Package |
|---|---|
CLI — nola init / build / run / check / declarations / skill and the Node loader (node --import nola-lang/register) |
nola-lang |
Runtime — Intent<T>, defineConfig, telemetry and receipts |
@nola-lang/runtime |
Providers — openai, anthropic, google, mockProvider, withRetry, fallback, roundRobin, record/replay |
@nola-lang/providers |
| Scaffolder | create-nola-lang (alias create-nola) |
| Bundler plugins — Vite, webpack, Rollup, Rolldown, esbuild, Rspack, Next.js | @nola-lang/vite, @nola-lang/webpack, … |
| Editor — tsserver plugin, language server, VS Code extension | nola.nola-vscode |
Diagnostics are numbered NOLA1xxx (parse), NOLA2xxx (compile), NOLA3xxx (runtime) and NOLA4xxx (bundler).
Next: Quick start — scaffold a project and run your first .tsi file offline.