Skip to content
buttery

v1.0.0

Source on GitHub

Version 1.0.0

Command line

buttery's command line starts an app from a template, adds pages and components to it, checks its layout, and sets buttery up in an app you have.

@butteryui/cli is the buttery command. It starts an app from one of the four templates, adds a page from buttery's patterns or a component of the app's own, runs the layout checks on the running app, and sets buttery up in a React app that doesn't have it yet. When something can't be done, it says how to fix it, and --json gives a machine the same findings as a person.

Start an app

bash

npx create-buttery my-shop --template dashboard

create-buttery runs buttery create with the package manager that started it, so pnpm create buttery my-shop installs with pnpm. It copies the template into a folder named after the app, puts that name in the title, the sidebar and package.json, and installs it:

text

Made my-shop from the dashboard template.

  cd my-shop
  npm run dev

Then check its layout with npx buttery check, and add pages with npx buttery add page <kind>.
TemplateWhat it starts
blankA Vite and React app wired up for buttery, with nothing on the screen yet
dashboardA back office: a sidebar of pages, an overview, a table of orders with a page for each, products, search, settings and a sign-in screen
editorAn app for making one thing at a time: a header bar, a stage and an inspector
marketingA one-page site: a sticky bar, a hero, what a product does and costs, and a footer

Every app comes with buttery's lint configs, Playwright with @butteryui/test and specs of its own, VS Code snippets (bt-page, bt-component, bt-stack and the rest), an AGENTS.md and CLAUDE.md, the make-it-buttery skill, and the MCP server in each common coding agent's config. --desktop adds the Tauri shell, so the app also opens as a desktop window, and --no-install leaves installing to you.

Add a page

bash

npx buttery add page table --name Customers

text

Added src/pages/CustomersPage.tsx: a list of records in a table, with its header and actions, from DataTable.
It's at /customers in src/App.tsx, with an item in the sidebar.
Check it with npx buttery check /customers.

A page starts from the example of its pattern that is a whole page, set in the page grammar: an example that isn't a page yet goes inside an AppPage with a title, and a sign-up or onboarding screen in a section of its own. In an app made from the dashboard template, the page is also wired into src/App.tsx: imported, its path in routes, a case in the page switch and an item in the sidebar, or a screen of its own outside the shell. Anywhere else, it says where to render it. --name names the component, its file, its path and its label; without it, the page keeps its example's name. Each one passes buttery check as it comes.

KindThe page
tableA list of records in a table, with its header and actions, from DataTable
detailOne record: its facts, its actions and what's linked to it, from DetailPage
overviewA dashboard's numbers for a period, from MetricCard
settingsOne group of settings, each in a row, from SettingsPage
settings-indexEvery group of settings, each opening its own page, from SettingsIndex
catalogItems to browse and pick from, by category, from CatalogPage
plansPlans side by side, one recommended, from PlanComparison
search-resultsResults of a search, paged, from SearchResults
emptyA page with nothing in it yet and the way to start, from EmptyState
feature-introA feature someone hasn't turned on, and why to, from FeatureIntro
sign-inSigning in or signing up with a code sent by email or text, no password, from AuthFlow
sign-upCreating an account, from SignUpForm
onboardingA first run that shows the way around, from Onboarding
landingA marketing page in bands, from Page
articleA long read with an aside, from ArticleLayout
faqQuestions and answers, from Faq

buttery add settings, onboarding, marketing-page and article add the same pages by their patterns' names, and buttery add app-shell writes src/AppFrame.tsx, a sidebar and a top bar to render the app's pages in.

Make a component

bash

npx buttery create component OrderCard --purpose "One order, as a card."

text

Made OrderCard:
  src/components/OrderCard/OrderCard.tsx
  src/components/OrderCard/order-card.css
  src/components/OrderCard/OrderCard.examples.tsx
  src/components/OrderCard/preview.html
  src/components/OrderCard/preview.tsx
  e2e/order-card.spec.ts

See it at /src/components/OrderCard/preview.html on the dev server, check it with npx buttery check /src/components/OrderCard/preview.html,
and run its spec with npx playwright test e2e/order-card.spec.ts.

The component is built on buttery's public parts, Slot and variants(), with a ref, its own class and a tone variant to start from, and the purpose as its JSDoc. Its CSS file is named after it in kebab case, so --bt-order-card-* variables at its top may hold raw values the lint config allows nowhere else. The dev server serves its preview page, so buttery check runs on it like any page, and its spec runs expectButtery there.

Check the layout

bash

npx buttery check / /customers

buttery check opens each page in the app's own Playwright and runs the checks from @butteryui/test on it, the ones expectButtery runs: overlap, overflow, text that crowds or wraps, sizes off the scale, small targets, controls out of line, contrast and the rest. A page is a path on the dev server or a whole address. When a page is a path and the app isn't running, it starts the dev server, on the port in package.json's config.port or wherever the server says it's listening, and stops it afterwards. If another app is answering on that port, it stops and says so rather than check the wrong one.

text

Checked / and /customers at 390 and 1280, light and dark, comfortable, in chromium.

buttery found no layout problems.

Each problem comes once, with its elements, its fix and every condition it showed in:

text

Checked /settings at 390 and 1280, light and dark, comfortable, in chromium.

โœ— /settings
  overflow      [data-bt="SettingsSection"]:nth-child(1) > [data-bt-part="section-head"]: content overflows its width by 1466px
                Fix: Give it room, let it shrink (min-width: 0 comes with Stack, Inline and Grid), wrap the text, or truncate it with <Text truncate>.
                In 390x844 light comfortable chromium, 390x844 dark comfortable chromium, 1280x800 light comfortable chromium and 1280x800 dark comfortable chromium.
  overflow      [data-bt="SettingRow"]: content overflows its width by 558px
                Fix: Give it room, let it shrink (min-width: 0 comes with Stack, Inline and Grid), wrap the text, or truncate it with <Text truncate>.
                In 390x844 light comfortable chromium, 390x844 dark comfortable chromium, 1280x800 light comfortable chromium and 1280x800 dark comfortable chromium.

buttery found 2 layout problems.

--json prints a list with each problem once for every condition it showed in, in the format LayoutGuard logs. Its first entry here:

json

{
  "rule": "overflow",
  "a": "[data-bt=\"SettingsSection\"]:nth-child(1) > [data-bt-part=\"section-head\"]",
  "px": 1466,
  "message": "content overflows its width by 1466px",
  "fix": "Give it room, let it shrink (min-width: 0 comes with Stack, Inline and Grid), wrap the text, or truncate it with <Text truncate>.",
  "page": "/settings",
  "viewport": "390x844",
  "theme": "light",
  "density": "comfortable",
  "engine": "chromium"
}

By default it checks at 390 and 1280 wide, light and dark, in comfortable density, in Chromium. --full checks every width from 390 to 1728 in both densities, in Chromium and WebKit, and --engine webkit picks the engine. It needs @playwright/test and @butteryui/test in the app, which the templates have, and Playwright's browsers, from npx playwright install.

Set up an app you have

bash

npx buttery init

init installs buttery's packages with the app's package manager, imports the styles and wraps the app in ButteryProvider at its entry, writes buttery's ESLint and stylelint configs when the app has none, adds lint and check scripts and buttery's VS Code snippets, and gives coding agents what they read: a section in AGENTS.md between <!-- buttery:start --> and <!-- buttery:end -->, the @AGENTS.md import in CLAUDE.md, the skill, and the MCP server in each agent's config, added to any config the app already has. What it can't do for certain, such as adding buttery's rules to an ESLint config of the app's own, it lists with how. Run again, it changes nothing:

text

buttery is already set up here.

buttery doctor checks the setup and says how to fix what isn't right:

text

โœ“ React 19.3.1
โœ“ @butteryui/core, @butteryui/react, @butteryui/test, @butteryui/lint, @butteryui/mcp, @butteryui/cli at 1.0.0
โœ“ src/main.tsx imports buttery's styles, which bring the Inter font
โœ“ ButteryProvider wraps the app
โœ“ No fonts load from the network
โœ“ eslint.config.js uses buttery's rules
โœ“ stylelint.config.mjs uses buttery's rules
โœ“ buttery check can run: @playwright/test and @butteryui/test are installed
โœ“ AGENTS.md and the agents' MCP configs know buttery

buttery is set up here.

It looks at the React version, whether buttery's packages are at one version, the styles at the entry and whether they're imported twice, the provider, fonts loaded from the network, the lint configs, a desktop app's smallest window, what buttery check needs, and the agents' files.

Migrate

buttery migrate runs the codemods a release asks for, from the version the app has installed to the command line's own, or to --to. No release has needed one yet.

Exit codes

A command exits 0 when it did what was asked, 1 when check or doctor found problems, and 2 when it couldn't run, with the reason and its fix on stderr.

  • Installation

    Starting a new app with create-buttery, adding buttery to an app you have with buttery init, working in buttery's repository, and what an app on buttery is made of.

  • Testing

    expectButtery, the Playwright check that fails a page that overlaps, overflows or shifts, at every size you ask for.

  • MCP server

    @butteryui/mcp lets a coding agent look buttery up instead of guessing: components and token values for the version in use, page starters, and checks that say how to fix what they find.

  • Dashboard

    A web app with a sidebar, an overview of the week's numbers, a table of orders with a page for each, products, search, settings with a plan page, and a sign-in screen, made from the App kit.