Jaunt

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

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.

On this page