Wit

Install & your first document

Wit runs on Node 20+. Install the command-line tool, then build a real document from an empty file — prose first, structure added one piece at a time.

Install the CLI

npm install -g @witlang/cli

Check it landed:

wit --version

That prints 0.2.0. The wit command has no runtime dependencies, so the install is quick. Below Node 20 the tool won't run — upgrade Node, not Wit.

Write some prose

Make a file called hike.wit and type ordinary sentences. A blank line starts a new paragraph; nothing else is required.

We reached Cairn Loop just after seven, ahead of the heat.

The ridge was quiet — a single hawk, and the wind doing all
the talking.

Build it to a web page:

wit build hike.wit -o hike.html

Open hike.html. Two clean paragraphs in a finished-looking theme — you wrote no CSS, because the default HTML output is a complete, self-contained styled page.

Add a heading and emphasis

Put a title on top and mark two words. stars make bold, underscores make italic:

source
@h1 Weekend hike: Cairn Loop h1@

We reached Cairn Loop *just after seven*, ahead of the heat.
The ridge was _completely_ silent.
result

Weekend hike: Cairn Loop

We reached Cairn Loop just after seven, ahead of the heat. The ridge was completely silent.

Rebuild and refresh. The @h1 … h1@ is a real heading, the starred words are bold, the underscored words italic. Everything you didn't mark stayed exactly as typed — the marks wrap a single token, so 5*6*7 and file_name are never touched.

Add a list

source
@h2 What we packed h2@

@ul
  @li Two litres of water each li@
  @li Windshell and gloves li@
  @li Trail bars li@
ul@
result

What we packed

  • Two litres of water each
  • Windshell and gloves
  • Trail bars

That renders a <ul> of three items. The indentation is for your eyes only — a node's scope comes from its @ul … ul@ pair, not from columns. Swap @ul for @ol to number them.

Add a table

Something Markdown can't do without dropping into HTML — a captioned table, written inline:

source
@table |rows [[Segment, Distance, Time], [Trailhead to ridge, 4.2 km, 1h10], [Ridge to summit, 2.8 km, 55m]]| |caption Splits|
result
Splits
SegmentDistanceTime
Trailhead to ridge4.2 km1h10
Ridge to summit2.8 km55m

Wit builds a full <table>: a <caption>, a <thead> from the first row, and a <tbody> from the rest. The rows ride in a parameter because they're structured metadata.

Add a figure

A picture with a real caption (any .png beside the file works for src):

@figure
  @img |src ./ridge.png| |alt The ridge at dawn|
  @figcaption First light on the ridge. figcaption@
figure@

You get a semantic <figure> wrapping the <img> and its <figcaption> — the src and alt are metadata in parameters; the caption is content in the body.

The whole file

@h1 Weekend hike: Cairn Loop h1@

We reached Cairn Loop *just after seven*, ahead of the heat.
The ridge was _completely_ silent.

@h2 What we packed h2@

@ul
  @li Two litres of water each li@
  @li Windshell and gloves li@
  @li Trail bars li@
ul@

@table |rows [[Segment, Distance, Time], [Trailhead to ridge, 4.2 km, 1h10], [Ridge to summit, 2.8 km, 55m]]| |caption Splits|

@figure
  @img |src ./ridge.png| |alt The ridge at dawn|
  @figcaption First light on the ridge. figcaption@
figure@

One plain-text file — prose, a heading, emphasis, a list, a table, a figure — and it built to HTML at every step.

The edit loop

Editing Wit is three beats: edit the file, run build, refresh the output. Two commands help alongside build:

  • wit check hike.wit — report parse and reference errors without building.
  • wit fmt hike.wit — tidy indentation without changing meaning (-w writes it back).

Build to PDF, Markdown, or a fragment

The -o extension picks the format:

  • -o hike.html — a complete, styled, self-contained page.
  • -o hike.md — clean Markdown, the same source for a different pipeline.
  • -o hike.pdf — a paginated, print-ready PDF.
  • No output flag — the HTML prints to your terminal, handy for piping.

Two flags fine-tune HTML: --fragment emits just the bare <article> for pasting into an existing site, and --rawswaps the built-in theme for a minimal reset so you can bring your own CSS.

PDF is the one format with a system requirement: Wit paginates its HTML through a headless Chrome, so a system Chrome or Chromium must be installed. If none is found, the build says so and names the fix:

wit build: no headless Chrome/Chromium found for PDF output.
Install Google Chrome, or point WIT_CHROME at a browser executable.

HTML and Markdown never need a browser; only PDF does.

See also