Skip to content

Examples

The repository includes the example projects below. Most pair a .tsi module with a plain TypeScript entry point in src/main.ts and use a mock provider, so you can run them without an API key.

Four examples are a single .tsi file with src/main.tsi as the entry point: feature-extraction and function-calling, which replay recorded answers from a committed ledger, agent-loop, which runs on the mock provider, and triage-ticket, whose default config calls typesafe.ai (the example explains how to switch to a mock provider).

The scaffolder’s templates are these examples. Every template except empty is copied from the repository at the release tag that matches the CLI’s version, so npm create nola needs network access for them; the first menu lists feature-extraction, function-calling, agent-loop, typescript-interop and triage-ticket, and More examples… the rest of the ones with a scaffold command below.

Every example types its asks with the colon spelling, ask `…`: T; <T> means the same thing. See Extractors.

Example Demonstrates Scaffold
feature-extraction Typed extraction as one top-level .tsi script: a context statement, const .message and const .role bindings, and two asks, the second reading the first’s answer npm create nola my-app (the default template; replays a recorded ledger offline)
function-calling A call intent as one top-level .tsi script: the model fills the arguments of an async function in a neighboring .ts file, and the call runs with them npm create nola my-app -- --template function-calling (replays a recorded ledger offline)
typescript-interop An infer function in person.tsi, imported and awaited from plain TypeScript npm create nola my-app -- --template typescript-interop (replays a recorded ledger offline)
extract-person Extract an object and call a TypeScript helper — (typescript-interop is this program without the helper, on a replay ledger)
extract-resume Nested arrays of objects, JSDoc schema descriptions npm create nola my-app -- --template extract-resume
extract-invoice Same-file type references, optional fields npm create nola my-app -- --template extract-invoice
classify-message Closed label sets: union alias, string enum, inline union npm create nola my-app -- --template classify-message
chain-of-thought Two-step reasoning: a free-text ask carried into a typed ask by a context statement with a value npm create nola my-app -- --template chain-of-thought
research-notes TypeScript control flow around Nola functions npm create nola my-app -- --template research-notes
contextual-args .param contextual parameters and the system.message config key —
cross-file-types A type imported from another file (a view of plain TypeScript), self-recursive; schema.ts prints its JSON Schema —
recursive-tree Self-recursive types: JSON Schema $defs/$ref, validated recursively —
file-ticket Call intents: the model fills a function’s arguments, sigil-less and hint forms npm create nola my-app -- --template file-ticket (the function-calling example is this feature as one top-level .tsi script)
agent-loop An agent loop as one top-level .tsi script: a while loop whose ask is typed as a Problem or null, and a context statement before the loop that is read again on every pass npm create nola my-app -- --template agent-loop (on the first template menu)
triage-ticket Ticket triage on typesafe.ai’s Jev as one top-level .tsi script: literal unions and booleans as typed questions npm create nola my-app -- --template triage-ticket (on the first template menu; skips the provider question; needs TYPESAFE_API_KEY)

Use a scaffold command from the table, or run an example from a repository checkout. The examples are npm workspaces, so install and build at the root first:

Terminal window
git clone https://github.com/nola-lang/nola
cd nola && npm install && npm run build
cd examples/extract-person
npx nola-lang run src/main.ts # mock provider, deterministic

To use a real model, open the example’s nola.config.ts. Most include a commented config for openai({ model: "gpt-5-mini" }), which reads OPENAI_API_KEY. For the others, replace mockProvider(...) with your chosen provider. See Providers.

Next: extract-person