If you’re starting from scratch, this page is for you. No code yet? Just an idea? That works too. This page shows how to go from one sentence to a project that coding agents (AI tools that write code) build goal by goal, with you deciding what “done” means before anything gets written.
From an idea
evolve new grapher --idea "A visual node editor in the browser, in the spirit of Unreal's Blueprints: add nodes to a canvas, wire an output pin to an input pin, and see the graph described as text."
Evolve starts a web app: a program that runs in the browser, written in Go and compiled to WebAssembly (a way to run such programs inside a browser), and sent to the browser by one small Go program. That means it’s built, checked and put live like any service. Then an agent reads your idea and suggests a roadmap, a list of goals in the order to build them:
Roadmap: a small visual node editor in the browser…
1 A person can add nodes to a canvas and see the graph described as text.
· a new page shows an empty graph
· the person adds two nodes and sees them on the canvas and in the text
2 A person can wire an output pin to an input pin by dragging…
· the person wires node 0 to node 1
· the person tries invalid wires and nothing is added
…
6 A person can type numbers into Number nodes and see the graph evaluated…
Each goal comes with scenarios: what a person does, step by step, and what they should then see (see browser checks).
Read them. They’re the specification, the description of what the app must do, so this is where you decide what you’re getting. You can approve them, edit them in your editor, or leave the proposal for later (evolve roadmap approve). Nothing is committed (saved into your Git history) until you approve it, and agents can never change the scenarios afterwards.
Then build it, one goal at a time:
evolve run next
Plans change, and that’s fine. Edit verification/roadmap.yaml (reword goals, add some, or mark reached ones retired: true) and run evolve roadmap revise. The scenarios follow, and the build carries on from where it is.
Sometimes a goal has to change what an existing protected test (one agents may never edit) checks. For that, give the goal unprotect: [path/to/that_test.go]. Agents may change those files for that goal only, and never evolve.yaml, verification/ or a check’s files.
Each goal is one run. It passes only when its scenarios pass in a headless browser (a real browser with no window, which Evolve drives) and every earlier goal’s still do. The next evolve run next merges the goal you just reached into your branch (your working line of code in Git) and starts on the next one. evolve roadmap shows where you are.
In our run, Claude Code proposed six goals with fourteen scenarios, and built the first two (a canvas of nodes, then wires between their pins) in under two minutes each.
Would you rather write the scenarios yourself? evolve new app --kind webapp starts the same web app with one scenario, “the app starts”, for you to build on.
An idea for a native app
If your idea says desktop, native, window or mobile, Evolve starts a native app (one you install, rather than open in a browser) in Go with Gio, a toolkit for building app interfaces in Go. That’s one codebase for Linux, Windows and macOS, and later Android, iOS and the browser.
evolve new blueprint --idea "A native desktop node editor in the spirit of Unreal's Blueprints: add nodes to a canvas, wire an output pin to an input pin, move nodes around, and see the graph described as text."
The app comes in two parts: ui/, its interface, which Evolve drives with no window, and cmd/<name>, which only opens the window. Gio’s code is kept inside the project (in vendor/) so checks can build the app with no network. Each goal comes with gui scenarios that name what a person sees (“Add node”, “node 0 output”) and the state they expect.
In our run, Claude Code proposed six goals with 22 scenarios, and built the first three (nodes, wires between pins, moving nodes with their wires) in about three minutes each.
On Linux, opening the window needs cgo (Go’s bridge to C code) and the EGL, X11 and Wayland development libraries, the system’s graphics and windowing code. The checks of the interface don’t.
An idea for a service
An idea about an API (a way for programs to talk to yours), endpoints (the addresses it answers) or a backend starts an HTTP service instead: a program that answers web requests. Evolve tells you which kind it picked, and --kind service, --kind webapp or --kind desktop picks for it.
evolve new tally --idea "A small JSON API for counters: create named counters, increment and read them, and list them."
A service’s goals are proven by example requests, written the same way --example takes them:
1 A client can create a named counter and read it back.
· POST /counters {"name":"visits"} => 201 {"name":"visits","value":0}
· GET /counters/visits => 200 {"value":0}
2 A client can increment a counter.
· POST /counters/visits/increment => 200 {"value":1}
…
When you approve, they become the service’s contract (the list of requests and the answers they must get), each marked with its goal, and the contract check runs them up to the goal being built. evolve run next works the same way here: a goal passes only when its examples, and every earlier goal’s, get the right answers.
An HTTP service, by example
The proof comes first
A brand new project has no tests, so there’s nothing to judge an agent’s work by. evolve new starts from the other end. You say what the service should do, as examples, and they become its contract before a line of it is written.
It’s a bit like agreeing the exam questions before the lesson. Agents can never change the contract. They build until it passes.
1. Describe it, by example
evolve new linkr \
--does "A URL shortener: POST a URL to get a short code, then GET it to be redirected." \
--example 'POST /links {"url":"https://evolve.dev"} => 201 has code' \
--example 'GET /links/unknown => 404'
Leave the flags (the --does and --example options) off and it asks you for both. An example is a request, then the answer it should get. Requests are written the way the web writes them: a method (GET to fetch, POST to send), a path, and a status code for the answer (200 means OK, 201 created, 404 not found):
| Example | Means |
|---|---|
GET /healthz => 200 |
answers with status 200 |
POST /links {"url":"https://evolve.dev"} => 201 has code |
with this JSON body, answers 201 with a code in its JSON |
GET /links/abc => 200 {"url":"https://evolve.dev"} |
answers 200 with exactly this value in its JSON |
2. What it sets up
- A Go service with only a health route (an address that answers “I’m up”), which reads the port it listens on from
$PORT, and a test of it. verification/contract.yaml: your examples, protected.evolve.yaml, the policy (the rules every change is judged by), exactly asevolve initwould suggest it: build, tests, contract and speed checks, with your tests and dependencies (other people’s code your project uses) protected.- The first goal,
objectives/linkr-v1.yaml: build it until every example passes.
It commits the lot, registers the project with Evolve’s server and records the goal.
3. Let an agent build it
evolve run start --objective linkr-v1 --repo linkr --agent claude-code --wait
Or add --agent claude-code to evolve new and it starts straight away. Each attempt (an agent’s try at the goal) is built and checked like any change. The run ends verified: the chosen change passed every check and waits for you, with the command to merge it into your code:
run 7a1f77ad closed: verified (attempt #2 passed every check; nothing to deploy.
Merge it with: git pull …/linkr.git refs/evolve/runs/7a1f77ad…/attempts/9f39c44c…)
In our run, Claude Code built the shortener in under a minute: POST /links answers 201 (the web’s code for “created”) with a short code, and GET /links/{code} sends you on to the original address.
The examples are the specification
Agents build what the examples ask for, and choose the rest themselves. Our examples never said where a code gets looked up, so the agent chose /links/{code}. If something matters to you, say it in an example: GET /links/abc => 302.
Add cases to verification/contract.yaml as the service grows. Every later change has to keep them passing.
Next
Once it runs somewhere, give it an environment, a place Evolve can put it live (the operator config), and set the policy’s deployment section. From then on, changes are put live, watched and rolled back like any other.