Most frontend teams don’t suffer from a lack of documentation.
They suffer from a lack of decision history.
Six months into a project, someone inevitably asks:
“Why are we using Pinia instead of TanStack Query?”
“Why did we choose Nuxt over React?”
“Why are we using SSR?”
“Why does every API call go through this abstraction?”
“Why can’t I just call the backend directly from the component?”
The frustrating part is that someone already answered those questions — usually multiple times. The problem is that the answers disappeared inside Slack conversations, Teams meetings, pull request comments, or simply inside one developer’s memory.
Eventually that developer leaves the project, and the entire team is debating the exact same problem again.
Table of contents
Open Table of contents
Code tells you what. Documentation tells you how. ADRs tell you why
Imagine opening a repository and seeing this:
src/
├── components/
├── composables/
└── stores/
You immediately know what exists. If the project has good documentation, you probably know how those pieces fit together. But you still don’t know why the project looks this way.
- Why Pinia?
- Why Nuxt?
- Why server-side rendering?
- Why Keycloak?
- Why cookies instead of
localStorage? - Why custom composables instead of directly calling
fetch()?
Those decisions rarely exist anywhere. Yet they’re often the most expensive decisions to change.
Architecture isn’t only for architects
One misconception I see frequently is that architecture decisions belong only to software architects. In reality, frontend teams make architectural decisions almost every sprint. For example:
- Choosing React, Vue or Angular
- CSR vs SSR vs SSG
- State management
- API communication strategy
- Authentication flow
- Form architecture
- Internationalization strategy
- Monorepo vs multiple repositories
- Component library
- Styling approach
- Testing strategy
None of these are implementation details. They’re decisions that influence every feature developed afterwards, and they deserve to be documented.
ADRs are intentionally simple
An Architecture Decision Record (ADR) is just a short Markdown document describing a single architectural decision.
That’s it. No Confluence pages, no Visio diagrams, no 30-page design documents.
A typical ADR contains:
- Status
- Context
- Decision
- Alternatives considered
- Consequences
One decision. One document. Nothing more.
For example:
# ADR-007: Use Nuxt instead of Vue SPA
## Status
Accepted
## Context
The application requires SEO, fast first paint, and server-side authentication.
## Decision
Use Nuxt with hybrid rendering.
## Alternatives
- Vue SPA
- Next.js
- Astro
## Consequences
Positive:
- Better SEO
- SSR support
- Route middleware
Negative:
- More complex infrastructure
- Server deployment required
Reading this takes less than two minutes, but it can save hours of future discussions.
ADRs reduce repeated discussions
One of the biggest benefits isn’t documentation. It’s reducing repeated conversations.
Without ADRs:
“Should we switch to TanStack Query?”
Three developers investigate. Two create proof-of-concepts. One writes benchmarks. The meeting lasts an hour. Then someone remembers:
“Didn’t we already discuss this last year?”
With ADRs, someone searches the repository, reads ADR-012, and sees the context, alternatives, trade-offs, and why the decision was made. Discussion finished in five minutes.
Notice something important here. The goal isn’t to prevent future changes — it’s to preserve the reasoning behind previous ones. If the context changes, write a new ADR that supersedes the old one rather than rewriting history.
Architecture evolves. Your decision history should too.
ADRs make onboarding dramatically easier
Every experienced developer has joined a project and immediately started asking questions like:
- Why is everything wrapped in custom composables?
- Why do we have three different API clients?
- Why does authentication work this way?
- Why can’t I use local component state here?
Most of those questions aren’t answered by code. They’re historical decisions.
Good onboarding isn’t teaching someone the framework. It’s teaching them the reasoning behind the architecture, and ADRs become that missing history.
Instead of interrupting senior developers with questions that have already been answered, new team members can understand why the project evolved the way it did.
ADRs make AI a better teammate
This benefit barely existed a few years ago. Today, it may be one of the strongest arguments for writing ADRs.
Modern AI coding assistants can read your repository, understand patterns, and generate working code remarkably well. What they cannot reliably infer is why your team made certain architectural decisions.
Consider a simple prompt:
“Implement a new file upload feature.”
Without ADRs, the AI might reasonably suggest:
- introducing a new state management library
- calling APIs directly from components
- storing authentication tokens in local storage
- creating another HTTP client
- using a completely different form library
None of those suggestions are inherently wrong. They’re simply unaware of the architectural constraints your team has already agreed upon.
Now imagine your repository also contains ADRs explaining:
- why Pinia was selected
- why every API call goes through a shared client
- why authentication uses HTTP-only cookies
- why forms follow a specific validation architecture
- why server-side rendering was chosen
- why certain libraries were explicitly rejected
Suddenly the AI has access to the same context as a senior engineer joining the project. Instead of generating code that is merely technically correct, it can generate code that is architecturally consistent.
In practice, this means:
- fewer prompts explaining your architecture
- fewer AI-generated pull requests that violate team conventions
- fewer unnecessary refactors
- more consistent implementations
- AI suggestions that respect previous engineering decisions
As AI becomes another contributor to the codebase, ADRs stop being just documentation. They become part of the project’s institutional knowledge — not just for humans, but for AI as well.
When should you write one?
Not every decision deserves an ADR. Changing a button color doesn’t. Renaming a component doesn’t. Adding another endpoint doesn’t.
Ask yourself one question:
Will someone ask “Why did we do this?” a year from now?
If the answer is yes, write an ADR.
In my experience, frontend teams should strongly consider ADRs for decisions around:
- Framework selection
- Rendering strategy
- Authentication
- State management
- API architecture
- Design systems
- Component libraries
- Monorepo strategy
- Security decisions
- Performance strategies
Final thoughts
I’ve introduced ADRs on multiple frontend projects, and they consistently become one of the highest-return engineering practices. Not because they improve documentation, but because they improve engineering decisions.
Writing an ADR forces the team to think through the trade-offs before committing to a direction. Months later, it prevents the same conversations from happening again. Years later, it explains why the architecture looks the way it does. And today, it gives AI assistants the context they need to produce code that aligns with your team’s architecture instead of fighting against it.
The codebase is your implementation history. ADRs are your decision history.
In the era of AI-assisted software development, both are equally important.