Embed the Wit parser
Run the Wit pipeline inside your own program — parse a document, feed it your own data, get HTML back — with no CLI, no subprocess, and no config file. This is for developers.
Step 1 — Install
Add the three packages you need:
npm install @witlang/parser @witlang/runtime @witlang/render-html
Step 2 — Run the whole pipeline
The pipeline is parse, then loadExternalData (only if the
document loads external data), then resolve, expand, and
finally a renderer. Verified end to end:
import { parse } from '@witlang/parser';
import { loadExternalData, resolve, expand } from '@witlang/runtime';
import { renderHtml } from '@witlang/render-html';
const src = `@load meta load@
@load sales load@
@h1 Release @meta.version h1@
Cut @meta.date.
@table |rows @sales|
`;
// Feed data through the same seam the CLI uses. A plain dictionary pairs each
// alias with an already-resolved value; keys must match the @load aliases.
const doc = loadExternalData(parse(src, 'report.wit'), {
meta: { version: '0.4.0', date: '2026-07-05' },
sales: [{ site: 'Dunmore', lit: 'yes' }, { site: 'Harbour', lit: 'no' }],
});
const html = renderHtml(expand(resolve(doc)), { mode: 'document', title: 'Release' });Result. html is a full page whose body contains <h1>Release 0.4.0</h1><p>Cut 2026-07-05.</p> and a table with the
two sales rows — verified. Pass mode: 'fragment' for embedding, or
supply css to override the inlined theme.
The data seam
A data source is either a plain dictionary or a loader function. The dictionary
form is simplest; a function of the shape (req) => value — where req carries the alias, its
arguments, and a source location — fetches lazily per alias.
Multi-file documents
If the source uses reference, pass resolve options with a rootPath and a synchronous fileReader that
takes an absolute path and returns the file's text. A single-file document needs
no options.
Pitfalls
- No
loadline, no data. Without the matching@loadline the dictionary key is never consulted, and the reference stays unresolved. - References need a root. Calling
resolveon a document that usesreferencewithout arootPaththrows — the resolver refuses to silently drop references.
See also
Write a custom renderershares this front half of the pipeline; A report with live data crosses the same seam through the CLI; Architecture diagrams every stage.