Skip to content
Back to skills

Component Anatomy

ASecurity

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.

  • 23 stars
  • 0 votes
  • 0 copies
  • 5 views
  • Added September 12, 2026
developmentreacttestingapi

Works with

  • api

Security analysis

A100/100

Scanned September 12, 2026

npx -y skills add LedgerHQ/lumen --skill component-anatomy --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Component Anatomy?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Component Anatomy
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/ledgerhq-component-anatomy/badge)](https://www.skillsdirectory.com/skills/ledgerhq-component-anatomy)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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/`) |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.