Install the packages
Wit ships as five small ESM packages with a strict dependency direction.
Installing the wrong subset — or reaching for CommonJS require — is
the first thing that goes wrong. This page gets the packages into a project and
confirms they import.
Prerequisites
- Node ≥ 20. Verified on v22.
- ESM only. Every package is
"type": "module". There is no CommonJS build; arequire('@witlang/parser')throws. Useimport, or dynamicimport()from a CommonJS file.
The package map
Renderers and the CLI depend on the runtime; the runtime depends on the parser. The arrows point from dependent to dependency:
@witlang/render-html ─┐ @witlang/render-markdown ┼─▶ @witlang/runtime ─▶ @witlang/parser @witlang/cli ─┘
Import only from each package's entry point. Everything under dist/ beyond the package root is package-private and may move
between releases.
Minimal install
The common case is the parser, the runtime, and one renderer:
npm i @witlang/parser @witlang/runtime @witlang/render-html
Add @witlang/render-markdown if you also want Markdown output.
You rarely install the parser or runtime alone — a renderer pulls the runtime,
which pulls the parser.
The CLI
Install @witlang/cli for the wit binary. It is the
only package with a bin, and it bundles its own copies of the
pipeline, so it works standalone — you do not need the library packages
installed to run wit.
npm i -g @witlang/cli # global `wit` on your PATH npm i -D @witlang/cli # or per-project, run via npx wit
Smoke test
Four lines that parse and render prose confirm the whole chain imports:
import { parse } from '@witlang/parser';
import { resolve, expand } from '@witlang/runtime';
import { renderHtml } from '@witlang/render-html';
console.log(renderHtml(expand(resolve(parse('Hello *there*.')))));
// → <article class="wit-doc"><p>Hello <strong>there</strong>.</p></article>From the CLI, the equivalent is a one-liner against a file:
wit build hello.wit # styled HTML document on stdoutTypeScript
Types ship with every package; there is nothing to install separately. Import type-only symbols from the entry point, never from an internal path:
import type { Document, NodeUse } from '@witlang/parser';
import type { ExpandedDocument, ResolveOptions } from '@witlang/runtime';
import type { RenderHtmlOptions } from '@witlang/render-html';Common mistakes
- Deep-importing a private module such as
@witlang/runtime/dist/expander.js. It is package-private and may move — importresolve,expandfrom the package root instead. - Expecting CommonJS. Mixing a CommonJS build tool without ESM interop breaks the import; the packages are ESM-only.
- Installing
@witlang/render-htmlbut callingresolvewithout having@witlang/runtimeresolvable — the renderer depends on it, so npm will pull it, but a hand-managednode_modulescan miss it.