Use when creating, naming, or placing a file or folder in libs/*, or when modifying or adding a file to an existing component (even when the barrel isn't touched) — component vs utility naming, the one-responsibility-per-file layout, when a folder needs an `index.ts` barrel (public API only), and the required set of files a component needs per lib. Load this before scaffolding or restructuring a component so the layout matches the codebase.
Scanned 9/12/2026
Install to Claude Code
npx -y skills add LedgerHQ/lumen --skill component-anatomy --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Component Anatomy?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/ledgerhq-component-anatomy)More formats (shields.io, HTML) on the badges page.
---
name: component-anatomy
description: >-
Use when creating, naming, or placing a file or folder in libs/*, or when
modifying or adding a file to an existing component (even when the barrel isn't
touched) — component vs utility naming, the one-responsibility-per-file layout,
when a folder needs an `index.ts` barrel (public API only), and the required
set of files a component needs per lib. Load this before scaffolding or
restructuring a component so the layout matches the codebase.
paths: libs/*/src/lib/Components/**/*.tsx, libs/**/index.ts
---
# Component & file anatomy
Naming and layout conventions for everything under `libs/*`. Each responsibility
gets its own file. Barrels (`index.ts`) exist to expose a public API and to
re-export several modules from one entry — not on every folder. Which files a
component *needs* depends on the lib — see the table below and the `Libraries`
map in `AGENTS.md`.
## Naming
- **Components** live in a **PascalCase** folder, one file per responsibility.
- **Utilities & hooks** live in a **camelCase** folder, split by responsibility.
- Everything that is not a component is camelCase.
## One responsibility per file
Split implementation, types, tests, stories, docs and Code Connect into separate
files rather than one large module. This keeps diffs small and lets each skill
(`component-styling`, `component-testing`, `component-stories`, `component-mdx`,
`code-connect`) attach to the file it owns.
## Barrel & re-export
A barrel is an `index.ts` that `export *` / `export type *` a folder's **public
API**. Use one when consumers should import the folder, not a specific file:
- **Package / layer barrels** (`Components/index.ts`, `core/index.ts`) — the
published surface.
- **Component folders** (`Button/`, `TextInput/`, `BaseInput/`) — several files
(impl, types, sub-parts); the barrel is the import target. Import from that
barrel, never from `.../Button/Button`.
- **A new public component** must also be re-exported from its parent
`Components` barrel so it ships from the package root.
Do **not** add a barrel for every folder. Skip `index.ts` when the folder is an
internal helper with a single implementation file (plus tests). Import the file
directly (`useMyHook/useMyHook` is the pattern;
`useMyHook/index.ts` is the anti-pattern to avoid repeating). A
one-file folder does not need a barrel just to re-export that file.
## Component folder layout
```
ComponentName/
├── ComponentName.tsx # implementation
├── types.ts # prop types with JSDoc
├── ComponentName.test.tsx # tests
├── ComponentName.stories.tsx # Storybook stories
├── ComponentName.mdx # Storybook docs
├── ComponentName.figma.tsx # Figma Code Connect
└── index.ts # barrel exposing the public API
```
## Utility / hook folder layout
```
useControllableState/ # public util — barrel so consumers import the folder
├── useControllableState.ts
├── useControllableState.test.ts
└── index.ts
useBaseInputValue/ # internal helper, one impl file — no barrel
├── useBaseInputValue.ts
└── useBaseInputValue.test.ts
```
## Required files per lib
Not every lib ships the full set. A component addition is complete when it has
the files marked required for its lib — do not add (or flag as missing) files a
lib does not use.
| Lib | impl `.tsx` | `types.ts` | `.test.tsx` | stories | `.mdx` | `.figma.tsx` |
| --- | --- | --- | --- | --- | --- | --- |
| `ui-react` | required | required | required | co-located `.stories.tsx` | required | if in Figma |
| `ui-rnative` | required | required | required | co-located `.stories.tsx` (id prefix `rnative-*`) | required | if in Figma |
| `design-core` | n/a (tokens, no components) | — | — | — | — | — |
| `utils-shared` | camelCase util files | co-located or inline | required | — | — | — |
**Charts** live at `Components/visualization/` inside `ui-react` and
`ui-rnative`, exposed only at the `/visualization` subpath. They follow their
lib's row above, with two exceptions: some web stories sit in `__stories__/`
rather than co-located, and there is no `.figma.tsx` or `.mdx` coverage on the
React Native side.
Notes:
- **Stories naming** — `Base` (not `Default`/`Primary`), `{Property}Showcase`,
`With{Feature}`; see `component-stories`. In `ui-rnative` the `Base` render is
usually explicit (`render: (args) => <Component {...args} />`).
- **Docs** — the two-tab Overview / Implementation structure lives in
`component-mdx`.
- **Disabled state** — any component with a `disabled` state must consume the
shared disabled context; see `disabled-context`.
## Review checks
Rules verifiable from a diff. Everything above is authoring guidance.
| Check | Applies to | Detect | Skip |
| --- | --- | --- | --- |
| Component folder/file not PascalCase, or utility not camelCase | all libs | folder/file casing vs kind | — |
| Missing `index.ts` on a public component / package / layer folder | all libs | new public component folder with no barrel | internal helper folder (single impl + tests) |
| Barrel on a single-file internal folder | all libs | new `index.ts` that only re-exports one sibling file | public component folders; folders that re-export several modules |
| Import from a deep path instead of a public component barrel | all libs | `from '.../Button/Button'` when `Button/index.ts` exists | internal helpers that have no barrel |
| New component not re-exported from the parent `Components` barrel | `ui-react`, `ui-rnative` | parent `index.ts` unchanged | — |
| More than one responsibility in a file (impl + types + stories in one file) | all libs | stories/types/tests inlined in the impl file | — |
| Required file missing for the lib (see table) | per lib | absent `.test.tsx` / `.mdx` / `.figma.tsx` where required | files a lib does not use (e.g. `.figma.tsx` under `Components/visualization/`) |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!