React Tailwind Layered Web
Use this skill to keep React + Tailwind apps organized around clear ownership, thin route composition, and one-way imports.
Apply When
Apply when work touches:
- app setup, routing, layouts, or page composition
- React components, Tailwind styling, or UI refactors
- feature-specific UI and behavior
- folder placement, module ownership, or import direction
Skip when the task is backend-only, infra-only, or unrelated to the web UI.
Core Rules
- Keep the top-level router thin.
- Keep route files thin; they should mostly compose shell and feature workspaces.
- Keep domain contracts explicit; do not invent browser-only domain behavior when ownership belongs to shared contracts or the backend.
- Prefer the lowest valid layer; do not promote code upward just because it might be reused later.
- Do not create or grow catch-all folders like
componentsorlibwhen a clearer layer exists.
Layer Map
| Layer | Purpose | Allowed contents | Disallowed contents |
|---|---|---|---|
src/foundations/ |
Visual foundations | design tokens, Tailwind imports, base styles | React components, domain logic |
src/primitives/ |
Generic UI controls | buttons, inputs, cards, form controls | business logic, API calls |
src/patterns/ |
Reusable UI compositions | headers, panels, form sections, list shells | business logic, API calls |
src/features/ |
Domain UI and behavior | product-specific views, hooks, state, feature composition | generic shared UI that belongs lower |
src/pages/ |
Route entry points | page orchestration, route-level assembly | deep feature logic, generic UI libraries |
src/shell/ |
App framing | layout chrome, providers, navigation shell | feature-owned domain behavior |
src/shared/ |
Sidecar shared code | API clients, schemas, helpers, generic utilities | UI-layer imports |
Placement Rules
Use this decision order:
- If it is styles, tokens, or Tailwind/base CSS only, place it in
src/foundations/. - If it is a generic standalone control, place it in
src/primitives/. - If it is a reusable UI composition built from primitives, place it in
src/patterns/. - If it knows about a product domain, workflow, or business state, place it in
src/features/. - If it only wires routes, page assembly, or app framing, place it in
src/pages/orsrc/shell/. - If it is non-UI shared logic, place it in
src/shared/.
When in doubt, keep code in the owning feature first and only extract downward once it is clearly generic.
Import Rules
Keep imports one-way:
foundations -> primitives -> patterns -> features -> pages
foundations -> primitives -> patterns -> features -> shell
shared -> usable by all layers
Enforce these constraints:
foundationsimports from no UI layerprimitivesmay usefoundationsandsharedpatternsmay usefoundations,primitives, andsharedfeaturesmay usepatterns, lower UI layers if the host project already allows it, andsharedpagesandshellcompose feature work; they should not become feature ownerssharedmust never import from UI layers
Follow the host project's existing import style. Do not introduce aliases just for this skill.
React + Tailwind Guidance
- Use function components.
- Prefer Tailwind utilities with
classNameextension points. - Establish a clear visual direction early and preserve it.
- Keep typography consistent:
text-xs: labels, badges, metadata, uppercase markerstext-sm: body copy, helper text, inputs, buttons, small headingstext-base: section and component titlestext-lg: page titles and prominent headingstext-2xl: stat values
Working Sequence
For each requested change:
- Start from the user-facing outcome.
- Identify the owning route, shell, feature, or shared contract.
- Place each new file in the lowest valid layer.
- Extract repeated generic UI downward into
primitivesorpatterns. - Keep domain behavior in
featuresand shared contracts insrc/shared/or the backend/service layer. - Keep pages and routing code thin.
- Add the required source-file header block to every source file you create or edit when the host project requires it.
Done Check
Before finishing:
- New code sits in the correct layer.
- Imports follow the allowed boundaries.
- Router and route files remain thin.
- Domain behavior stays in
featuresor shared/server-owned contracts. - Styling stays consistent with the chosen visual direction.
- Normal UI validation for the host app has been run.