Skip to main content

Getting started

Install through one door: the CLI adds the packages, the stylesheets and the Claude Code plugin.

MACAW is installed through one door. The CLI adds the packages, the stylesheet imports and the Claude Code plugin, so the next session already knows the system.

Install

npx @macaw-ds/cli init

init installs @macaw-ds/ui, @macaw-ds/tokens and @macaw-ds/icons, drops the plugin (skills, hooks, reviewer agent, MCP config) into .claude/, and writes a short CLAUDE.md block.

Stylesheets

init adds these imports to your root CSS for you, right after your Tailwind import, between /* macaw:start */ and /* macaw:end */. It looks in the usual places (src/app/globals.css, app/globals.css, src/index.css, app/app.css and a few more); if it finds none or several, or you pass --no-css, add them yourself in this order. Tailwind v4 reads the theme from theme.css, so only token utilities exist afterwards. MACAW needs Tailwind CSS v4, and init stops on a v3 project.

If your root CSS still has a starter template's :root colours, @theme fonts or body styles (create-next-app ships them), delete them; they override the tokens.

@import 'tailwindcss';
@import '@macaw-ds/tokens/tokens.css';
@import '@macaw-ds/tokens/theme.css';
@import '@macaw-ds/ui/styles.css';

Theme, density and motion

Light and dark, comfortable and compact, and reduced motion are all modes of the token layer, set with data attributes on <html> or on any region. With no data-theme the OS preference applies; with no data-motion the OS reduced-motion setting applies. Component code never branches on any of them.

<html lang="en" data-theme="dark" data-density="compact">
AttributeValuesChanges
data-themelight, darkEvery semantic colour
data-densitycomfortable, compactControl heights, TopBar height, gutters, margins, padding
data-motionreduced, fullDurations collapse to 0 ms and the spinner stops

Frame a page

Products start from the system frame: AppShell with a TopBar and a SideNav, and a PageHeader at the top of every page. See Layout templates.

Fonts

The token font stacks start with Inter and Geist Mono and fall back to system fonts. Load them any way you like; with Next.js:

import { Geist_Mono, Inter } from 'next/font/google';

const inter = Inter({ subsets: ['latin'], variable: '--font-inter' });
const geistMono = Geist_Mono({ subsets: ['latin'], variable: '--font-geist-mono' });

<html className={`${inter.variable} ${geistMono.variable}`}>

Use a component

import { Button, Text } from '@macaw-ds/ui';

export function Summary() {
  return (
    <>
      <Text numeric>$12,480.00</Text>
      <Button>Pay invoice</Button>
    </>
  );
}

CLI commands

npx @macaw-ds/cli add button          # wires the import, prints a starter snippet
npx @macaw-ds/cli add button --eject  # copies the source in; recorded in .macaw/ejected.json
npx @macaw-ds/cli diff                # (0.2) shows what ejected copies are behind

The plugin for Claude Code

init installs it. To add it to an existing Claude Code setup by hand:

claude plugin marketplace add Cristian-pineda/MACAW-Design-System
claude plugin install macaw

See For agents for what the plugin contains.

Tailwind-native option

If you compile your own utilities instead of importing @macaw-ds/ui/styles.css, point Tailwind at the component sources and keep the theme import:

@import 'tailwindcss';
@import '@macaw-ds/tokens/tokens.css';
@import '@macaw-ds/tokens/theme.css';
@source '../node_modules/@macaw-ds/ui/src';

The ESLint config @macaw-ds/eslint-config then rejects anything that is not a token utility: raw hex or px, arbitrary values, Tailwind's default palette, and className on a MACAW component.