Looks like TypeScript because it is
The TS 5 TSX grammar plus contextual declarations. Models already know it: 64 blind programs had zero syntax-caused errors.
table page api crud layout
state effect authLith is TypeScript, JSX and Prisma-style queries plus five declarations. An AI agent builds a correct, full-stack web app in about a quarter of the tokens it spends on Next.js.
table Todo own { title: string(1..200) done: boolean = false created: Date = now() } page "/" { const todos = db.todo.findMany({ orderBy: [{ done: "asc" }] }) return <main> <form action={addTodo}> <input name="title" /><button>Add</button> </form> <ul>{todos.map(t => <li> <input type="checkbox" checked={t.done} onChange={() => setDone(t.id, !t.done)} /> {t.title} </li>)}</ul> </main> } function addTodo(title: string) { db.todo.create({ data: { title } }) } function setDone(id: int, done: boolean) { db.todo.update({ where: { id }, data: { done } }) }
Six reference tasks, each written by an expert in Lith and in five popular web stacks: Next.js, SvelteKit, Laravel, Django and Rails. Tokens are counted with the o200k_base tokenizer: what a model actually pays.
Write tokens are the mean of 6 expert solutions per stack. Files and lines count everything written for a task, starting from each framework's standard scaffold. The blind result: a fresh model that had only the 2,349-token Lith card built 4 unseen apps, 2 testers each, 8 of 8 passing after compiler-guided fixes.
A todo app with per-user data, validation, a detail page and a 404. In Lith, the schema, pages, server logic and the server/client split all live together, and the compiler infers which code runs where.
table Todo own { title: string(1..200) done: boolean = false created: Date = now() } page "/" { const todos = db.todo.findMany({ orderBy: [{ done: "asc" }, { created: "asc" }] }) return <main> <h1>Todos</h1> <form action={addTodo} class="flex-row"> <input name="title" /> <button>Add</button> </form> <ul> {todos.map(t => <li> <input type="checkbox" checked={t.done} onChange={() => setDone(t.id, !t.done)} /> <a href={`/todos/${t.id}`} class={t.done ? "line-through" : ""}>{t.title}</a> <button onClick={() => deleteTodo(t.id)} class="text-red-600">Delete</button> </li>)} </ul> </main> } page "/todos/:id" (id: int) { const todo = db.todo.findUniqueOrThrow({ where: { id } }) return <main> <h1>{todo.title}</h1> <p class="text-gray-500">Created {todo.created}</p> </main> } function addTodo(title: string) { db.todo.create({ data: { title } }) } function setDone(id: int, done: boolean) { db.todo.update({ where: { id }, data: { done } }) } function deleteTodo(id: int) { db.todo.delete({ where: { id } }) }
Lith came out of a measured design lab: four competing designs, blind tests with models that had never seen the language, and a rule that every feature must lower total cost.
The TS 5 TSX grammar plus contextual declarations. Models already know it: 64 blind programs had zero syntax-caused errors.
table page api crud layout
state effect authRanges and lengths live in the type and are checked on every write and every form. Migrations for new columns are automatic.
title: string(1..200)
views: int(0..) = 0own scopes every query, update and delete to the logged-in user. Other users' rows act as missing.
table Note own { body: string }A function that touches db or me runs on the server; the browser calls it automatically. No "use server", no API glue.
<form action={addComment}>Inputs fill typed parameters by name. Every check runs at once, and failures re-show the form with messages next to each field. It works without JS.
fail({ body: "No links" })List, get, create, patch and delete with validation, JSON errors and correct status codes. Plain api routes return any Response.
crud "/api/products" Productstate and effect replace hooks. Pages without islands ship 0 kB of JavaScript; the client runtime targets 10 kB gzipped.
state starred = task.starredlith check returns the first error as JSON with a ready patch, so a fix costs one short round instead of a debugging session.
{ "code": "E0110", "patch": … }Emits standard JS, HTML and CSS on Node 22. Import any npm package; export .d.ts types so TypeScript can call into Lith.
import { marked } from "marked"Token counts: o200k_base · 6 measured tasks · 5 baseline stacks · blind validation n = 8