This article is published in English.
Vercel's AGENTS.md Skill Teaches AI Assistants 70 React Best Practices
A hands-on look at Vercel's react-best-practices agent skill, showing how it embeds 70 production-tested React rules directly into AI-generated code.
A colleague on the platform team shared a link in an internal Slack channel without any explanation — just the raw URL and a shrug emoji. The link pointed to the vercel-labs/agent-skills repository, specifically to the react-best-practices skill. The expectation going in was another rehashed "React performance tips" listicle dressed up for the AI moment. That's not what it turned out to be. Instead, it's a rulebook spanning 70 rules across 8 categories, which Vercel describes as distilled from more than a decade of watching production React and Next.js applications break in a recurring set of ways. Crucially, it's designed to be consumed by an AI coding assistant first, and by a human developer only secondarily.
That framing is really the core of what makes this notable, and it's worth pausing on before digging into the actual rule content.
What's Actually In the Repo
Installing the skill takes a single command:
npx skills add vercel-labs/agent-skills
Behind the scenes, this compiles into an AGENTS.md file — the convention that's gaining traction as a way to feed structured project context to coding agents (tools like Claude Code, Cursor, Codex, and OpenCode all look for this file). Once it's in place, your agent has a rulebook it can reference while writing or reviewing code, instead of relying purely on whatever assorted React tutorials happened to be scraped into its training data.
The 70 rules are split into eight categories, each carrying a priority label ranging from CRITICAL to LOW. The two categories marked CRITICAL are, predictably, the ones Vercel's team points to as the biggest sources of real-world breakage: sequential async operations that create waterfalls, and unchecked bundle size growth. A typical rule from the waterfall category captures the idea like this:
// Flagged: sequential awaits create a waterfall
async function getThreadPage(threadId) {
const thread = await getThread(threadId)
const author = await getAuthor(thread.authorId)
const replies = await getReplies(threadId)
return { thread, author, replies }
}
// Preferred: parallelize independent fetches
async function getThreadPage(threadId) {
const [thread, replies] = await Promise.all([
getThread(threadId),
getReplies(threadId),
])
const author = await getAuthor(thread.authorId)
return { thread, author, replies }
}
None of this is groundbreaking if you've spent time building with React. What's actually interesting isn't the substance of the rule — it's that the rule now exists in a form a machine can parse and apply uniformly across an entire codebase, including at 2am, on a pull request nobody scrutinized closely, without the fatigue or shortcuts that creep in when a deadline is looming.
Why This Is Different From a Linter
The immediate reaction is to wonder whether this is just ESLint wearing a different hat. In some ways, yes — but the mechanism is what sets it apart. A linter flags a problem after the code already exists. This approach is meant to influence the code while it's still being generated, catching the issue before it's ever typed out. If an AI assistant is responsible for somewhere between 30 and 60 percent of a given pull request's diff (and estimates on that number vary a lot depending on who on the team you ask), embedding the rules directly into the generation process is a fundamentally different kind of leverage compared to catching mistakes after the fact.
There's also a class of guidance that a linter simply isn't well suited to express: architectural judgment calls. A rule like "avoid creating a waterfall" is at least loosely something a linter could approximate given enough custom configuration and tolerance for false positives. But something like "this component should probably become a Server Component since it has no interactive behavior and the client boundary drawn around it looks arbitrary" requires actual reasoning about intent and structure — precisely the kind of decision you'd want an agent weighing in on, rather than something enforced through pattern matching.
Where Skepticism Creeps In
It's worth naming the uncomfortable part directly. A set of rules authored by the same company that builds the framework, and whose hosting platform happens to reward certain performance patterns, isn't a neutral document by default. Some of the CRITICAL-level guidance around bundle size lines up a little too neatly with the kinds of patterns that also make Vercel's own analytics dashboards and edge caching setup look great. That overlap doesn't automatically make the advice bad. Steering clear of async waterfalls is sound engineering no matter who's serving your app. Still, it's fair to keep in mind that vendor-curated "best practices" are never purely technical artifacts — there's always a faint marketing undertone baked in alongside the engineering advice.
The second worry is more structural: what happens once 70 rules turn into 200, or once skills from competing vendors start landing in the same AGENTS.md file and contradicting one another? Right now, with a single repo and a brand-new concept, things feel tidy and easy to reason about. Fast-forward eighteen months, though, and it's easy to imagine every framework, every hosting vendor, and every design system wanting its own skill installed. At that point your agent could be juggling a stack of rulebooks with conflicting guidance, and there may be no obvious way to tell which one is supposed to win.
Running It Against a Real Codebase
Out of curiosity more than expectation, the skill was pointed at a mid-sized internal dashboard to see what it would actually surface. The CRITICAL and HIGH findings turned out to be fairly mundane: a handful of sequential await calls that could have run in parallel, a couple of client components that had no real reason to be client components, and one mildly embarrassing case of pulling in an entire date-handling library just to format a single value. None of it would surprise anyone who's already done a serious performance pass on a React codebase. What did stand out was the speed — the agent needed roughly four minutes to locate and flag all of it, compared with however long a human reviewer would need to spot the same issues scattered across a large pull request.
That speed difference is really the core value proposition here. The rules themselves aren't groundbreaking — most experienced engineers already carry this knowledge around instinctively. What changes is that the rules now get applied with a consistency and pace that a human reviewer, especially one deep into their third review of the day, simply can't sustain.
An Underrated Benefit: Teaching, Not Just Enforcing
What actually changed the calculus wasn't the performance checks themselves — it was watching how a newer team member used the tool. This person had only been on the team a few months and was still getting familiar with the codebase. Before opening a pull request, they asked their agent to review it first. The agent caught a waterfall pattern and, instead of just flagging it, explained in plain language — tied directly to the specific rule — why running those calls in parallel actually mattered in that particular context. That's a meaningfully different experience from a linter that spits out a rule ID and a terse message you then have to go look up separately. It felt closer to a senior engineer leaving a genuinely helpful review comment, except the feedback arrived before the PR was even out of draft.
That might be the more compelling use case here, more than "the AI writes cleaner code." It's closer to "the AI teaches better habits," continuously and without needing someone to carve out time for mentoring or write onboarding documentation that's stale within six months. Whether this benefit survives once a team has fifty overlapping skill files installed — each with its own opinions, some inevitably clashing with others — remains an open question. But for a small team built around one experienced engineer and a few people still finding their footing, it already looks like a real force multiplier.
Where This Leaves Things
The skill ended up installed in the shared team configuration, largely because the downside is minimal and the upside — an agent that stops writing waterfall code — is a reasonable trade to make. Whether this pattern becomes the default way frameworks ship their opinions to AI agents, or just turns into another configuration file that quietly rots once the novelty fades and nobody bothers to update it, isn't clear yet. That's a question worth revisiting in six months rather than answering now.