fakenerd.ai

ninja nerdingKent C. Dodds: your coding agent needs better primitives

Kent C. Dodds: your coding agent needs better primitives

Kent C. Dodds' 16-minute episode on why agents make a mess. The short of it: the agent is only as good as the building blocks your project gives it. Find them, then keep creating, combining, deleting and expanding them. A better prompt won't fix a missing piece.

Jump to the playground map, the before-you-build checklist, the four moves, or the homework prompt.

The video

16 minutes, posted Jul 15, 2026 on Kent's channel, episode 10 of Better with Kent. Talking head with slides on screen; no live coding. The chapters are his. Every timestamp on this page opens the video at that moment.

  1. 0:00 Bad agent output starts in the system
  2. 0:37 We are all tech leads now
  3. 1:28 What is a primitive?
  4. 4:57 Four moves: create, combine, delete, expand
  5. 6:01 Create: role-based access control
  6. 7:59 Combine: downshift and Kody packages
  7. 10:37 Delete: Instagram and Kody email
  8. 12:22 Expand: packages subscribe to events
  9. 13:51 Why good primitives work
  10. 14:43 Homework for your agent
  11. 15:32 Keep evolving the system

Ten signals

The whole episode in ten boxes. Each links to the part of this page that explains it.

  1. 010:00

    Bad output starts in the system

    If your agent keeps making garbage, a better prompt may not fix it. The project it works in decides most of the result.

    How
  2. 020:55

    You are the tech lead now

    A tech lead used to build the setup so the team could work well inside it. Now your team is agents, and that setup is your job.

    How
  3. 031:32

    A primitive is a building block the agent can trust

    The smallest piece your project offers that does one thing and fits with the others: a Button, a cancelSubscription action, a deploy command.

    How
  4. 041:40

    Seven areas need them

    Look, server actions, data, hosting, agent tools, repeatable jobs, and who is allowed to do what. Each one missing has its own kind of mess.

    How
  5. 056:02

    Missing piece, brittle workaround

    When a block is missing, the agent invents one on the spot. Those workarounds are broad, fragile, hard to check, and get rebuilt in every corner.

    How
  6. 065:00

    Four moves keep the set healthy

    Create what's missing. Combine what's the same. Delete what nobody needs. Expand what's almost right. Forever, not once.

    How
  7. 079:01

    Fewer concepts, fewer mistakes

    Three combobox components at PayPal became one library, downshift. Fewer things to know is better for people and for agents.

    How
  8. 0811:23

    Every block is something the agent might misuse

    Instagram started as Burbn and won by cutting most of it. Each thing you delete is one less thing the agent can reach for by mistake.

    How
  9. 0912:00

    Send events, let others react

    Kody's email handler did too much. Now it only announces “email received” and any package can listen and decide. Smaller, and far more flexible.

    How
  10. 1014:43

    Homework: ask the agent

    It plays in your playground every day. Ask it which blocks exist and what to create, combine, delete or expand. Then you decide.

    How

Words on this page

26 terms, in plain words. Skip this if you already build apps with coding agents.

Primitive
A basic building block your project offers: one job, a clear name, and it fits with the others. Kent: “the smallest unit of meaning that your system exposes.”
System
Everything the agent works inside: your code, design pieces, data, hosting, tools and rules.
Coding agent
An AI that reads and edits your project and runs commands: Claude Code, Codex, Cursor and the like.
Playground
Kent's word for the system, seen from the agent's side: a safe space with good toys in it.
Tech lead
The person on a team who sets up how the work is done so everyone else can move fast.
Action space
Everything the agent could possibly do next. Good primitives make it smaller, so there's less guessing.
Composable
Pieces that snap together like Lego, without you rebuilding how each piece works.
Workaround
A quick hack the agent writes because the proper piece doesn't exist. Works today, breaks later.
Component
A reusable piece of screen, like a Button or a text box, that looks and acts the same everywhere.
Design tokens
Named values for colours and spacing (say 8, 16, 24) so nobody picks a random one.
API
The doors your server offers to the rest of the app: “get this order”, “cancel this subscription”.
Resource and verb
A thing (orders) and what you can do to it (create, cancel). POST /orders means “create an order”.
Entity
A kind of thing your data stores, like a user, an order or a line on an order, and how they link up.
Infra
Where your app runs and lives: hosting, storage, deploys, secrets, scheduled jobs.
Cron job
A task that runs on a timer, like “every night at 2 a.m.”.
Volume
A storage disk on a server. Deleting the production volume means deleting the live database.
Shell script
A quick list of terminal commands. Fine once; risky as the agent's everyday tool.
MCP
Model Context Protocol: a standard plug that lets an agent call outside tools.
Event
An announcement that something happened, like “email received” or “payment failed”.
Subscribe
Asking to be told whenever a certain event happens, then reacting to it.
Inversion of control
Instead of one piece doing everything, it announces what happened and lets other pieces decide what to do.
RBAC
Role-based access control: people get roles (admin, user) and roles get permissions.
God-mode key
One password or key that can do everything. If an agent holds it, a mistake can do anything too.
Audit trail
A record of who did what and when, so you can check it afterwards.
Combobox
A text box with a dropdown of suggestions, like picking a country as you type.
Package (in Kody)
Kent's name for a saved bundle of code, screens and endpoints his assistant can reuse and share.

Primitives, in plain terms

Not a tool. A way of looking at your project: what building blocks does it hand the agent, and which ones is the agent forced to make up? “Your goal is to build, like, a playground for agents to operate in safely.” 1:05

Weak system · the agent guesses

  • No Button, so it styles each one by hand.
  • No deploy command, so it types raw commands.
  • No roles, so it gets the one key that does everything.
  • Every task, it rebuilds a little more of the same.

Good primitives · the agent assembles

  • It picks the Button and the spacing tokens.
  • It runs deploy, which has a preview and a rollback.
  • It works as a user with the permissions it needs.
  • Fewer choices, fewer mistakes, easy to check.

Kent's framing: a tech lead used to build the setup so the people on the team could work well. “Now we are all the tech leads,” because agents work inside the setup you design. That setup is the scarce, valuable part of the job now. 0:55 Six examples follow, three basic and three advanced. They are ours, written to his four moves.

Basic

  1. 01Every button on your site looks a bit differentcreate · UI & design

    Agent guessing

    The agent styles each new button by hand. Five pages, five shades of blue, three corner sizes.

    With the primitive

    One Button component and a short list of colours and spacings. Your rules file says: use these, never invent new ones.

  2. 02Three forms, three ways to send an emailcombine · API & backend

    Agent guessing

    Contact, signup and booking each have their own email code. A fix in one never reaches the others.

    With the primitive

    One sendEmail action all three call. Fix it once, fixed everywhere.

  3. 03An old page nobody visitsdelete · Features

    Agent guessing

    A testimonials page from last year. The agent keeps updating it every time it touches the layout.

    With the primitive

    Gone, with its code. One less thing to maintain and one less thing for the agent to trip over.

Advanced

  1. 04The agent deploys by typing raw commandscreate · Infra & platform

    Agent guessing

    Every deploy is a fresh set of terminal commands. One day it points at production by mistake.

    With the primitive

    One deploy command with a preview step and a rollback. The agent runs that and nothing else.

  2. 05A second newsletter listexpand · API & data

    Agent guessing

    The signup code only knows one list, so the agent copies it to make a second form.

    With the primitive

    The signup action takes a list name. One piece now covers both, and the next list is free.

  3. 06Three timers all checking for new orderscombine · Workflows

    Agent guessing

    A receipt job, a stock job and a Slack job each poll the database every five minutes.

    With the primitive

    One “order created” event. Each job subscribes and reacts the moment it happens.

Everything named

Almost everything he names is from his own stories. You need none of it to start: the idea works in any project with any agent.

Your coding agentClaude Code, Codex, Cursor or any agent that can read your project.The one doing the homework. He doesn't name a brand.to start
KodyKent's AI assistant, sold as “your agents' cloud”: memory, packages, triggers and keys for any agent. Free tier, Pro $12 a month.Three of his examples: roles, packages, the email events.no
MCP serverA service that offers tools to an agent through MCP.Kody is one. Its tools include search and execute.no
Cloudflare D1A small database hosted by Cloudflare.Where Kody's old “skills” were saved as rows.no
Cloudflare ArtifactsGit repositories hosted inside Cloudflare.Why he replaced skills with packages: a whole repo beats a saved snippet.no
Durable ObjectsCloudflare's small, long-lived servers that keep their own state.Named as one of the things packages can now bundle.no
downshiftKent's open-source library for comboboxes and suggestion boxes, built at PayPal.His combine example: three components became one.no
Instagram (Burbn)Instagram began as Burbn, a check-in app in the style of Foursquare.His delete example: cut everything but photos.no
RBACRoles and permissions. A pattern, not a product.His create example: admin vs user before community packages.later

The agent playground

His on-screen diagram: the agent goes through auth, then reaches six areas. The building blocks and the “without it” line in each area are copied from his screen cards. Click an area, or follow one of his changes and watch which areas it touches. 1:40

The agent playground · his diagram, made clickable

AI agent

Everything below sits behind that gate.

Red = the area you picked. Dark border = the area the story below is touching.

Follow one change through it

His delete-and-expand example. One rigid block becomes two small ones that snap together. Press Start and watch which areas light up.

his story, said; the bus diagram is on his slides

Small, callable capabilities · from the screen

Watch at 3:33

Agent tools

  • Searchsearch(query)
  • Executeexecute(task)
  • Publishpublish(package)
  • Without itDisposable shell scripts

“If the agent doesn't have really good callable tools, then you're going to end up with … just writing one-off bash scripts.”

On his slides

Looks like: Callable capability: a Kody export, an MCP tool, search, execute. Without it: Browser automation, scraping, one-off bash.

Ask your agent about this area · ours

Which one-off scripts have you written in this project more than once? Which of them should become a named command or tool?
  1. Auth & trust Roles and permissions

    Blocks: User (Publish · Fork), Admin (Review · Delist), Permission check (Scoped and auditable). Without it: God-mode access.

    Ask: Which keys or accounts in this project can do everything? Where should a narrower role or permission exist instead?

  2. Agent tools Small, callable capabilities

    Blocks: Search (search(query)), Execute (execute(task)), Publish (publish(package)). Without it: Disposable shell scripts.

    Ask: Which one-off scripts have you written in this project more than once? Which of them should become a named command or tool?

  3. API & backend Resources and operations

    Blocks: Resource (/orders/:id), Verb (POST /orders), Business action (cancelSubscription()). Without it: Duplicated business logic.

    Ask: Where is the same business rule written in more than one place? Which actions should exist as one named function?

  4. Data Entities and relationships

    Blocks: User (id · email), Order (userId · total), Line item (orderId · product). Without it: Ad-hoc data shapes.

    Ask: List the main kinds of data in this project and how they link. Where is the same thing stored in two different shapes?

  5. UI & design Interface building blocks

    Blocks: Button (Save changes), Text field (Email address), Spacing tokens (8 · 16 · 24). Without it: Inconsistent interfaces.

    Ask: Which screen pieces get rebuilt by hand instead of reused? Which colours or spacings are used that aren't in the design tokens?

  6. Workflows Repeatable control flow

    Blocks: Retry (Backoff built in), Queue (Ordered work), Schedule (Predictable timing). Without it: Reimplemented process logic.

    Ask: Where does the code retry, wait, poll or run on a timer by hand? Which of those should use one shared retry, queue or event?

  7. Infrastructure Safe platform capabilities

    Blocks: Deploy (Known environments), Storage (Scoped data access), Secrets + cron (Safe and scheduled). Without it: Unsafe one-off operations.

    Ask: How do deploys, secrets and scheduled jobs work here today? Which steps does an agent have to improvise in the terminal?

Kody needs roles his story, said

  1. The feature: community packages. People can publish a Kody package to a public list so others can copy it into their own Kody.
  2. The gap: no admin vs user. Someone has to review the list and pull bad packages. That needs an admin role with powers a normal user doesn't have, and Kody had no roles at all.
  3. The tempting shortcut. Tell the same agent: build roles quickly on the side, then carry on with packages. He has done that before.
  4. What he did instead: a separate agent for roles. A new agent, made responsible only for role-based access control. Roles got built as a proper block first, not as a side job.
  5. Then the feature, on solid ground. Roles merged the day he recorded. Now the packages agent can lean on a real permission check instead of inventing one.

Kody's email handler his story, said; the bus diagram is on his slides

  1. Before: one big email handler. An email arrives. Kody runs a few agent turns with all its tools, does what the email asked, and replies. All built in.
  2. The problem: too specific, too rigid. It only did the one thing it was built for. Anything else you wanted from an email meant changing the handler.
  3. Delete the handler. The big email-processing block goes away.
  4. Shrink email to one announcement. When an email arrives, Kody now just publishes an event: email received. That's all email does.
  5. Expand packages: they can subscribe. Packages gain one new ability: listen for events. A small addition to a block that already existed.
  6. They meet on one event bus. Email announces, packages listen. Two simple pieces combine cleanly.
  7. Now anyone can handle email their way. One package ignores the wrong subject line. Another reads the body and acts on it. Any number of them, without touching email.
  8. A bit more work, done by agents. Inversion of control asks more of whoever builds the package. That's fine: agents write most of the code anyway.

The primitives checklist

What to have in place before the agent builds features. Kent's seven areas, plus three we add because the agent needs them to check its work, read its errors and find everything else. The items and examples are ours. Start with the day-one set; add the rest when the app needs it.

10 areas

7 from Kent, 3 FakeNerd adds.

32 day-one blocks

Before the first feature. A small site may need only half.

24 for later

Add each when a feature needs it, not before.

0 of 32 day-one blocks ticked

01UI & designKent's area

So every screen the agent makes looks like the same product.

02DataKent's area

So the agent stops guessing what a “customer” or an “order” is.

03API & backendKent's area

So each business rule lives in one place, not in every screen.

04Auth & trustKent's area

So neither you nor the agent ever needs a key that does everything.

05InfrastructureKent's area

So the agent never improvises a command against production.

06Workflows & eventsKent's area

So retries, timers and reactions aren't rewritten by hand in every feature.

Nothing on day one. Add these when the app needs them; switch to Everything to see them.

07Agent tools & scriptsKent's area

So the agent runs your commands instead of writing throwaway ones.

08ChecksFakeNerd add

So the agent can prove its own work before you look.

09Errors & logsFakeNerd add

So when something breaks, the agent can read what happened.

10Rules for the agentFakeNerd add

So the agent can find all of the above. A block it can't find doesn't exist.

FakeNerd starter · set up the day-one blocks

Before we build features, set up the building blocks this project should have. Work one area at a time.

The product: [one or two sentences]
The stack: [framework, database, host, or "you choose and tell me why"]

1. Read the project. For each area below, tell me which blocks already exist (with the file) and which are missing:
   UI & design, data, API & backend, auth & trust, infrastructure, workflows & events, agent tools & scripts, checks, errors & logs, rules for the agent.
2. Propose the "day one" set only: the smallest blocks we need before the first feature. Skip anything we don't need yet.
3. Wait for my OK. Then build one area per change, on a branch, smallest first.
4. After each area, add its blocks to PRIMITIVES.md under "Use these, don't rebuild them", and run the checks.

The whole checklist · paste into your project

# Primitives checklist

Day one = before the first feature. Later = when you need it.

## UI & design

- [ ] Colour and spacing tokens (day one): --brand, --ink, spacing 4 · 8 · 16 · 24
- [ ] Type scale (day one): one font, body 16, headings 20 · 28 · 36
- [ ] Button (day one): <Button variant="primary | secondary | danger">
- [ ] Form fields (day one): <TextField label error />, Select, Checkbox
- [ ] Page layout (day one): <PageShell>, <Container>, <Stack gap={16}>
- [ ] Feedback pieces (later): Toast, Modal, empty state, loading skeleton
- [ ] One icon set (later): lucide-react, nothing else

## Data

- [ ] Main entities, written down (day one): User, Project, Order, with their fields
- [ ] How they link (day one): an Order belongs to one User
- [ ] Standard fields (day one): every table has id, createdAt, updatedAt
- [ ] One way to change the database (day one): npm run db:migrate
- [ ] Fake data to test with (later): npm run db:seed
- [ ] A rule for deleting (later): archive with deletedAt, never hard delete

## API & backend

- [ ] Named actions (day one): createOrder(), cancelSubscription(id)
- [ ] Input checking (day one): one schema per action (Zod or similar)
- [ ] One error shape (day one): { error: { code, message } }
- [ ] One wrapper per outside service (day one): lib/email.ts, lib/payments.ts
- [ ] Paging for long lists (later): listOrders({ cursor, limit })
- [ ] Rate limits (later): limit("signup", 5 per minute)

## Auth & trust

- [ ] Sign-in (day one): one auth provider, getCurrentUser()
- [ ] Roles (day one): admin, member (even if it's only you)
- [ ] Permission check (day one): requireRole("admin") at the top of every action
- [ ] Secrets out of the code (day one): .env locally, never committed
- [ ] Narrow keys for agents (later): an API token that can read, not delete
- [ ] Audit log (later): who did what, when, to which record

## Infrastructure

- [ ] Named environments (day one): local, preview, production
- [ ] One deploy command (day one): npm run deploy: preview first, then promote
- [ ] A rollback you can name (day one): the command to go back one version
- [ ] Settings read in one place (day one): lib/env.ts, fails loudly if a secret is missing
- [ ] File storage (later): one bucket, one uploadFile() helper
- [ ] Backups, and a restore you've tried (later): nightly copy, restored once on purpose

## Workflows & events

- [ ] Retry with backoff (later): withRetry(fn, { tries: 3 })
- [ ] Background jobs (later): enqueue("send-receipt", { orderId })
- [ ] Scheduled jobs in one place (later): one cron list: nightly-report at 2 a.m.
- [ ] Events (later): publish("order.created"), subscribe(...)
- [ ] Incoming webhooks (later): one handler that checks the signature first

## Agent tools & scripts

- [ ] Standard scripts (day one): npm run dev · build · test · lint
- [ ] Dev server on a fixed port (day one): npm run dev → localhost:3000
- [ ] Reset to a clean state (later): npm run db:reset
- [ ] A browser the agent can drive (later): Playwright, to look at the page it built
- [ ] Your app's own tools (later): an MCP server or CLI: search, run, publish

## Checks

- [ ] Type check (day one): npm run typecheck
- [ ] Lint (day one): npm run lint
- [ ] A test runner with one real test (day one): npm test, one test that passes
- [ ] One command for all of it (day one): npm run check
- [ ] A preview link per change (later): a URL you can open before it goes live
- [ ] Click-through tests (later): sign up, buy, cancel, run in a browser

## Errors & logs

- [ ] One logger (day one): log.info / log.error, never bare console.log
- [ ] A friendly error page (day one): one error screen for the whole app
- [ ] Error reporting (later): Sentry or similar, with the user and the page
- [ ] Usage events (later): track("signup_completed")

## Rules for the agent

- [ ] Rules file (day one): AGENTS.md or CLAUDE.md: how to run, test, deploy
- [ ] The list of primitives (day one): PRIMITIVES.md: use these, don't rebuild them
- [ ] Where things go (day one): components/ for UI, lib/ for actions, one line each
- [ ] Skills for repeat jobs (later): a skill for “add a page” or “add an action”
- [ ] A decisions log (later): docs/decisions/: why we picked X over Y

The four moves

Create, combine, delete, expand, for the whole life of the project. “As a new need for a new primitive shows up, is that just an existing primitive with a different shape?” Pick what you're seeing to get the move. The questions to ask are ours. 5:00

What are you seeing?

The move

Create

The capability doesn't exist yet, so the agent works around it.

His example

  • Kody: roles and permissions built first, by their own agent, before community packages6:01

Watch out

Don't let the feature agent build the missing block as a side job. Give it its own task.

Ask your agent · ours

Which capabilities are missing from this project, so that you'd have to write a workaround to finish a typical task? For each one, say where the workaround would end up.
  1. Create: The agent keeps writing its own version of something

    The capability doesn't exist yet, so the agent works around it. His example: Kody: roles and permissions built first, by their own agent, before community packages. Watch out: Don't let the feature agent build the missing block as a side job. Give it its own task.

    Ask: Which capabilities are missing from this project, so that you'd have to write a workaround to finish a typical task? For each one, say where the workaround would end up.

  2. Combine: Two or three things do nearly the same job

    A new need turns out to be an old block with a different shape, or two blocks drifted into one idea. His example: PayPal: three combobox components became one, downshift; Kody: skills and saved apps folded into packages. Watch out: Be ruthless, and ask it every time a new block is proposed: is this an existing one in disguise?

    Ask: Which parts of this project do nearly the same job in different ways? For each group, propose the one piece that could replace them all.

  3. Delete: Nobody uses it, or it's too rigid to bend

    Less surface is the win. Every block is one more thing the agent might call. His example: Instagram: Burbn cut everything except photo sharing; Kody: the built-in email handler removed. Watch out: Deleting a rigid block often means expanding a simpler one to cover the real need.

    Ask: Which features, files or helpers in this project look unused or too narrow? For each, say what would break if we deleted it.

  4. Expand: One block almost covers the new need

    An existing primitive is nearly right and should do a bit more. His example: Kody: packages gained event subscriptions. Watch out: Expand by adding a small, general ability (subscribe to events), not a special case for one feature.

    Ask: Which existing pieces almost cover a need we keep hitting? Propose the smallest general change that would let them cover it.

Before and after: Kody's email

His best example, and one of the few diagrams on his slides. One rigid block gets deleted, an existing one gets a little bigger, and the two meet on an event bus. 11:30

Before · one fat handler

An email arrives
Email handler: runs a few agent turns with every tool, does the task, replies
Want anything else from an email? Change the handler.

After · announce and subscribe

An email arrives
Publishes one event: email.received
Package A: ignores the wrong subject
Package B: reads the body and acts
Package C: whatever you need next

Delete

The built-in email handler goes.

Expand

Packages learn to subscribe to events.

Combine

Email and packages meet on one bus.

“At first you might think, well, Kent, that means that it's a little less helpful and I have to build things myself.” That's inversion of control: more work for whoever builds the package, much more power. And since agents write most of the code, the extra work is cheap. 13:05

Why good primitives work

His three reasons, from the end of the episode. 13:51

0113:51

A smaller action space

Fewer, clearer blocks means fewer decisions for the agent and fewer wrong turns.

0214:05

Snap together, don't improvise

The agent combines pieces you trust instead of writing a fresh script or hacking a one-off screen.

0314:22

Easy to audit

When infra and auth go through known blocks, you can see what the agent touched and check it.

The homework prompt

Said out loud, not typed on screen, so the wording is from the captions. The checklist was on screen. “The agent is the one that's playing in the playground, so you may as well ask the agent.” Then you judge, because you know where the product is going. 14:43

On screen · “Ask your agent:”

  • What primitives exist?
  • What should we create?
  • What should we combine?
  • What should we delete?
  • What should we expand?

Then use your judgment.

Kent's homework · said, close wording

What are the primitives that currently exist in the system, and what should we create or combine or delete or expand among these primitives? What's missing? What looks kind of the same? What needs a little bit more so that it can be more powerful?

FakeNerd fill-in · read-only, with your product plans

Read this project before answering. Don't change any files.

Where this product is going: [one or two sentences about the product and who it's for]
What's coming next: [the next feature or two you plan to build]

1. List the primitives that exist today: the building blocks the code offers for reuse. Group them under: UI & design, API & backend, data, infrastructure, agent tools and scripts, workflows (retries, queues, timers, events), auth & permissions. One line each, with the file it lives in.
2. Create: what's missing, so that you'd have to write a workaround to build [the next feature]?
3. Combine: what looks kind of the same? Name the duplicates and the one piece that could replace them.
4. Delete: what looks unused or too rigid?
5. Expand: what almost covers a need and could do a bit more?
6. Tell me how it feels to work in this project. Where do you have to guess?

End with your top three changes, smallest first, and why.

FakeNerd follow-up · one move at a time

Do only change [number] from your list: [paste it].

Work on a new branch. Don't touch anything outside this change.
When it's done:
- list every place that now uses the new piece,
- add one line about it to [AGENTS.md / CLAUDE.md / PRIMITIVES.md] under "Use these, don't rebuild them",
- run the tests and tell me what you checked.

Write them down

Not in the video. Kent's own Kody repo now keeps a primitives map: 58 primitives in 5 groups, plus 13 rules that must always hold. His later episode on reviewing pull requests uses it (our page on it). A starter for your own project sits on the right; adjust the paths.

Kent's primitives.yaml · excerpt, read Oct 25, 2026

# Kody system primitives map (taxonomy)
# Risk labels used in PR recaps:
#   composes - wires existing primitives without changing them
#   extends  - changes a primitive's behavior, shape, or contract
#   adds     - introduces a new primitive (update this file in the same PR)

groups:
  - id: surfaces
    name: Entry points
  - id: auth
    name: Identity & auth
  - id: assistant
    name: User-facing assistant primitives
  - id: runtime
    name: Execution runtimes
  - id: storage
    name: Storage & infrastructure

primitives:
  - id: rbac
    group: auth
    name: Role-based access control
    summary: Permissions, roles, admin route guards, and admin MCP metadata.
    code:
      - packages/worker/src/identity/permissions
      - packages/worker/universal/permissions

  - id: email
    group: assistant
    name: Email
    summary: Per-user and operator system inboxes on the platform domain.
    code:
      - packages/worker/src/email/

invariants:
  - id: compact-mcp-surface
    summary: Keep public MCP tools small; add capabilities via search/execute.
The full file on GitHub

FakeNerd starter · PRIMITIVES.md

# PRIMITIVES.md
The building blocks of this project. Use these. Don't rebuild them.
If a task needs something that isn't here, stop and ask before inventing it.

## UI & design
- Button, TextField, Card: components/ui/
- Colours and spacing: app/tokens.css (never hardcode a colour)

## API & backend
- sendEmail(to, subject, body): lib/email.ts
- createOrder(), cancelSubscription(id): lib/orders.ts

## Data
- User, Order, LineItem: lib/db/schema.ts

## Infrastructure
- Deploy: npm run deploy (preview first, then promote)
- Secrets: set in the host's dashboard, read through lib/env.ts

## Agent tools and scripts
- npm run seed, npm run check

## Workflows and events
- Events: order.created, email.received (lib/events.ts)
- Retries: withRetry() in lib/retry.ts

## Auth & permissions
- Roles: admin, member (lib/auth/roles.ts)
- Every server action calls requireRole() first

## Rules
- A change that adds or reshapes a block updates this file in the same change.

composes

The change wires existing blocks together. Low risk.

extends

The change reshapes a block. Look closer.

adds

A new block. Update the map in the same change.

Try it, smallest version first

Six steps on a project you already have. You can stop after step 3 and still have done Kent's homework. The starter prompts are in the section above.

  1. 01

    Open a project you already have

    Any coding agent works: Claude Code, Codex, Cursor, or a sandbox like Cloudroom or bb (getbb.app). Commit or save first so nothing is at risk.

  2. 02

    Ask the homework question, read-only

    Paste Kent's question, or our fill-in below. Tell it not to change any files. Five minutes.

  3. 03

    Read the list and judge it

    The agent sees the mess; you know where the product is going. Cross out anything that doesn't fit your plans.

  4. 04

    Pick one move, the smallest

    One create, combine, delete or expand. If it's a missing block, give it its own task or session, the way Kent gave roles their own agent.

  5. 05

    Write the blocks down

    Add a short “use these, don't rebuild them” list to your rules file or a PRIMITIVES.md. Agents can only reuse what they can find.

  6. 06

    Ask again next month

    Or whenever you catch the agent writing a workaround. Kent: “This is a process that you never stop.”

Kent's homework · paste this first

What are the primitives that currently exist in the system, and what should we create or combine or delete or expand among these primitives? What's missing? What looks kind of the same? What needs a little bit more so that it can be more powerful?

Next to the others

Other pages on the same idea, and what each adds.

kent c. dodds: visual recapSameKent's next episode, built on the same primitives map.AddsUses the map to review pull requests: which blocks a change composes, extends or adds.
theo: prompt biggerSameBoth teach MEGA. Both say the old habits waste the agent.AddsTheo changes what you ask for: the whole job, with a check. Kent changes what the agent works inside.
Matt Pocock's skillsSameFewer, deeper pieces with small, clear doors (his “deep modules”).AddsReady-made skills that hunt for those pieces in your code and redesign them.
Compound EngineeringSameImprove the system after the work, so the next task goes better.AddsWrites down lessons after every task. Kent reshapes the building blocks themselves.
System design patternsSameQueues, events and background jobs show up in both.AddsThe classic app-scaling techniques, one by one, for when your app grows.

FakeNerd's take

The homework is the best part

One read-only question, five minutes, any agent. Even if you skip everything else on this page, do that.

Beginners have primitives too

You don't need roles or event buses. Design tokens, one email function and one deploy command already count, and they stop most of the mess.

He doesn't say how the agent finds them

Good blocks only help if the agent knows they exist. A short list in your rules file is the cheapest fix. Kent's own repo now keeps a primitives map for this.

Most examples are his product

Three of the five stories are Kody. The idea stands without it: the PayPal and Instagram stories make the same point.

Attribution

  • Kent C. Dodds, “Your Coding Agent Needs Better Primitives” (Better with Kent, episode 10, Jul 15, 2026). The idea, the seven areas, the four moves, every story and the homework question are Kent's. The area cards and the homework checklist are read off the screen; the “looks like” lines come from his slide deck; quotes come from the captions. Where screen and slides differ (the screen says “Workflows”, the slide “Events / workflows”), the map follows the screen.
  • Disclosure: Kody, the source of three of his five stories, is Kent's own product (free tier, Pro $12 a month). downshift is his open-source library. He also co-teaches MEGA, a paid course, which this video doesn't mention. No sponsor read in the video.
  • He calls Instagram's first app “Bourbon”; it was spelled Burbn. The description also links his “I built my own OpenClaw” video, which this page doesn't use.
  • The primitives.yaml excerpt is from his Kody repo, not from the video, and is marked that way.
  • The six examples, the questions in the map and the picker, the fill-in and follow-up prompts, the PRIMITIVES.md starter, the before-you-build checklist (its three extra areas, every item and example), the step notes in “follow one change”, the glossary and the takes are FakeNerd's. Not sponsored by anyone on this page.
↑↓ move enter openBrowse every card