Designing a codebase AI agents can extend with tested components
A codebase that an AI coding agent can extend — not just blindly regenerate — sounds obvious. But it's rare. Most repos, even highly-rated open source templates, force an agent to guess at ad hoc patterns, reinvent prop shapes, or regenerate the same routing scaffolds again and again. The result: wasted context, broken UI, and a dev loop that never gets shorter. We engineered the OTF kits for a different lifecycle — one where the agent recognizes real, tested components and builds on top of them, not against them. That's unlocked by more than "nice code". It's process, tooling, and a relentless focus on agent-readability.
A kit that lets an agent build the right thing the first time — without breakage, drift, or hallucinated conventions — is a force multiplier. It means you get predictable output, faster automation, and fewer rewrites. The thesis: designing for humans and for AIs aren't the same thing, and most templates miss what AI needs.
Here's how OTF kits make agent extension possible — and how to architect for this mode.
Engineering for extension, not regeneration
The core pain is easy to name: AI agents facing an unfamiliar codebase default to guesswork. They regenerate components from scratch, miss internal APIs, or entangle logic with presentation. Even strong, context-heavy models do this. A dev loop meant to accelerate instead burns cycles re-learning the structure or breaking the same UI layer each run.
What actually breaks:
- Agents ignore base components (
<Button>,<Card>) and write bespoke UI by hand. - Data-access or API shapes get reinvented — slight mismatches, unnecessary expansion.
- Routing and navigation are re-implemented, often inconsistent with the rest of the app.
- Consuming applications drift: mobile and web diverge, so extensions land broken in one or both.
The path off this treadmill isn't "nicer code". It's explicit conventions, per-agent instructions, and focused context. Predictability wins over novelty every time. If you're choosing a starting point, prefer one that's already agent-readable over one you have to teach the agent from scratch.
What makes a codebase agent-readable
For a coding agent to extend — not guess — it needs:
- Surface area: actual, tested exports for every intended extension point. If your
<Card>isn't exported, it's invisible. - Predictable patterns: routing, storage, theme, and data access that always look the same. Novelty equals breakage.
- In-band documentation: signals in the repo for what to use and how (
ai/prompts/,CLAUDE.md,.cursorrules,AGENTS.md). - Demo code: real, production-grade surfaces — not just a toy demo page, but live usage for every UI primitive.
- Component parity: same interface across platforms, so there's no guesswork about "web-only" variants.
- Consistent file structure: every agent knows where to look for components, routes, and prompts or config.
Anything else is wasted agent context. The tighter your context budget, the more critical this prep becomes.
11 production screens. Login and database wired.
The SaaS Dashboard Kit includes login, a database, and a working dashboard. Live demo at saas.otf-kit.dev.
Why every OTF kit ships CLAUDE.md, .cursorrules, and ai/prompts/
The mechanism is standard across the industry: persistent instruction files loaded into the agent's context at session start. Claude Code documents exactly this pattern — CLAUDE.md files give the agent persistent project context, complemented by scoped rule files — and Cursor's rules system provides the same thing via version-controlled project rules plus AGENTS.md as a portable alternative. The specific agent configs in OTF kits aren't afterthoughts. They're part of the tested, production code. Here's what actually ships:
-
CLAUDE.md: Model-specific summary and example extension tasks. For Claude-family agents, a few direct examples are enough for the agent to map class names, routing, and merge styles instead of rewriting:# CLAUDE.md ## Extend the dashboard: add a settings page 1. Add `src/routes/settings.tsx` that renders `<SettingsForm />`. 2. Use `<Button>` from `@otfdashkit/ui`, pass `variant="primary"`. 3. Wire up API calls via the shared `src/api/settings.ts`. -
.cursorrules: Targeted heuristics for Cursor's AI (and similar agents). This file tells the agent what to use, what NOT to touch, and which conventions matter:[components] use = [ "@otfdashkit/ui/Button", "@otfdashkit/ui/Card", "@otfdashkit/ui/Table" ] block = [ "legacy-components/*" ] [conventions] routing = "Hono, file-based" theming = "OTF design tokens" -
ai/prompts/: Tested, short prompts for adding flows, dashboards, and auth logic the OTF way — not generic "add a page" filler:# ai/prompts/add-plan-modal.md Add a billing plan modal to the main dashboard. Use: - `<Dialog>` from `@otfdashkit/ui` - Stripe price IDs from the `env/` folder - Submit form via `@otfdashkit/api/billing.ts` Render in `src/routes/dashboard.tsx`
Agents load these on startup. So do senior devs. The friction drops — the agent never hallucinates a base component or rewrites the modal layer. For the Cursor side of this setup, our Cursor rules guide shows how project rules keep conventions enforced across sessions.
Convention beats cleverness every time
A clean, boring convention is more agent-friendly than "genius" abstractions. Here's how that lands in OTF kits:
-
Component names match props, everywhere. A
<Button>from@otfdashkit/uion web is the same as<Button>from/ui-nativeon Expo — same prop contract, same look. No guessing. This is the same-component architecture applied as an agent strategy. -
Design tokens are shared, not duplicated. Theme changes in one spot. Compiles to CSS vars for web, native tokens for iOS and Android.
-
File structure is fixed. Every kit:
/components /Button.tsx /Card.tsx ... /ai/prompts/ /routes/ CLAUDE.md .cursorrulesThe agent never burns context-window budget re-deriving unrelated file names or searching for "real" components.
The delta: on a generic template, the agent spends most of its early calls just mapping to the right base component. On OTF, it lands there immediately.
When agents guess versus when agents extend
The difference is night and day. Here's a real example:
-
Guessing (broken): Agent is told "add a Confirm Delete modal". Base code exports a
<Modal>, but with an unusual prop shape. No docs for this. Agent hallucinates usage:// What you get: <Modal open={isOpen} onClose={() => setOpen(false)}> <h1>Confirm Delete</h1> ... </Modal>Doesn't match the actual API. Modal doesn't close correctly; styles are off; code is a dead end.
-
Extending (works): Agent has a prompt for modals:
ai/prompts/add-confirm-modal.mdAnd the actual Modal is exported in
/components/Modal.tsxwith this signature:// In Modal.tsx import { Modal, ModalProps } from "@otfdashkit/ui" // Usage <Modal isOpen={open} onOpenChange={setOpen} variant="danger"> <h1>Confirm Delete</h1> ... </Modal>The agent recognizes how to wire it, extends the code in place, and the modal works — first run.
This is the distinction between a codebase that trains the agent to guess (and fail) versus a codebase that guides the agent to extend (and succeed).
How to make your repo agent-friendly
You don't need to ship a product kit to get this right. A few concrete moves raise agent readability overnight:
-
Export every reusable component.
If it can be reused, make it a named export. Otherwise, an agent will rewrite it inline.
// components/Button.tsx export { Button } from "@otfdashkit/ui" -
Write a top-level CLAUDE.md or AGENTS.md.
Summarize extension patterns, not just purposes. It's a targeting doc, not marketing. Both filenames are recognized conventions — Claude Code reads
CLAUDE.mdas persistent context, andAGENTS.mdworks as the portable equivalent across tools.# CLAUDE.md Use `<Button>` from `/components/Button.tsx` everywhere. Use `<Modal>`, not `<Dialog>` for popups. -
Provide agent-specific prompt files.
Short, result-oriented tasks — not long-winded context. One prompt per pattern.
/ai/prompts/add-profile-dropdown.md /ai/prompts/add-signup-flow.md -
Document conventions in-band.
Routing? State? Theming? Spell it out at the top of each new subfolder.
# routes/README.md All route files must export `Page`. Async data loads with `fetchData()`, not `useEffect`.
The cumulative effect: the agent no longer guesses. It extends what's there, in ways that stick.
The delta: maintainability, automation, trust
Here's what this enables for a real engineering team:
- Faster merges. AI PRs rarely break the base case, so reviewing takes minutes, not hours.
- No more "regenerate-from-scratch" loops. Agents add to, not overwrite, the base code.
- Automate boring flows. You can tell an agent to scaffold an entire billing flow and get a correct, on-brand UI — because the agent recognizes existing modals, tables, and API handlers.
- Reasonable context windows. Even models with modest context budgets stay on track — because prompts are tight and context surfaces are clear.
- Cross-platform consistency. Mobile and web stay in sync; the agent never has to infer dual interfaces.
Every OTF kit gets this by default, enforced by a checklist before code ships. And since you own the kit code, there's no lock-in down the line.
Why "build on real components" is the foundation, not the garnish
Shipping agent-ready code isn't a bonus — it's the enabler for real-world adoption. As agents get better, codebases that teach the AI to extend (not guess) will outpace those that don't. Kits that document their primitives and cue agents with real prompts are the only ones that don't decay under pressure.
OTF's angle is simple: instead of fighting the tool churn, build a foundation that every agent, current and future, can extend. That's why a kit's prompts, conventions, and structure matter as much as — maybe more than — its surface code.
The lesson: design for extension, not just for you. Agents are teammates now. Make your codebase agent-readable, and you'll ship faster, with fewer breaks, on every stack.
Start from a kit that's already built this way — browse the OTF kits.
Sources
- Claude Code, "How Claude remembers your project" (CLAUDE.md mechanism) — https://code.claude.com/docs/en/memory
- Cursor, "Rules" documentation (project rules, AGENTS.md) — https://cursor.com/docs/rules
Ship the product, not the setup.
- 11 production screens — auth, team, analytics, and settings
- Login and a real database are wired in
- AI configs pre-tuned so your agent extends instead of regenerates
Ship your first screen tonight — free starter in your inbox
The quickstart, the SDK repo and the live kit demos, on this screen and in your inbox.
No spam. Unsubscribe any time.