react-domain-architecture
Skill0 starsChanged 16 days agoMITView on GitHub
Use when creating, moving, or naming files in a plain React app (Vite or similar SPA, no Next.js/Remix) organized by business domain, with a modules/ folder and a core/ folder outside it. Best for mid to large apps and teams. Covers module layout, public APIs, import boundaries, config, tests, and growth.
- Reads credentials
In this repository7 other files it gives its agents.
The file
Show its rules and text
We split this skill into the rules it gives an agent
25 rules. About 0 are common, 11 are distinctive, and 14 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈11
Distinctive · estimate
This author's own choices. Worth a look.
14
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Read src/modules/ and src/core/ before creating files.
- Distinctive: line 40
Read references/full-tree.md when you need the expanded tree, including module internals.
- Distinctive: line 55
Start flat: put files in the module root.
- Distinctive: line 66
Do not repeat the module name in file names inside the module, unless the name is the domain entity.
- Distinctive: line 78
Never import another module's internal files.
- Very specific: line 79
Prefer composing two modules in a page in core/app over coupling them.
- Very specific: line 92
Put tests next to the file: invoice-table.tsx, invoice-table.test.tsx.
- Very specific: line 93
Put test setup and shared helpers in core/test/.
- Distinctive: line 94
Test a module through its public API when possible.
- Very specific: line 95
Put end-to-end tests in e2e/ at the repo root, grouped by module name.
- Distinctive: line 99
Read references/growth-stages.md when deciding whether to restructure.
- Very specific: line 103
Use react-layered-architecture or a flat src/.
- Very specific: line 107
Use core/ plus 2 to 6 flat modules.
- Distinctive: line 117
Read references/anti-patterns.md when reviewing a layout or before moving files.
- Very specific: line 119
Do not import modules/ from core/.
- Very specific: line 120
Do not deep-import modules/x/components/Y.
- Very specific: line 121
Do not create a shared/ or common/ folder inside or beside modules/.
- Very specific: line 122
Do not put domain logic in core/.
- Distinctive: line 123
Do not create a module per page.
- Very specific: line 124
Do not re-export everything from index.ts.
- Very specific: line 125
Do not share state between modules through globals.
- Distinctive: line 126
Do not write query keys inline.
- Very specific: line 127
Do not copy query data into useState or core/store.
- Distinctive: line 128
Do not use deep relative imports.
- Distinctive: line 129
Do not use PascalCase or camelCase file names, or rename a file only to change its case.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
React domain architecture
Plain React single-page app, grouped by business domain. Server data is handled with TanStack Query (or a similar query client). Each domain is a module. Shared infrastructure lives in core/, outside modules/.
Target version
Written for React 19 with TypeScript and Vite on 2026-10-29. Applies to any client-only React setup. Not for meta-frameworks (Next.js, Remix). For small apps, use react-layered-architecture instead.
Follow the repo first
Read src/modules/ and src/core/ before creating files. If the project already has conventions (module names, casing, import alias, lint boundaries), use them. Check tsconfig.json for aliases and the lint config for import rules.
Default directory layout
src/
main.tsx # entry: mounts <App />
app.tsx # composes core providers and the router
core/ # infrastructure with no business logic
app/ # providers, router, route composition
api/ # HTTP client, QueryClient setup, error types
config/ # env parsing and constants
ui/ # design-system primitives (Button, Modal)
hooks/ # generic hooks (useDebounce)
lib/ # pure helpers
store/ # app-wide client state (auth session, theme)
types/ # shared generic types
styles/ # global CSS and tokens
test/ # test setup and shared helpers
modules/ # one folder per business domain
<module>/Read references/full-tree.md when you need the expanded tree, including module internals.
Module layout
modules/invoices/
index.ts # public API: the only file others may import
routes.tsx # route objects for this module
pages/ # route-level components
components/ # module-private UI
hooks/ # module-private hooks
queries/ # query and mutation hooks, query keys, request functions
types/ # module types- Start flat: put files in the module root. Add subfolders once the module passes about 8 files.
- Export from
index.tsonly what other modules orcore/appneed.
Naming conventions
- Modules: kebab-case domain nouns, such as
invoicesoruser-profile. - Files and folders: kebab-case for everything, such as
invoice-table.tsxanduse-invoices.ts. Do not mix casing. - Components: the export is PascalCase and the file is its kebab-case form:
InvoiceTableininvoice-table.tsx. - Exports: use named exports. Avoid default exports.
- Hooks:
use-thing.tsfor UI logic. Data hooks go in queries, nothooks/. Queries:invoice.queries.ts, exportinginvoiceKeys,useInvoices,useCreateInvoice. Types:invoice.types.ts. - Routes: pages are
invoice-list-page.tsx. URL paths are kebab-case. - Do not repeat the module name in file names inside the module, unless the name is the domain entity.
- Imports: use
@/core/...and@/modules/.... Never use../../...
Dependency direction
main -> core/app -> modules -> corecorenever imports frommodules.- A module imports
corefreely. - A module imports another module only through that module's
index.ts. - Never import another module's internal files.
- Prefer composing two modules in a page in
core/appover coupling them. Avoid circular module imports. - Move code to
coreonly when 3+ modules need it and it has no domain meaning.
Where things live
- Config:
core/config/. Readimport.meta.envonly incore/config/env.ts. - Env vars: prefix with
VITE_. List every var in.env.exampleat the repo root. - Shared types: generic ones in
core/types/. Domain types in the owning module'stypes/. - Query client: create it in
core/api/query-client.ts. Mount the provider incore/app. - Global state: app-wide state in
core/store/. Domain state in the owning module. Keep UI state local.
Tests
- Put tests next to the file:
invoice-table.tsx,invoice-table.test.tsx. - Put test setup and shared helpers in
core/test/. - Test a module through its public API when possible.
- Put end-to-end tests in
e2e/at the repo root, grouped by module name.
Structure at three sizes
Read references/growth-stages.md when deciding whether to restructure.
Prototype
Use react-layered-architecture or a flat src/. Do not start with modules for a single screen.
Mid-size
Use core/ plus 2 to 6 flat modules.
Signal to move up: a module passes about 20 files, two teams edit one module, or modules import each other's internals.
Large
Give big modules subfolders. Enforce boundaries with lint rules. Split a module into submodules when it holds two domains.
Signal to extract packages: a second app needs core/.
Anti-patterns
Read references/anti-patterns.md when reviewing a layout or before moving files.
- Do not import
modules/fromcore/. - Do not deep-import
modules/x/components/Y. Import frommodules/x. - Do not create a
shared/orcommon/folder inside or besidemodules/. - Do not put domain logic in
core/. - Do not create a module per page. A module is a domain.
- Do not re-export everything from
index.ts. - Do not share state between modules through globals. Pass it through props or
core/store. - Do not write query keys inline. Use the module's key factory.
- Do not copy query data into
useStateorcore/store. - Do not use deep relative imports. Use aliases.
- Do not use PascalCase or camelCase file names, or rename a file only to change its case.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

