The document language for people who love LaTeX's output

Write the paper. Not the preamble .

Wit gives you typeset-quality documents without the LaTeX tax — plain, readable source with real components, data, and cross-references. One file renders to HTML, Markdown, and print-ready PDF.

@div(class hero)
  @h1 Hello, @span(class grad) world span@ h1@
  A paragraph that simply reads like a paragraph.
div@

Made for manuscripts

What Markdown and raw HTML make painful, Wit makes native. Click a card for the source, the result, and the thing you no longer do by hand.

📚

Citations that resolve themselves

Name a source once and cite it by idea. The reference — and the bibliography — stay in sync.

Show example ↓

🧩

Write a component once

Define a callout, a figure, a pull quote — then reuse it. Change the design in one place.

Show example ↓

📊

Tables from data, not by hand

Keep the data as data; the table renders from it. Edit a value, not a wall of pipes.

Show example ↓

🔀

Draft and final, one source

Gate content on data. The same file renders a working draft and a clean final.

Show example ↓

🗂

Assemble across files

A thesis is chapters. Reference them and emit them in order — one document, many files.

Show example ↓

📄

One source, every format

The same manuscript becomes semantic HTML, Markdown, or a paginated, print-ready PDF.

Show example ↓

📚 Citations that resolve themselves

Close ✕

Wit source

#weil: Simone Weil, Gravity & Grace (1952) !!

Attention, as @weil argued, is the
rarest form of generosity.

Renders to

Attention, as Simone Weil, Gravity & Grace (1952) argued, is the rarest form of generosity.

Markdown: retype the full citation everywhere, and keep the reference list in sync by hand.

🧩 Write a component once

Close ✕

Wit source

#tip @aside(class note) 💡 ... aside@ tip#

@tip Save early. Save often. tip@

Renders to

Markdown: no components — paste the same block of HTML every single time.

📊 Tables from data, not by hand

Close ✕

Wit source

#sites: [
  { name - Dunmore, lit - yes }
  { name - Carrick, lit - no }
] !!

@table |schema [name, lit]| |rows @sites|

Renders to

NameLit
Dunmoreyes
Carrickno

Markdown: hand-align pipes; change one value and re-type the row.

🔀 Draft and final, one source

Close ✕

Wit source

(if @doc.status is draft)
@aside Draft — do not circulate. aside@
(end)

Renders to (draft build)

Markdown: keep a second copy and remember to strip the notes.

🗂 Assemble across files

Close ✕

Wit source

reference ./intro.wit
reference ./methods.wit
reference ./results.wit

@intro intro@  @methods methods@  @results results@

Compiles to

intro.wit + methods.wit + results.wit → one thesis.pdf.

Markdown: no includes — you bolt on a separate build tool to stitch files.

📄 One source, every format

Close ✕

Wit source

wit build thesis.wit -o thesis.html
wit build thesis.wit -o thesis.pdf
wit build thesis.wit -o thesis.md

Produces

HTML PDF Markdown

Markdown: it is the source, and HTML is the ceiling — no route to a print-ready PDF.

Three documents, one language

A journal-style thesis, a novel that never indents, and a branching game script — same tool, same source rules. Click a panel to open it.

🎓 A thesis chapter

Academic

Collapse ↑

Wit source

reference ./sources.wit        ~ the bibliography, written once

@h2 3 · Method 3.method@

We pre-train on a masked-language objective, following
@cite bert bert@, then fine-tune each task in turn.

@figure
  @img |src corpus.png| |alt Corpus by domain|
  @figcaption Figure 3.1 — Corpus composition. figcaption@
figure@

@table
  |schema [split, docs, tokens]|
  |rows @corpus|
table@

As @xref 3.method xref@ shows, scale beats architecture —
a point @cite sutton sutton@ makes forcefully.

Renders to

3 · Method

We pre-train on a masked-language objective, following Devlin et al. (2019), then fine-tune each task in turn.

SplitDocumentsTokens
Train40k12.4M
Dev5k1.5M
Test5k1.5M

As §3 shows, scale beats architecture — a point Sutton (2019) makes forcefully.

References

  • Devlin, J. et al. (2019). BERT. NAACL.
  • Sutton, R. (2019). The Bitter Lesson.

Why not LaTeX? the citation, the table, and the cross-reference all resolve from one source — no preamble, no package hunt, no re-compile roulette.

✍ A novel that never indents

Prose

Expand ↓

Wit source — flat, no indentation

@h2 One · The Harbour h2@

The rain had not stopped for three days.

Mara pressed her palm to the cold glass and counted
the boats that were no longer there. @em One. Two. em@
The third had been her father's.

@break ✦ ✦ ✦ break@

"You can't stay," the harbourmaster said.

She said nothing. There was nothing, she had learned,
that saying could fix.

Renders to

One · The Harbour

The rain had not stopped for three days.

Mara pressed her palm to the cold glass and counted the boats that were no longer there. One. Two. The third had been her father's.

✦ ✦ ✦

"You can't stay," the harbourmaster said.

She said nothing. There was nothing, she had learned, that saying could fix.

Why not Markdown? for pure prose Wit gets out of the way entirely — but a scene break, an epigraph, or a chapter component is one node away, not a drop into raw HTML.

🎲 A branching game script

Interactive

Expand ↓

Wit source — data, conditions, iteration

#hero: { name - Vera, hp - 8, gold - 12 } !!

@scene The Crossroads scene@

::hero.name::, the road forks beneath a broken
signpost. You are carrying ::hero.gold:: gold.

(if @hero.hp is low)
@warn You are wounded — the dark path may kill you. warn@
(end)

@choices
  @choice |goto village| Take the lit path choice@
  @choice |goto tower|   Take the dark path choice@
choices@

Pack: (each @hero.pack) ::this::  (end)

Renders to (one playthrough)

The Crossroads

Vera

, the road forks beneath a broken signpost. You are carrying 12 gold.

Choose:
  • → Take the lit path toward the village
  • → Take the dark path toward the tower
Pack:

torch · rope · a letter you should have burned.

Why not HTML? the stats, the wounded-check, and the inventory are data and logic in the document — not a wall of tags you hand-edit for every state.

It's just a parser and an AST

Wit parses your document into a small, typed AST. HTML, Markdown, and PDF are renderers over that tree — so when you need a different target, you write a function, not a fork.

FormatRendererOutput
HTMLbuilt inclean semantic markup
Markdownbuilt inportable plain text
PDFheadless Chromepaginated pages
Anythinga function you writewhatever you need

import { parse } from "@witlang/parser";

const ast  = parse(source);      // the whole document, typed
const html = renderHtml(ast);    // a renderer is just: AST in, string out
const mine = myRenderer(ast);    // so bring your own target

Every built-in renderer is written exactly this way.