Wit

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; a require('@witlang/parser') throws. Use import, or dynamic import() 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 stdout

TypeScript

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 &#39;@witlang/parser&#39;;
import type { ExpandedDocument, ResolveOptions } from &#39;@witlang/runtime&#39;;
import type { RenderHtmlOptions } from &#39;@witlang/render-html&#39;;

Common mistakes

  • Deep-importing a private module such as @witlang/runtime/dist/expander.js. It is package-private and may move — import resolve, expand from 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-html but calling resolvewithout having @witlang/runtime resolvable — the renderer depends on it, so npm will pull it, but a hand-managed node_modulescan miss it.

See also

Architecture

· Embed Wit in an app · CLI reference.