From the Latin veritas, meaning truth. Verification is built into the language from the ground up.
Programming languages have always co-evolved with their users. Assembly emerged from hardware constraints. C from operating systems. Python from productivity needs. If models are becoming the main authors of code, the languages they write should change for them too.
Syntax is the easy part. The hard problem for a model is coherence at scale: models are pattern matchers optimising for local plausibility, not architects holding the whole system in mind.
Research on model-written code finds that names are a particular weakness. Models pick misleading names, reuse names wrongly, and lose track of which name refers to which value. Vera takes the variable names away.
The model doesn't need to be right. It needs to be checkable. Structural references replace names. Contracts are mandatory. Effects are typed. Every function is a specification the compiler checks against its implementation, proving what it can with Z3 and compiling runtime checks for most of the rest.
The FAQ goes deeper into the design: why there are no variable names, what gets verified, and how Vera compares with Dafny, Lean and Koka.
Nothing is implicit. The signature declares types, preconditions, postconditions and effects, and vera verify proves this contract with Z3 before the program ever runs. A zero divisor the verifier can find is refused at compile time (E526) rather than left to crash at run time.
public fn safe_divide(@Int, @Int -> @Int) requires(@Int.1 != 0) ensures(@Int.result == @Int.0 / @Int.1) effects(pure) { @Int.0 / @Int.1 }
public fn fizzbuzz(@Nat -> @String) requires(true) ensures(true) effects(pure) { if @Nat.0 % 15 == 0 then { "FizzBuzz" } else { if @Nat.0 % 3 == 0 then { "Fizz" } else { if @Nat.0 % 5 == 0 then { "Buzz" } else { "\(@Nat.0)" } } } }
public fn classify_sentiment(@String -> @Result<String, String>) requires(string_length(@String.0) > 0) ensures(true) effects(<Inference>) { let @String = string_concat("Classify as Positive, Negative, or Neutral: ", @String.0); Inference.complete(@String.0) }
public fn research_topic(@String -> @Result<String, String>) requires(string_length(@String.0) > 0) ensures(true) effects(<Http, Inference>) { let @String = url_encode(@String.0); let @Result<String, String> = Http.get(string_concat("https://api.duckduckgo.com/?format=json&q=", @String.0)); match @Result<String, String>.0 { Ok(@String) -> Inference.complete(string_concat("Summarise this in one paragraph:\n\n", @String.0)), Err(@String) -> Err(@String.0) } }
public fn find_user(@String -> @Result<Array<Array<Option<String>>>, String>) requires(string_length(@String.0) > 0) ensures(true) effects(<DB>) { DB.query("SELECT name, email FROM users WHERE name = ?", [Some(@String.0)]) }
[E001] Error at main.vera, line 2, column 1: { ^ Function is missing its contract block. Every function in Vera must declare requires(), ensures(), and effects() clauses between the signature and the body. Vera requires all functions to have explicit contracts so that every function's behaviour is mechanically checkable. Fix: Add a contract block after the signature: private fn example(@Int -> @Int) requires(true) ensures(@Int.result >= 0) effects(pure) { ... } See: Chapter 5, Section 5.2 "Function Declaration Syntax"
Six of nine frontier models write 100% correct Vera, a language none of them had seen before.
A 60-problem benchmark across 5 difficulty tiers: pure arithmetic, strings and arrays, ADTs and exhaustive matching, recursion with termination proofs, and effects propagated across functions. Nine models, three providers, four modes each: Vera written against the full specification, Vera written from a plain English description with the model writing its own contracts, and the same problems in Python and TypeScript. The table shows three of the four modes as % solved, meaning the code compiled, ran and produced the right output. A refusal, a compile failure, a crash and a wrong answer all count as a miss.
| Model | Vera | Python | TypeScript |
|---|---|---|---|
| Claude Fable 5 ceiling | 100% | 97% | 97% |
| GPT-5.6 Sol (pro) ceiling | 100% | 95% | 100% |
| Claude Opus 5 flagship | 100% | 95% | 100% |
| Claude Opus 4.8 flagship | 93% | 98% | 100% |
| GPT-5.6 Sol flagship | 98% | 95% | 100% |
| Kimi K3 flagship | 100% | 100% | 100% |
| Claude Sonnet 5 workhorse | 97% | 98% | 100% |
| GPT-5.6 Terra workhorse | 100% | 95% | 100% |
| Kimi K2.6 workhorse | 100% | 97% | 100% |
Frontier models write Vera as well as they write the languages they were trained on. Vera scores highest, or joint highest, for six of the nine models.
Mandatory contracts and typed slot references give a model enough structure to make up for having no training data at all. Every one of these programs was written by a model that had never seen Vera, working from a single skill file in its context.
The gap between Python and TypeScript tells the same story. Python is dynamically typed, so a type error surfaces when the code runs; TypeScript rejects the same error before anything runs. Vera goes further than TypeScript, making requires, ensures and effects mandatory on every function and replacing variable names with typed slot references. Sort the three languages by how much they constrain the model, rather than by how much of them it has read, and the two that constrain it finish ahead of the one that doesn’t.
TypeScript earns its results from years of training data. Vera earns very nearly the same results with none. Whatever familiarity buys TypeScript, Vera’s constraints supply by other means.
Each model made one attempt per problem, with no pass@k, and each of the sixty problems is worth just under two percentage points. Language design can outweigh sheer volume of training data, and if you generate code at any scale, that’s worth knowing.
Results from VeraBench v0.0.18 against Vera v0.1.8. Inspired by HumanEval, MBPP, and DafnyBench.
Design principles
vera fmt settles it.@T.n), not arbitrary names.Key features
@T.n) replace variable names: @Int.0 is the most-recent Int binding, @Int.1 the one before. A whole class of naming hallucinations disappears from the language instead of being caught after the fact.decreases measure (or the Diverge effect) on every recursive one. vera test uses Z3 to generate inputs from the contracts and runs them through WASM, so there are no test cases to write by hand.<DB> effect accepts only a query written as literals in the source, never one spliced together from a runtime value. Interpolating user input into SQL is a compile-time error (E207), so every value goes through a ? placeholder. Injection safety stops being a discipline you have to remember and becomes a rule the compiler enforces.State and Exn are handled in Vera code; the host effects are backed by the runtime.n.requires that can never hold is refused, so a contradiction can’t prove everything. vera verify --timeout-ms sets the solver budget.@Nat underflow, a failed contract or assert, an index out of bounds or an escaped exception reports what kind of trap it is and how to fix it, the same way on wasmtime, in the browser and under WASI 0.2.Inference.complete is an algebraic effect: typed, checked against its contract, and backed by the host. It works with Anthropic, OpenAI, Moonshot, Mistral, xAI and DeepSeek.<Async> effect and compose with the rest of the effect system.<HttpServer> effect marks a total handle(Request -> Response). The accept loop lives in the host, so every handler contract is an ordinary proof obligation. vera serve runs it.vera compile --target wasi-p2 emits a component that any stock wasip2 host runs (experimental, covering IO and Random). --world server packages a handler as a wasi:http component for wasmtime serve.Vera compiles to WebAssembly. The same .wasm runs at the command line under wasmtime and in the browser inside a self-contained JavaScript runtime, and the same source builds a portable WASI 0.2 component.
$ vera run examples/hello_world.vera Hello, World! $ vera run examples/factorial.vera --fn factorial -- 10 3628800
vera run compiles to WASM and executes via wasmtime. --fn picks any public function; arguments follow --.
$ vera compile --target browser \
examples/hello_world.vera
Browser bundle: examples/hello_world_browser/
module.wasm
runtime.mjs
index.html
Self-contained, with no bundler. Serve it from any HTTP server (python -m http.server). IO.print writes to the page, and everything else the browser target supports behaves exactly as it does at the command line; parity tests hold the two runtimes to the same output on every pull request. Inference.complete and DB return an error in the browser by design, because the credentials they need would be readable from the page source. Reach them through a server-side proxy over Http.
$ vera compile --target wasi-p2 --world server \ examples/http_server.vera Compiled (WASI Preview 2 server component (run with: wasmtime serve <file>)): examples/http_server.wasm $ wasmtime serve examples/http_server.wasm Serving HTTP on http://0.0.0.0:8080/
--target wasi-p2 emits a WASI 0.2 component that any stock wasip2 host runs; wasmtime run module.wasm needs no flags and no Vera bindings. The target is experimental and covers IO and Random. --world server packages a handle(Request -> Response) program as a wasi:http component that wasmtime serve runs unmodified.
Python 3.11+. Everything installs into a virtual environment.
# Install the toolchain from PyPI python -m venv .venv source .venv/bin/activate python -m pip install veralang vera version # Optional: the language server for editors and agents python -m pip install "veralang[lsp]"
Upgrading from 0.1.x? The checker and verifier are stricter in 0.2.0, so some programs that 0.1.13 accepted are now refused. The two you’re most likely to meet are a recursive function with neither decreases nor Diverge (E137), and a decreases measure whose @Nat subtraction can underflow (E502). The CHANGELOG lists every new check.
The wheel installs the compiler and the vera command. Install from source for the full environment (the bundled examples, the conformance suite and the specification the agent docs teach from) or to work on the compiler itself.
# Clone and install from source git clone https://github.com/aallan/vera.git cd vera python -m venv .venv source .venv/bin/activate pip install -e ".[dev]" # Check, verify, run, compile the bundled examples vera check examples/absolute_value.vera vera verify examples/safe_divide.vera vera run examples/hello_world.vera vera compile --target browser examples/hello_world.vera
Three editors are supported out of the box. Vera Language for Visual Studio Code is the most complete: install it from the Marketplace or with code --install-extension veralang.vera-language, and it starts vera lsp for .vera files alongside syntax highlighting. A Vim package covers Vim 8+ and Neovim, and a Vera .tmbundle covers Sublime Text and other editors that read TextMate grammars.
Live proof-aware diagnostics, hover, slot go-to-definition and typed-hole completion come from the language server. The source install above (.[dev]) includes it; from PyPI, add it with python -m pip install "veralang[lsp]", or use pip install -e ".[lsp]" for a lighter source checkout. Any editor with a generic LSP client can point at vera lsp directly.
Every document here has a markdown alternate on the same domain, discoverable through the standard <link rel="alternate">, llms.txt, and the Mintlify llms-txt and llms-full-txt conventions.
builtins, effects and errors introspection commands.Claude Code discovers SKILL.md and CLAUDE.md automatically when working inside the repo. For other projects, install the skill manually:
mkdir -p ~/.claude/skills/vera-language cp /path/to/vera/SKILL.md ~/.claude/skills/vera-language/SKILL.md
For other models, point them at SKILL.md through the system prompt, a file attachment or retrieval. It’s self-contained and works with any model that reads markdown. Every Vera example in it, and on this page, is tested in CI.
The documents above are how machines read Vera. The language server is how they interrogate it. vera lsp holds a warm, incremental Z3 session between edits, and four custom methods (vera/speculativeEdit, vera/proposeEdit, vera/strengthenContract and vera/addEffect) tell an agent whether an edit keeps, breaks or strengthens a program’s proofs before it commits, then apply the edit only through the verification gate.
# vera/speculativeEdit: the proof delta for an in-memory edit { "ok": true, "proof_delta": { "newly_discharged": ["..."], "newly_undischarged": [], "timed_out": [], "removed": [], "unchanged": 11, "proof_regressions": [] }, "diagnostics": 0 }
A complete compiler with 164 built-in functions, ten algebraic effects (IO, Http, HttpServer, State, Exceptions, Async, Inference, DB, Random, Diverge), contract-driven testing with Z3, a language server with agent-facing proof deltas, and a 14-chapter specification. A 256-program conformance suite and 43 worked examples are validated against the spec on every pull request. It’s all developed in the open on GitHub under the MIT licence.