structure-a-shared-ui-lib
Skill1 starsChanged 5 months agoMITView on GitHub
Use when building or organizing an internal shared UI / design-system library that multiple apps depend on — src layout, folder-per-component with version coexistence, the createStore/query/Utils wrappers it re-exports, versioned generated design tokens, subpath build & exports, Storybook + visual regression. React/TS reference, framework-flexible.
In this repository40 other files it gives its agents.
- authoring-project-skillsSkill
- background-jobs-and-cachingSkill
- code-conventionsSkill
- containerize-and-ship-a-serviceSkill
- database-migrationsSkill
- design-an-error-modelSkill
- git-flowSkill
- handle-files-frontendSkill
- import-data-from-csvSkill
- integrate-external-servicesSkill
- integrate-identity-providersSkill
- integrate-internal-servicesSkill
- keep-service-memory-leanSkill
- operate-ecs-services-safelySkill
- prevent-secret-and-pii-leaksSkill
- release-safetySkill
- render-transactional-emailsSkill
- rules-backendSkill
- rules-code-styleSkill
- rules-debuggingSkill
- rules-gitSkill
- rules-infraSkill
- rules-pr-reviewSkill
- rules-shippingSkill
- rules-workflowSkill
- schedule-effective-dated-changesSkill
- secure-a-frontend-appSkill
- security-auditSkill
- send-slackSkill
- serve-realtime-with-websocketsSkill
- structure-a-backend-serviceSkill
- structure-a-frontend-appSkill
- structure-a-shared-backend-libSkill
- tdd-http-firstSkill
- use-feature-flagsSkill
- write-cross-cutting-codeSkill
- write-frontend-codeSkill
- write-frontend-testsSkill
- write-service-codeSkill
- write-unit-testsSkill
The file
We split this skill into the rules it gives an agent
1 rule. About 0 are common, 0 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈0
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 64
Utilsnamespace (pure, no React): default export { DateUtil, CurrencyUtil, StringUtil, CommonUtil, FileUtil, CsvUtil, ...
≈ “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
Structure a shared UI library
A design-system package (placeholder @org/web-ui) that multiple apps depend on for components,
hooks, utils, the data/state primitives, and theme tokens. Examples are React/TS over a base
component library (e.g. Ant Design); each rule is principle → ▸ Example → ▸ Other stacks.
Apps that consume this lib follow structure-a-frontend-app / write-frontend-code.
Core principle
The lib is the single source of truth for UI + shared primitives — apps import from it, never
re-implement. It ships subpath entry points (/store, /queries, /utils, /theme/<v>, …) so
apps pull only what they need, and it lets old and new versions of a component coexist so a
redesign never forces a big-bang migration.
1. src/ layout (built to lib/)
▸ Example:
src/
├── components/ # folder-per-component (the bulk) — see §2
├── store/ # Zustand wrapper consumed as @org/web-ui/store (createStore + query helpers)
├── queries/ # React Query wrapper: useQuery / useMutationData / useInfiniteDataQuery / provider
├── hooks/ # shared React hooks + index barrel
├── utils/ # pure *.util.ts (date/currency/string/array/csv/...) + co-located *.test.ts
├── theme/ # versioned design tokens: core, v1, v1_1, v7 — see §4
├── icons/ charts/ # icon set, chart wrappers
├── hoc/ providers/ # higher-order components, context providers
├── models/ types/ enums/ constants/ # shared TS contracts
├── services/ # shared API clients used across apps
├── stories/ # Storybook
└── index.ts # main barrelSource lives in src/; a build step compiles it to lib/ (what apps import). ▸ Other stacks: one
package, organized by capability, built to a dist/ consumers import.
2. Component organization
- Folder-per-component, flat (no atomic-design atoms/molecules layering). Each folder:
components/Button2/ ├── Button.tsx # forwardRef, typed props ├── Button.less # BEM-scoped classes (e.g. ui-button-v2__primary--small) └── index.ts # barrel: export { Button, ButtonProps } - Every component's props extend a shared base for test/observability hooks — e.g. a
CustomAttributePropscarryingdata-test-id+ privacy/analytics data-attributes — plusAriaAttributes. - Version coexistence for redesigns. A breaking restyle ships as a NEW component beside the old
(
Button→Button2→Button3); apps migrate per-usage during a deprecation grace period instead of all at once. Mark the old one deprecated; delete it once no app imports it. ▸ Other stacks: folder-per-component + a versioned name (or major-version export path) for breaking redesigns.
3. Shared runtime wrappers (the lib owns these; apps consume them)
The lib wraps the state/data libraries ONCE so every app uses the same configured primitive:
createStore(Zustand wrapper):createStore<Store>(stateCreator, { storeName, enabledDevTools? })→[useBoundStore, selector]. Devtools dev-only; persist middleware optional. Apps build feature stores on this (seewrite-frontend-code§3).- Query wrapper (React Query):
useQuery(key, fn, options?),useMutationData,useInfiniteDataQuery, and theQueryClientProviderwith the org's default config. Normalizes quirks (e.g. aselectreturningundefined→ original data). Utilsnamespace (pure, no React): default export{ DateUtil, CurrencyUtil, StringUtil, CommonUtil, FileUtil, CsvUtil, ... };CommonUtilre-exports the lodash functions the org uses so apps import them from one place. Each util is unit-tested in the lib. ▸ Other stacks: the shared lib centralizes the data/state/util choices; apps don't import the raw libraries.
4. Design tokens — versioned, generated, not hand-edited
- Tokens are versioned folders (
theme/v1,v1_1,v7,core); a new visual language is a new version, exported separately, so existing apps don't break. - Generated from a source-of-truth JSON, not hand-written:
Pipeline: Figma → a tokens transform (Tokens Studio / Style Dictionary) → JSON → JS + CSS (atheme/v1_1/ ├── tokens.json # SOURCE (color ramps, spacing, radius, typography, shadows) ├── _variables.js # AUTO-GENERATED token getters (colorNeutral50, spacingSmall, ...) ├── _variables.css # AUTO-GENERATED CSS custom properties └── index.ts # getColorPalettes('Neutral'), getSpacings(), getRadiuses(), getSemanticTokens()tokens:buildscript). Edittokens.json(or Figma) and regenerate — never edit_variables.*. - Apps consume via the token getters + the theme/Tailwind preset (see
write-frontend-code§7); they never hard-code hex. ▸ Other stacks: tokens JSON → generated CSS vars / platform files — same "design source → generated, versioned" idea.
5. Public API — subpath entry points
- The build emits many small entry points to
lib/so apps import only what they use:@org/web-ui(components + main),/store,/queries,/utils,/hooks,/theme/<version>,/charts,/models,/constants,/enums,/services.import { Button, Modal } from '@org/web-ui'; import { useQuery } from '@org/web-ui/queries'; import Utils from '@org/web-ui/utils'; import { createStore } from '@org/web-ui/store'; import { theme } from '@org/web-ui/theme/v1_1'; - Built as UMD + emitted
.d.ts(works via ESM, CommonJS, and a global script). ▸ Other stacks: a packageexportsmap / multiple entry points so consumers tree-shake to what they need.
6. Storybook + tests
- Storybook is the dev surface + living docs:
src/**/*.stories.tsxauto-discovered; visual-regression (e.g. Chromatic) gates UI changes. - Pure utils are unit-tested (Jest + Testing Library, co-located
*.test.ts); components are exercised through Storybook + visual regression rather than heavy render unit tests.
7. Versioning & consumption
- Semver the package. Components version by coexistence (§2); theme versions are separate entry points (§4) — both let apps adopt incrementally.
- Apps consume the built lib via the package registry, OR vendored at a pinned branch/tag (e.g. a
meta gitcheckout into the app'slibs/), so every app runs a known version. Bump deliberately. ▸ Other stacks: publish to your registry or pin a submodule/vendored copy; one shared version per app.
Verification
src/is split by capability (components, store, queries, hooks, utils, theme, icons, …); source insrc/, shipped fromlib/.- Components are folder-per-component (
<Name>.tsx+ styles +index.ts), props extend the shared base, and a redesigned component coexists under a new name rather than mutating the old. - The lib exposes state/query/utils primitives via subpaths; apps import those, not the raw libs.
- Theme tokens live in versioned folders, generated from a source JSON (the
_variables.*are not hand-edited). - Storybook stories exist for components; pure utils have unit tests.
Related
structure-a-frontend-app/write-frontend-code— the apps that consume this library.code-conventions— general code style.
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.

