SSD Nodes Learn 8GB RAM — $66/yr
Guides Matt ConnorBy Matt Connor

DESIGN.md: the file after AGENTS.md

AGENTS.md tells a coding agent how to work in your repo. DESIGN.md tells it why the code is shaped that way, so it stops undoing your decisions.

What DESIGN.md is, and what AGENTS.md does not cover

DESIGN.md is a markdown file in your repository root that tells an AI coding agent why the code is shaped the way it is. AGENTS.md answers a different question: how to work here, which means the build command, the test command, the lint that has to pass, and the paths to leave alone. DESIGN.md records the decisions that are already settled, and what breaks when one of them is undone.

A coding agent, meaning a tool like Claude Code or Cursor that reads and edits your repository on its own, is confident by default. It finds a pattern it does not recognise and it improves that pattern. A hand-written cache becomes Redis (an in-memory data store), because that is what a cache looks like in most of the code the model has read. AGENTS.md does not stop this, because make test passes either way. The rule that was broken was never written down anywhere the agent could read it.

If you have not written the first file yet, start there. AGENTS.md and the HUMAN.md that sits beside it covers the format and where each tool looks for it. What follows is the chapter after that one.

What is actually inside a published DESIGN.md

The fastest way to learn the format is to read the files that companies publish about themselves. The repository official-design-md tracks only those. Its inclusion rule is one line, and that line is the whole point of the collection:

Every entry here is a DESIGN.md published by the company or project itself — not extracted, not reverse-engineered, not community-made.

As of August 2026 it lists seven: Atlassian, Clerk, Mintlify, Nuxt, Resend, Vercel and VoltAgent. Each file sits at a stable public URL, so you can read one in a terminal right now.

curl -s https://nuxt.com/design.md | head -n 60
curl -s https://vercel.com/design.md | wc -w

Both of those are design system documents. They describe how a product should look: colour, type, spacing, motion. Read past the subject matter, because the useful part is the shape of the writing rather than the topic.

The Nuxt file runs to roughly 2,100 words, and most of it is a rule with its reason attached:

Dark mode is the default theme.
Colors are semantic (`primary`, `neutral`, `error`…) rather than hardcoded hex values in components.
Don't hardcode `#00DC82` in UI code — use `text-primary` or `color="primary"`.

The Vercel file is longer, around 6,500 words in August 2026, and it goes one step further. One of its headings is Reject generated-design reflexes. Underneath sits a list of what a capable generator reaches for when nobody has told it not to:

Hard reject decorative gradients, gradient text, glows, blobs, stripes, textures, grid backgrounds, glass effects, paper simulations, colored side rails, ornamental shadows, and fake depth.

That sentence defines the file type. It is a written list of the defaults a confident model produces, published so the model stops producing them. Every DESIGN.md worth committing is that list for some domain.

Why do companies publish their own DESIGN.md?

The community got there first. awesome-design-md holds 73 files reverse-engineered from public websites, each written to the same nine-section format, so an agent can be pointed at one and produce something close to that look. Those files are useful and they are still guesses. Nobody at the companies reviewed them.

A first-party file is different because it is the source rather than a reading of the output. When Vercel changes its type scale, vercel.com/design.md changes with it. A copy scraped in March keeps teaching your agent the old scale, and nothing in your repository will tell you the copy went stale.

Seven publishers is a small number, and the repository says as much: the standard is new and official adoption is growing. Both collections are maintained by VoltAgent, an open source agent framework that publishes its own file too, so read the list as a tracker and not as a neutral census. It is still worth watching, because of who the seven are. They are the companies whose front-end code other developers copy most, and their files are becoming the worked example of what a DESIGN.md is. Compare the path AGENTS.md took: agents.md now counts over 60,000 open source projects using the format, and stewardship sits with the Agentic AI Foundation under the Linux Foundation. Conventions for agent-readable files are settling quickly, and they are settling from the top.

What goes in a DESIGN.md when the project has no user interface

Most software running on a VPS has no visual language to specify. The file still earns its place, because the mechanism has nothing to do with colour. It is about writing down the constraints that a confident editor would otherwise violate without noticing.

Invariants. One sentence each, stating something that must stay true after any edit. "Every write goes through queue.enqueue(). A direct database write skips the audit log, and the audit log is what the compliance export reads." An invariant with its reason attached survives contact with a task you never anticipated. An invariant on its own reads as a preference, and preferences get optimised away.

Rejected alternatives. The obvious option, and why it lost. "We do not use Redis for caching. The service runs on a single VPS, so an in-process map is faster and it is one less daemon to keep alive. Revisit this when a second application server exists." Without that paragraph, an agent asked to speed up the cache adds Redis, and it is right to do so: you never told it the constraint. This is the section that pays for the whole file.

Boundaries. The places where a small edit has a large blast radius. The database schema. The public route prefix that customers already script against. The config file a deploy reads before the application starts. The cron entry that assumes only one copy of it runs. Name them, and say what a change to each one costs.

Vocabulary. If the code says tenant and the team says customer, write the mapping down. An agent that guesses wrong here produces code that reads fine and models the wrong thing, which is the hardest kind of mistake to spot in review.

A DESIGN.md you can copy today

# DESIGN.md

## What this service is
One paragraph. What it does, who calls it, where it runs.

## Invariants
- Every write goes through `queue.enqueue()`. Direct writes skip the audit log.
- Timestamps are stored as UTC integers. Only the display layer converts them.
- One process writes to SQLite. The database is in WAL mode, and a second writer
  gets `database is locked` under load.

## Rejected alternatives
- **Redis for caching.** Rejected: one VPS, one process, an in-process map is
  enough. Revisit at two application servers.
- **An ORM for the reporting queries.** Rejected: the reports are four hand-tuned
  SQL statements. The generated query joined the same table twice.

## Boundaries
- `schema.sql` is append-only. A column rename needs a migration and a deploy window.
- The `/v1/` routes are public. Customers script against them, so the response
  shape is frozen.

## Vocabulary
- `tenant` in code is what the docs and the billing system call a customer account.

## Keeping this file honest
Update it in the commit that changes the decision. A stale DESIGN.md is worse
than no DESIGN.md, because the agent believes it.

Fill the two sections you can write from memory today, invariants and rejected alternatives, and leave the rest as headings. A file with four honest lines works. A file with forty guessed ones does not.

Some tools load every markdown file in the repository root and some load only the one they are told about, so do not assume. Add a pointer to AGENTS.md:

Read DESIGN.md before editing anything under `src/`. It lists the invariants and
the alternatives that were already rejected.

The anti-pattern: a DESIGN.md that repeats the README

The most common bad version reads well and teaches nothing. It opens with what the project does, lists the features, explains how to install it, and closes with the licence. Every line of that is already in the README, and none of it says why anything is the way it is.

That costs you twice. The first cost is context. A file the agent reads at the start of every task is paid for on every task, and a duplicated install section is pure overhead against a fixed window. Budgeting that window is a skill of its own, covered in managing the context window in Claude Code. The short version: anything loaded automatically should be the highest-value text in the repository.

The second cost is worse. Two copies of the same statement drift apart. The README says the service listens on 8080, DESIGN.md still says 3000, and the agent has no way to rank one over the other, so it picks one and writes code around it. A file that is sometimes wrong gets consulted with the same confidence as a file that is always right.

The test is quick. If a paragraph would sit comfortably in the README, cut it from DESIGN.md. What remains should be the part you would say out loud in a code review, the part that starts with "we tried that already".

How do you know the file is working?

There is no linter for this. There is a check you can run in a minute.

Give the agent a task that walks straight into an invariant. "Add a background job that marks stale rows as expired." A file that is doing its job shows up in the answer before any code does: the agent should tell you the job writes through queue.enqueue(), because a direct write would skip the audit log. If it opens a database connection and writes, one of two things is true. The file is not being read at all, or the invariant is worded loosely enough to argue with.

Watch the token count as well, since this file is loaded on every turn. If context usage jumps after you add DESIGN.md and the answers do not get better, the file is carrying prose the agent already had. Reading the token counters in Claude Code shows where that budget goes.

This matters most when the agent lives on a server rather than on your laptop. An agent working in a long-running session, like the setup in a Claude Code workspace on a VPS with tmux, has no memory of yesterday's conversation. The repository is the memory. Everything you explained in chat and never committed is gone by the next session, and DESIGN.md is where that explanation goes so it survives.

Start with the decisions you argue about

The first version takes twenty minutes. Open the last several pull requests where a reviewer wrote "no, we do it differently here". Each of those comments is an invariant that was never written down, and each one is a place an agent will make the same mistake, faster and more often than a person would. Add to the file when it fails you, not on a schedule. If you are still working out where agents fit into a normal development workflow, the 2026 guide to learning AI agents is a reasonable next stop.

FAQ

Is DESIGN.md an official standard?

Not in the way AGENTS.md is. AGENTS.md has a home at agents.md, over 60,000 open source projects using it, and stewardship under the Agentic AI Foundation, part of the Linux Foundation. DESIGN.md as of August 2026 has no governing body and no published specification. What it has is first-party adoption: seven companies, including Vercel, Nuxt, Atlassian and Resend, publish one at a public URL, and a community collection holds 73 more reverse-engineered from public sites. Treat it as a convention you can adopt now and extend freely, because nothing validates your section names.

Should DESIGN.md just be a section of AGENTS.md?

For a small repository, yes. One file the agent definitely reads beats two files where one gets ignored. Split them when AGENTS.md stops being scannable, or when you notice the two halves changing at different rates. AGENTS.md changes when the build changes. DESIGN.md changes when a decision changes, which is rarer and carries more weight. When you split, add one line to AGENTS.md telling the agent to read DESIGN.md before editing code, because not every tool loads every markdown file in the root.

How is DESIGN.md different from an architecture decision record?

An ADR (architecture decision record) is a dated record of one decision, and a healthy project accumulates dozens of them in a folder. That is a history, and history is expensive to load, since an agent would have to read all of them to work out which are still true. DESIGN.md is the current state, written to be read in full on every task. Keep both if you already write ADRs. The ADR says what was decided and when. DESIGN.md says what is true today, and it is the one you point the agent at.

How long should a DESIGN.md be?

Short enough to load on every turn without regret. The published examples are long because they specify a whole visual language: the Nuxt file is about 2,100 words and the Vercel file about 6,500 as of August 2026. A backend service usually needs far less. Start at one page and grow it only when an agent gets something wrong that a single sentence would have prevented. Length is not the measure. Every line should be a thing the agent would otherwise get wrong.