AAOA.studio · Case Study · Figma · npm · Design System

Started as a Figma UI Kit.
Now it lives in your codebase.

MooooM is a design system that began in 2023 as a Figma component library, a way to build project pages faster and keep them visually consistent. The times changed. A UI Kit that only lives in Figma leaves developers rebuilding every token by hand. So we added the code side: 6,000+ icons, 38+ components, and 860+ design tokens available as npm packages for React, Vue, and vanilla CSS.

Figma · npm · Vanilla CSS React · Vue · Web Components 2023 – present moooom.design ↗
Scroll
Origin
No external bet, a personal problem. Every new project started the same way: rebuilding a UI kit from scratch. MooooM began as a way to stop doing that. The insight that turned it into a product: if it solved the problem well enough to use on every project, it was worth selling to the designers and developers who had the same problem. The audience was already there, we were already in it.
The pricing experiment
A self-imposed challenge: start at $2 and double the price every week while shipping meaningful new content each time. Early adopters who paid $2 for 40 icons now have 6,000+ icons, 38+ components, and will receive the coded component library at no extra charge. The price has reached $100 and will likely settle around $140. The affiliate program pays 50% commission, affiliates alone have generated $900+ in revenue, keeping the same amount for themselves.
Signal so far
A mild financial success, a strong technical one. The system now underpins every new project, the original problem is solved. The community is active and waiting for the coded components update, which ships soon. The affiliate structure turned buyers into distributors without an ad budget. The personal ROI is already paid, anything commercial from here is upside.
0+
icons across 4 styles
Line · Duo · Sharp · Solid
38+
accessible UI components
WCAG 2.1 AA · ARIA · keyboard nav
0+
design tokens
Colour · type · spacing · radius · effects
5
npm packages
mom · mom-pro · react · vue · web

Ch01

The origin. A Figma Kit for moving faster, building consistent.

MooooM started in 2023 as a Figma component library. The problem it was solving was immediate and practical: when you work across multiple product projects, you spend a disproportionate amount of time rebuilding the same UI primitives. A button here, a badge there, a modal that differs just enough from the last one to break the visual language. The breaking point was specific: rebuilding the same date picker for the third project in a single quarter. The first version of MooooM was a direct answer to that, a shared Figma library that could be referenced across projects, keeping typography, spacing, colour, and component states consistent without requiring every page to invent them from scratch.

The icon library came early. Iconography is one of the most copy-paste-heavy parts of any product interface, and most free icon sets are either stylistically inconsistent or missing half the categories you need. MooooM's icon set was built from the start with four style variants, Line, Duo, Sharp, and Solid, so a product could pick one and apply it consistently across the entire surface, or mix styles deliberately for hierarchy without losing cohesion.

A Figma Kit solves the designer's problem. It does nothing for the developer staring at a token that only exists as a variable in a frame.

The gap became obvious over time. Figma variables map to CSS custom properties. Figma components map to HTML patterns. But the mapping only exists implicitly, a designer specifies color/neutral/900, and someone has to translate that into a hex value, give it a CSS variable name, decide where it lives in the codebase, and repeat that process for every token in the system. The code version of MooooM exists to close that gap. The design tokens, components, and icons that designers use in Figma are the same ones developers install from npm.

Ch02

The system. Icons, tokens, components, each a layer, all connected.

MooooM is structured as three interdependent layers. The icon library is the bottom layer: 6,319 SVG files organised by style and category, with 57 category groups covering every common UI context from system controls to finance, maps, media, gestures, and weather. The token layer sits above it: 860+ design tokens derived from Radix UI colour scales, with 28 colour scales, each with 12 steps and alpha variants, plus typography, spacing, radius, and effect tokens. The component layer is built entirely from those tokens, so changing a token changes every component that uses it.

Line
1,574 icons
Duo
1,587 icons
Sharp
1,584 icons
Solid
1,574 icons

The four styles are not just aesthetic variants. They map to distinct use cases: Line for lightweight informational interfaces, Duo for marketing and feature pages where icons need visual weight without feeling heavy, Sharp for dense data-rich UIs where the rounded corners of Line would feel incongruent, and Solid for filled states, toggle-active indicators, and small sizes where stroke visibility becomes an issue. Sharp was never planned: it started as a one-off fix for a dashboard project that kept fighting Line's rounded caps, and the fix grew into a full 1,584-icon style.

TOKEN CATEGORIES

Colour
28 Radix scales
860+ tokens. 12 steps per scale, plus alpha variants. Dark-first, with light mode override. Generated by build-tokens.js from Radix UI source.
Typography
Inter, 9-step scale
Font family, weights (400–900), sizes (xs → 7xl), line heights, and letter-spacing. Naming follows Tailwind conventions for zero-friction adoption.
xs sm base lg xl
Spacing · Radius · Effects
Full geometric system
Spacing scale (0.5 → 96), border radius (sm 4px → full), shadow levels (sm → xl), and animation tokens for transitions.

LIVE COMPONENTS

From the mom package, same markup as Figma

Active Draft New

COMPONENT CATEGORIES

Form controls Navigation Feedback Overlays Data display Button · Button group Input · Textarea · Select Checkbox · Radio · Toggle Date picker · Slider · File upload Modal · Drawer · Dropdown Command palette Toast · Alert · Tooltip Table · Card · Badge · Avatar Skeleton · Spinner · Progress Tabs · Accordion · Carousel
Component viewer · token palette · icon browser

Ch03

In code. The same system designers use, available as npm packages.

The code side of MooooM ships as five npm packages in a monorepo. mom is the free tier: the full CSS component framework with design tokens, the Line icon set, and the <mom-icon> web component, dark mode by default. mom-pro extends it with light mode, all four icon styles, and licence-gated access. The framework packages, @mom-ui/react, @mom-ui/vue, and @mom-ui/web, wrap the same HTML and CSS patterns in typed component APIs for each ecosystem.

The architecture is CSS-first by design. Every component is BEM-named HTML with CSS custom properties for every visual decision. The React and Vue packages are thin wrappers that render the correct HTML and manage interactive state, they do not own the visual layer. This means a product can use MooooM CSS directly without any JavaScript framework, or use the React/Vue packages and get the same exact pixels either way. The design tokens and component styles are identical whether you reach them through Figma, CSS, or a framework component. The developer staring at a token that only exists as a variable in a frame now runs npm install and has it.

Package What it includes Tier
mom CSS components + design tokens + Line icons + <mom-icon> web component. Dark mode. Free
mom-pro Everything in mom + light mode + all 4 icon styles (Line, Duo, Sharp, Solid). Licence key required. Pro
@mom-ui/react React 18+ typed components. Requires mom or mom-pro for styles. Free
@mom-ui/vue Vue 3+ typed components. Requires mom or mom-pro for styles. Free
@mom-ui/web Framework-agnostic web components. Requires mom or mom-pro for styles. Free
HTML · Vanilla CSS mom package, zero dependencies
<!-- Install: npm install mom -->
<link rel="stylesheet" href="node_modules/mom/dist/mom.css">
<script src="node_modules/mom/dist/mom-icon.js"></script>

<!-- BEM class API, consistent with Figma component naming -->
<button class="mom-btn mom-btn--primary mom-btn--md">
  <span class="mom-btn__icon" aria-hidden="true">
    <mom-icon name="System/shield" variant="line" size="16"></mom-icon>
  </span>
  <span class="mom-btn__label">Save changes</span>
</button>

<!-- Icon web component, same category/name as Figma -->
<mom-icon name="Arrows/arrow-right" variant="duo" size="24"></mom-icon>
TypeScript · React @mom-ui/react, typed component API
// Install: npm install @mom-ui/react mom
import { ButtonRoot, InputWrapper, BadgeRoot } from '@mom-ui/react'
import '@mom-ui/react/css'

function SaveButton() {
  return (
    <ButtonRoot variant="primary" size="md">
      Save changes
    </ButtonRoot>
  )
}

The <mom-icon> web component is the bridge between the icon library and any runtime. It fetches SVG files by category path (System/shield, Arrows/arrow-right), normalises stroke colours to currentColor so the icon inherits CSS color, and caches fetched SVGs in memory so repeated uses of the same icon do not re-request. The base path is configurable for CDN usage.

Ch04

The build. SVGs in, tokens in. Packages out.

The monorepo has no manual token or icon maintenance. Two build scripts generate everything from source. build-tokens.js reads the @radix-ui/colors npm package and outputs a single system/tokens/colors.css with all 28 colour scales, dark default, light override, including both sRGB and P3 variants. Run it once when Radix updates a scale; the output propagates to every component that references those variables. build-icons.js walks src/icons/{Style}/{Category}/*.svg, strips non-essential attributes, and outputs one JSON file per style into icons/data/, which the icon browser and the web component both consume. The system that began as a way to stop rebuilding the same components now rebuilds itself.

JavaScript · Node build-icons.js · SVG → JSON pipeline
// Reads:  src/icons/{Style}/{Category}/*.svg
// Writes: icons/data/{Line,Duo,Sharp,Solid}.json
// Each entry: { name, displayName, category, content }
for (const cat of categories) {
  for (const file of await readdir(catDir)) {
    const raw = await readFile(join(catDir, file), 'utf-8')
    icons.push({
      name:        basename(file, '.svg'),
      displayName: toDisplayName(basename(file, '.svg')),
      category:    cat.name,
      content:     cleanSvg(raw),   // strips fill, normalises viewBox
    })
  }
}
await writeFile(outPath, JSON.stringify(icons))

The component packages are built with Vite in library mode. Each framework package (mom-react, mom-vue, mom-web) exports typed components and a single CSS file from the same source tokens. The build pipeline is one command: npm run build from the monorepo root triggers icon generation, token generation, and all five package builds in sequence.

MooooM's codebase was built with Cursor and Claude Code throughout. Shipping a cross-framework npm monorepo with a working build pipeline, typed component APIs for React and Vue, and a web component icon bridge, with a team this lean, is not a normal outcome. It became possible when AI tooling compressed the implementation loop. What that tooling cannot do: decide what the token naming convention should be, determine which icon styles to ship, figure out why the Figma-to-code parity matters to the people buying the kit, or invent the pricing experiment. Those decisions came from years of frustration with existing tools and a clear picture of the problem worth solving.

npm workspaces monorepo
5 packages under packages/ with shared tsconfig.base.json. Single npm install from root, single npm run build to publish all.
mom · mom-pro · react · vue · web
Zero-dependency core
The mom and mom-pro packages are pure CSS + vanilla JS. No bundler, no framework, no runtime cost. Framework packages are opt-in thin layers.
CSS custom properties · BEM · Web Components
Figma parity
Component names, variant names, and token names match Figma exactly. A designer specifying badge/ghost/teal/sm maps directly to .mom-badge--ghost.mom-badge--teal.mom-badge--sm.
Design → code · No translation layer
Capability
MooooM
Figma-only kit
Design tokens
Figma variables + CSS custom props
Figma variables only
Icon usage in code
Web component + JSON
Manual SVG copy-paste
Light + dark mode
CSS class toggle, localStorage
Figma modes only
Accessibility
WCAG 2.1 AA, ARIA, keyboard nav
Visual spec only
Framework support
React · Vue · Web Components
None
Token source of truth
Radix colors → CSS → Figma
Figma (manual)

Coda

The same system,
everywhere it needs to be.

The original problem is solved. Every new project now starts from a base that already has the tokens, the icons, the component patterns, and the coded equivalents ready. What used to cost days of setup costs nothing. That alone makes MooooM worth it, the revenue is a bonus.

The pricing experiment worked as designed. People who took the $2 bet when there were 40 icons are now sitting on a system worth considerably more, and will receive the coded component library at no extra charge when it ships. The first $2 sale came from our social media pipeline, which mattered far more than the amount.

The affiliate program, 50% commission, turned the early community into a distributed sales team. No ad spend, $900+ generated by people who believed in the product enough to stake their own reputation on it. That structure was a design decision too: the pitch to early adopters had to be a product argument compelling enough that people would put their name behind it.

What changed between 2023 and now is the definition of a design system. In 2023 it meant a Figma file. Now it means a Figma file, five npm packages, a token pipeline, and components that work in React, Vue, and vanilla CSS. MooooM grew to meet the actual surface area of where design decisions live, and it has one more update left before that surface is complete.

View MooooM