Skip to main content
A design module is a regular Ooneex module whose <kebab>.yml declares type: "design". It carries your design system — React components, hooks, icons, fonts, styles, and front-end utilities — and is shared across applications. Unlike a normal module, a design module is not registered into AppModule or SharedModule; nothing imports it as a runtime feature. Its src/ is not scaffolded from a generator either — it comes from the upstream skeleton-design repository, so the layout below is fixed and canonical.

Layout

A design module lives under modules/<kebab-name>/. It keeps the base module files but drops the runtime <Pascal>Module.ts, and its src/ is organized by asset kind:
modules/<name>/        # <kebab>.yml declares type: "design"
  package.json         # @module/<kebab>
  tsconfig.json
  <kebab>.yml          # type: "design"
  src/
    components/        # React (.tsx) UI — one folder per component
    hooks/             # Reusable React hooks
    icons/             # SVG icons in fill/ + outline/ variants
    fonts/             # Bundled web fonts (Space Grotesk) + @font-face CSS
    styles/            # Global stylesheets
    utils/             # Front-end helpers

Module-level files

These live at the module root, the same as any module — see Module structure for the shared conventions.
FileWhat it is
<kebab>.ymlModule manifest. Declares type: "design", which marks the module as a design system rather than a runtime feature.
package.jsonNames the package @module/<kebab> so other modules can depend on it.
tsconfig.jsonTypeScript configuration for the module.
Unlike a normal module, there is no <Pascal>Module.ts (and no matching spec). A design module has no runtime entry class to register — the scaffolded module file is removed because the src/ content is provided by skeleton-design, not generated locally.

The src/ folders

Each folder under src/ holds one kind of asset. Stay within these conventions when adding to a design module.
FolderWhat it holdsConventions
components/Reusable React (.tsx) UI — roughly 50 components such as accordion, avatar, badge, button, card, dialog, form, input, select, table, tabs, tooltip. One folder per component, grouping its variants.Compose these primitives rather than writing ad-hoc markup or duplicating their internals.
hooks/Shared presentation-layer React hooks — useClickOutside, useMobile, useControlledState, useAutoHeight.Keep them generic (state, DOM measurement, events). Domain and data-fetching logic belongs in services, not here.
icons/SVG icons in fill/ and outline/ variants, grouped by category and size (sm, md, lg).Choose the right variant and size. Add new icons to the matching category folder — never inline SVG into components.
fonts/Bundled web fonts (Space Grotesk) with their @font-face CSS.No external CDNs. Add new font files here together with their CSS.
styles/Global stylesheets — app.css, brand.css, shape.css, status.css, typography.css — for app-wide tokens, themes, and base styling.Prefer shared styles plus component-scoped classes over one-off CSS.
utils/Front-end helpers — cn (class-name merge) and staleChunk.Small, pure presentation helpers only. No backend or business logic.

The component-variant pattern

A component folder groups a primitive with its variants. The button/ folder, for example, holds the base Button.tsx alongside variants like ButtonSave.tsx:
src/components/button/
  Button.tsx
  ButtonSave.tsx

When you need a specialized version of a component, add a sibling variant in the same folder and build it on the base primitive. This keeps every flavor of a control in one place and avoids re-implementing shared behavior.

Next steps