jaunt, don't code.
Spec-driven code generation for Python and TypeScript: write a typed contract, and Jaunt writes the implementation.
Tyger Tyger, burning bright, / In the forests of the night -- William Blake, via Alfred Bester's The Stars My Destination
Jaunt is a CLI for spec-driven code generation in Python and TypeScript. Python is stable; the TypeScript target is an alpha in Jaunt 1.7. In either language, you write a typed contract and Jaunt generates a validated implementation beside it.
In Python, call jaunt.magic_module(__name__) once and every typed stub below it is a
spec; reach for @jaunt.magic when you need per-symbol options. In TypeScript, private
*.jaunt.ts and *.jaunt.tsx files are parsed without execution by the project-local
@usejaunt/ts worker. Production code imports a normal committed facade, and emitted
JavaScript has no Jaunt runtime dependency.
The spec is the contract. Jaunt reads your signature and docstring, drives the OpenAI Codex CLI to write the code, checks the result against the signature you declared, and stamps each file with a provenance header. Edit a docstring and rebuild: only the specs whose contract actually changed regenerate, because jaunt hashes each spec with its dependencies.
There is a second mode for code you already trust. Python's
@jaunt.contract derives a pytest battery from the
committed implementation and its docstring. TypeScript contract mode adopts an
exported function or concrete class and derives a committed Vitest battery from its
declaration and TSDoc. The name comes from Bester's 1956 novel, where to jaunt is to
teleport by thinking about where you want to be.
Python in one file
You write the stubs. Jaunt writes the rest. One magic_module call governs the whole file: the docstring-only class, the function stub, and nothing else. The handwritten constant and helper stay yours.
import re
import jaunt
jaunt.magic_module(__name__, prompt="All parsers are RFC 5322 strict.")
ADDR_RE = re.compile(r"[^@\s]+@[^@\s]+") # handwritten constant
class Email:
"""An email message with from_, to, subject, and body string fields.
Validate on construction: from_ and to must each look like an address.
"""
def parse_email(raw: str) -> Email:
"""Parse a raw RFC 5322 payload into an Email. Read the From, To, and
Subject headers and the body after the first blank line. Raise ValueError
on malformed input."""
...
def _render_debug(email: Email) -> str: # real body → handwritten helper
return f"<{email.from_} -> {email.to}>"The Python quickstart runs a full module end to end. The TypeScript quickstart starts from an empty directory, synchronizes the typed facade, builds the implementation, and runs the generated Vitest battery.
And since 1.5.2, jaunt builds jaunt: parts of the framework you install are generated from their own docstring specs, and jaunt check gates the framework's own drift in CI.
Find your way around
Python quickstart
An empty directory to a generated, tested Python module.
TypeScript quickstart
Install @usejaunt/ts, sync the typed boundary, then build and test ordinary TypeScript.
Jaunt builds Jaunt
Since 1.5.2 the framework is its own adopter — the proof, the boundaries, and the bugs dogfooding caught.
Get things done
Task-first guides: writing specs, dependencies, contract mode, the daemon, and CI.
Understand it
How runtime forwarding, incremental builds, and the Codex engine actually work.
Look it up
The CLI, jaunt.toml schema, JSON output, and the generated-file layout.
Two ways in
Evaluating Jaunt? Pick the Python quickstart or the TypeScript quickstart, then read design philosophy and the honest limitations before you commit to it.
Building an agent that drives jaunt? The coding agents guide covers jaunt instructions -- the canonical machine-readable project primer -- and the --json contract that every command speaks.