Composition

Build loud. Compose smart.

v0.2.0 introduces a composition system for building loud, token-driven, Angular-first brutalist UIs. Small primitives that lock together like LEGO — each primitive owns one job, and they compose to build anything.

The mental model

Every ng-brutalism UI starts with a surface. Regions inside that surface are sections. Content flows vertically in stacks and horizontally in clusters. Two-column layouts use split. Actions and metadata complete the picture.

Decision guide

Which primitive do I need?
Need a panel?→ nbSurface
Need header / body / footer inside a panel?→ nbSection
Need vertical spacing?→ nbStack
Need horizontal or wrapping items?→ nbCluster
Need two columns or main/aside?→ nbSplit
Need an action?→ nbButton or nbIconButton
Need metadata?→ nbChip or nbBadge
Need emphasis text?→ nbTitle, nbDisplay, or nbText
Need status?→ nbStatusDot, nbBadge, or nbCallout

Rendered example

A complete panel built with composition primitives only — no class soup required.

Launch checklist

v0.2.0

Build a loud release panel using composition primitives instead of class-heavy wrappers.

SurfaceSectionStackCluster
Ready for release

Before / after

The same brutalist card — one written with raw Tailwind classes, one with composition primitives.

Before — class soup

HTML
<div
  class="rounded-2xl border-4 border-black
         bg-yellow-300 p-6
         shadow-[8px_8px_0_#000]"
>
  <div
    class="flex items-center justify-between
           border-b-4 border-black pb-4"
  >
    <h2>Launch card</h2>
    <span>v0.2.0</span>
  </div>

  <div class="py-4">
    <p>Lots of repeated class decisions.</p>
  </div>
</div>

After — composition

Template
<article nbSurface tone="yellow" radius="xl"
         shadow="hard" clip>
  <header nbSection padding="lg" divider="bottom"
          layout="between" align="center">
    <h2 nbTitle>Launch card</h2>
    <span nbChip tone="pink">v0.2.0</span>
  </header>

  <div nbSection padding="lg">
    <p nbText>Same structure, clearer composition.</p>
  </div>
</article>

Less class soup. More composition.

API language

Every primitive in ng-brutalism speaks the same token vocabulary. Learn it once, use it everywhere.

tone

Visual intent / color theme

size

Component scale

radius

Corner shape

shadow

Brutalist offset depth

border

Outline strength

padding

Internal space

gap

Child spacing

align

Cross-axis alignment

justify

Main-axis alignment

collapse

Responsive layout behavior

clip

Keep inner regions inside the outer radius

divider

Border between regions — top, bottom, etc.

Customization

Use public inputs first. Reach for CSS custom properties when presets are not enough. Keep overrides local so they only affect the element and its descendants.

CSS variable override
<!-- Step 1: use public inputs first -->
<div nbSurface tone="cream" radius="xl" shadow="hard">
  Token-driven surface
</div>

<!-- Step 2: CSS variables for fine-grained control -->
<div
  nbSurface
  tone="cream"
  style="--nb-surface-bg: #faf6f0"
>
  Custom surface background
</div>

<!-- Overrides are local — only this element is affected -->
<div
  nbSurface
  style="--nb-shadow-offset-x: 12px; --nb-shadow-offset-y: 12px"
>
  Custom shadow offset
</div>
Click 'Show more' to view additional details.

Explore the system