All articles
claudereacttypescript

How to Create a .claude Folder for a Frontend SPA

A practical blueprint for structuring Claude project memory, skills, agents, rules, commands, hooks, and templates for a React + TypeScript + Vite single-page app.

Kazi Efazul Karim
Kazi Efazul Karim
•11 min read
How to Create a .claude Folder for a Frontend SPA

A good .claude folder turns Claude from a general coding assistant into a project-aware teammate.

Instead of explaining your architecture, testing rules, styling preferences, and review checklist in every chat, you encode them once. Claude can then read the right instructions before it edits files, delegates work, or runs checks.

This guide shows how I would structure a .claude folder for a modern React + TypeScript + Vite single-page application. I am using React here because it is the most common frontend SPA stack, but the same pattern adapts cleanly to Vue, Angular, Svelte, Solid, or any other client-heavy application.

The goal#

The .claude folder should answer seven questions:

  1. What stack does this app use?
  2. Where does each kind of code belong?
  3. What patterns should Claude follow before coding?
  4. Which specialized agents can Claude delegate to?
  5. What rules are non-negotiable?
  6. What commands should Claude run for validation?
  7. What hooks and templates keep work consistent?

A useful structure looks like this:

txt
1.claude/
2  CLAUDE.md
3  skills/
4    react-components/SKILL.md
5    react-hooks/SKILL.md
6    react-router-setup/SKILL.md
7    tailwind-styling/SKILL.md
8    zod-validation/SKILL.md
9    react-testing/SKILL.md
10    vite-config/SKILL.md
11  agents/
12    component-builder.md
13    page-builder.md
14    hook-builder.md
15    e2e-tester.md
16    accessibility-auditor.md
17  rules/
18    component-rules.md
19    state-management.md
20    api-integration.md
21    accessibility.md
22    performance.md
23    type-safety.md
24  commands/
25    add-component.md
26    add-page.md
27    add-hook.md
28    test.md
29    test-e2e.md
30    lint.md
31    type-check.md
32    build.md
33    review.md
34    a11y-audit.md
35  hooks/
36    pre-tool-use-secret-guard.js
37    post-tool-use-lint.js
38    post-tool-use-typecheck.js
39    session-start-context.js
40    stop-test-smoke.js
41  templates/
42    component.md
43    story.md
44    pr-description.md
45    issue.md
46    adr.md
47  settings.json
48

The point is not to create bureaucracy. The point is to reduce repeated decisions.

Step 1: Write CLAUDE.md, the project constitution#

CLAUDE.md is the first file I would create. It should describe the stack, the folder layout, and the mental model of the app.

md
1# Frontend SPA — Claude Project Rules
2
3## Stack
4
5- Framework: React 19, TypeScript 5.5, Vite 6
6- State: Zustand for global UI state, React Query for server state
7- Routing: React Router 7
8- Styling: Tailwind CSS 4, shadcn/ui components
9- Forms: React Hook Form + Zod validation
10- Testing: Vitest + React Testing Library + Playwright
11- Linting: ESLint + Prettier
12- Type checking: tsc --noEmit
13- Package manager: pnpm
14
15## Architecture
16
17src/
18  components/    → Reusable UI components
19  features/      → Feature modules
20  hooks/         → Shared custom hooks
21  lib/           → Utilities, API client, constants
22  pages/         → Route-level components
23  stores/        → Zustand stores
24  types/         → Shared TypeScript types
25

Then make the architecture concrete:

txt
1src/features/auth/
2  components/
3    login-form.tsx
4    register-form.tsx
5  hooks/
6    use-auth.ts
7    use-login.ts
8  services/
9    auth-api.ts
10  types.ts
11

This teaches Claude where to place code. Without this, it may scatter components into random folders, create duplicate API clients, or put feature-specific hooks into global locations.

Step 2: Add skills for repeatable frontend decisions#

Skills are the files Claude reads before doing a particular kind of work. Think of them as focused playbooks.

SkillPurpose
react-components/SKILL.mdComponent patterns, props interfaces, composition, memoization
react-hooks/SKILL.mdCustom hooks, React Query usage, Zustand selectors, cleanup rules
react-router-setup/SKILL.mdRoute config, nested routes, lazy loading, route guards
tailwind-styling/SKILL.mdUtility-first patterns, responsive design, dark mode, cva variants
zod-validation/SKILL.mdForm schemas, API response parsing, runtime validation
react-testing/SKILL.mdVitest, React Testing Library, mocking, Playwright E2E
vite-config/SKILL.mdVite config, env vars, aliases, build optimization

A component skill might include rules like:

md
1# React Component Skill
2
3Before building a component:
4
5- Check whether a reusable component already exists.
6- Define a named props interface.
7- Keep rendering declarative.
8- Prefer composition over boolean-heavy APIs.
9- Use `memo` only when the component is expensive or receives stable props.
10- Add a test for behavior, not implementation details.
11

A hook skill might say:

md
1# React Hook Skill
2
3When creating hooks:
4
5- Prefix with `use`.
6- Keep server state in React Query.
7- Keep global UI state in Zustand.
8- Avoid returning unstable objects unless memoized.
9- Clean up subscriptions, timers, and event listeners.
10- Test state transitions and cleanup behavior.
11

This prevents Claude from solving the same design question differently every time.

Step 3: Define agents for delegated work#

Agents describe specialized roles Claude can hand work to when a task is large enough to split.

AgentJob
component-builder.mdBuilds React components with types, tests, and stories
page-builder.mdCreates route pages with data fetching, loading states, and error boundaries
hook-builder.mdCreates custom hooks with cleanup and memoization
e2e-tester.mdWrites and runs Playwright end-to-end tests
accessibility-auditor.mdChecks semantic HTML, ARIA, keyboard flows, and contrast

A component-builder.md file can be very direct:

md
1# Component Builder Agent
2
3You build production-ready React components.
4
5For every component:
6
71. Confirm where it belongs: `components/` or `features/<feature>/components/`.
82. Create a typed props interface.
93. Use existing shadcn/ui primitives when possible.
104. Support loading, disabled, and error states when relevant.
115. Add Vitest + React Testing Library coverage.
126. Add a Storybook story if Storybook is configured.
137. Report changed files and validation commands.
14

The best agent instructions are not philosophical. They should tell the agent exactly what done means.

Step 4: Write rules Claude must never violate#

Rules are where you put project constraints that should apply across many tasks.

Rule fileContent
component-rules.mdProps interface required, no inline styles, memo only for expensive renders
state-management.mdServer state → React Query, UI state → Zustand, form state → React Hook Form
api-integration.mdAll API calls through lib/api.ts, consistent errors, loading skeletons
accessibility.mdSemantic HTML, ARIA labels, keyboard navigation, color contrast
performance.mdRoute-level code splitting, lazy loading, no barrel imports in hot paths
type-safety.mdNo any, typed API responses, Zod runtime validation

For example, state-management.md could say:

md
1# State Management Rules
2
3- Server state belongs in React Query.
4- Global UI state belongs in Zustand.
5- Form state belongs in React Hook Form.
6- Do not prop drill past three levels.
7- Prefer selectors when reading Zustand stores.
8- Do not duplicate React Query data in Zustand.
9

That last rule matters. A common SPA mistake is copying API data into a global store, which creates stale data and confusing invalidation paths.

Step 5: Create commands for common workflows#

Commands are shortcuts for repeatable tasks. They give Claude a predictable checklist when you say things like “add a component” or “review this diff.”

CommandPurpose
/add-component <name>Create component, types, test, and story
/add-page <route>Create page, route config, and data fetching
/add-hook <name>Create custom hook and test
/testRun Vitest unit tests
/test:e2eRun Playwright E2E tests
/lintRun ESLint and Prettier checks
/type-checkRun tsc --noEmit
/buildRun pnpm build and inspect errors
/reviewReview the diff against main
/a11y-auditRun an accessibility review

An /add-component command might include:

md
1# /add-component <name>
2
31. Read `skills/react-components/SKILL.md`.
42. Check for existing similar components.
53. Decide whether this is shared or feature-specific.
64. Create the component file.
75. Create or update tests.
86. Create a story if Storybook exists.
97. Run lint, type-check, and targeted tests.
108. Summarize files changed and trade-offs.
11

This is especially useful when multiple engineers use the same repository. Everyone gets the same AI-assisted workflow.

Step 6: Add hooks for automated guardrails#

Hooks are where your workflow becomes safer. They run automatically around tool use or session boundaries.

HookTriggerWhat it does
pre-tool-use-secret-guard.jsWrite/EditBlocks accidental API keys, tokens, and secrets
post-tool-use-lint.jsEdit .tsx or .tsRuns ESLint on the edited file
post-tool-use-typecheck.jsEdit .tsRuns tsc --noEmit after TypeScript changes
session-start-context.jsSession startShows framework version, route count, component count, build status
stop-test-smoke.jsSession endRuns Vitest on touched test files

The secret guard is the first hook I would add. Frontend projects often expose environment variables, API URLs, analytics IDs, and third-party SDK keys. A guardrail that blocks .env edits or suspicious token patterns can prevent painful mistakes.

Step 7: Add templates for consistent output#

Templates keep generated work boring in the best way.

TemplatePurpose
component.mdComponent file structure: props, hook logic, render, export
story.mdStorybook story format
pr-description.mdPR summary with screenshots, tests, and accessibility notes
issue.mdBug or feature issue format
adr.mdArchitecture decision record format

For a frontend SPA, the PR template should ask for things backend templates usually do not:

md
1# PR Description
2
3## Summary
4
5- What changed?
6- Which route or component is affected?
7
8## Screenshots
9
10- Desktop:
11- Mobile:
12- Dark mode, if applicable:
13
14## Accessibility
15
16- Keyboard navigation checked?
17- Screen reader labels checked?
18- Color contrast checked?
19
20## Validation
21
22- Unit tests:
23- E2E tests:
24- Lint:
25- Type-check:
26- Build:
27

Screenshots and accessibility notes are not optional decoration for UI work. They are part of the acceptance criteria.

Step 8: Lock down settings.json#

settings.json should allow the commands Claude needs while blocking destructive or risky ones.

json
1{
2  "permissions": {
3    "allow": [
4      "Bash(pnpm *)",
5      "Bash(npx vite *)",
6      "Bash(npx playwright *)",
7      "Bash(npx vitest *)",
8      "Bash(npx eslint *)",
9      "Bash(npx tsc *)",
10      "Bash(npx prettier *)",
11      "Bash(curl http://localhost:5173*)"
12    ],
13    "deny": [
14      "Bash(rm -rf*)",
15      "Bash(git push --force*)",
16      "Edit(.env)",
17      "Write(.env)"
18    ],
19    "ask": [
20      "Bash(pnpm add *)",
21      "Bash(pnpm remove *)",
22      "Bash(npx playwright install*)"
23    ]
24  }
25}
26

For most frontend apps, Claude should be able to run tests, type checks, builds, and local browser checks without asking. Dependency changes and browser binary installation should usually require approval because they affect the environment more broadly.

Step 9: Configure MCP servers for frontend work#

MCP servers make Claude more capable when it needs external tools or project context.

ServerPurpose
playwrightBrowser testing, screenshots, visual checks
context7React, Tailwind, shadcn/ui, and library documentation lookup
githubPull request and issue management
figmaOptional design-to-code extraction

For frontend projects, Playwright is the most valuable one. Claude can inspect the real page, verify interactions, catch layout regressions, and capture screenshots for PRs.

A practical workflow example#

Imagine you ask Claude:

Add a settings page where users can update their profile name and timezone.

With the .claude folder in place, the workflow becomes predictable:

  1. Read CLAUDE.md for architecture.
  2. Read react-router-setup/SKILL.md for route placement.
  3. Read zod-validation/SKILL.md for form validation.
  4. Read state-management.md to avoid misusing Zustand.
  5. Create src/pages/settings.tsx or the project’s configured route equivalent.
  6. Add a form using React Hook Form and Zod.
  7. Use React Query for the profile update mutation.
  8. Add loading, error, and success states.
  9. Add unit tests and possibly Playwright coverage.
  10. Run lint, type-check, tests, and build.
  11. Produce a PR summary with screenshots and accessibility notes.

The assistant does not need to guess the workflow. The repository tells it what good work looks like.

What changes for Vue, Angular, or Svelte?#

The structure stays the same. Only the names and contents of the skills change.

For Vue, replace React-specific skills with:

  • vue-components/SKILL.md
  • pinia-state/SKILL.md
  • vue-router-setup/SKILL.md
  • vue-testing/SKILL.md

For Angular, replace them with:

  • angular-components/SKILL.md
  • angular-services/SKILL.md
  • angular-routing/SKILL.md
  • rxjs-patterns/SKILL.md

For Svelte, use:

  • svelte-components/SKILL.md
  • sveltekit-routing/SKILL.md, if applicable
  • svelte-stores/SKILL.md
  • svelte-testing/SKILL.md

The underlying idea is framework-independent: document the architecture, encode repeatable workflows, and automate validation.

Final checklist#

If I were adding this to a real frontend SPA, I would start with this minimum viable .claude setup:

  • CLAUDE.md with stack, architecture, package manager, and validation commands.
  • Three skills: components, hooks, and testing.
  • Three rules: state management, API integration, and type safety.
  • Five commands: add component, add page, test, type-check, build.
  • Two hooks: secret guard and targeted lint/type-check.
  • One PR template that requires screenshots and accessibility notes.

You can always add more later. The best .claude folder is not the biggest one; it is the one that makes Claude consistently produce code that matches your team’s standards.

Share this article

Found this helpful? Share it with your team or engineering network.