AGENTS.md · heroui-inc/heroui
AGENTS.md from heroui-inc/heroui: 377 lines covering Repository Overview, Commands, Behavioral tests (@heroui/react), Git Commit Convention and more.
Template by heroui-inc
Chalk Labs
Need help deploying AGENTS.md · heroui-inc/heroui?
Chalk Labs sets up agents like this inside real teams: connected to your tools, tested on your data, with a human in the loop where it matters.
Install
Works with Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code. Read the repository before you give any tool access to your data.
curl -fsSL https://raw.githubusercontent.com/heroui-inc/heroui/v3/AGENTS.md -o AGENTS.md
Read it and adapt it to your project before use.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: prompt-engineering
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
What's in it
An AGENTS.md file: instructions coding agents (Codex, Cursor, Copilot, Gemini CLI and others) read before working in a repo.
- For
- Codex, Cursor, GitHub Copilot, Gemini CLI, OpenCode, Claude Code
- Length
- 377 lines
- File
AGENTS.md
Sections
- Repository Overview
- Commands
- Behavioral tests (@heroui/react)
- Git Commit Convention
- Component Architecture
- Documentation and External References
- Current Components
- Non-obvious Gotchas
- Cursor Cloud Specific
First lines (shown under the repo's Apache-2.0 license)
# AGENTS.md
Instructions for AI agents working with the HeroUI v3 repository.
## Repository Overview
HeroUI v3 is a modern React UI library built with **Tailwind CSS v4**, organized as a **pnpm monorepo** managed by **Turborepo**. Components are built on top of [React Aria Components](https://react-spectrum.adobe.com/react-aria/) and follow a compound component pattern similar to Radix UI.
### Tech Stack
| Technology | Version | Purpose |
|---|---|---|
| Node.js | 22+ | Runtime |
| pnpm | 10.26.2 | Package manager (via corepack) |
| React | 19+ | UI framework |
| Tailwind CSS | 4.x | Styling |
| TypeScript | 5.x | Type safety |
| Turborepo | 2.x | Build orchestration |
| Storybook | Latest | Component development |
| Vitest | 4.x | Testing |
| React Aria Components | Latest | Accessibility primitives |
| tailwind-variants | Latest | Variant-based styling (includes twMerge) |
Use the workspace manifests and lockfile as the source of truth for exact dependency versions.
### Monorepo Structure
```
/
├── apps/
│ └── docs/ # Documentation site (Next.js + Fumadocs)
├── packages/
│ ├── react/ # Main UI library (@heroui/react)
│ │ ├── src/components/ # All components
│ │ ├── src/utils/ # Shared utilities
│ │ └── scripts/ # Build & codegen scripts
│ ├── styles/ # CSS styles & variants (@heroui/styles)
│ │ ├── components/ # Per-component .css files (flat, e.g. button.css)
│ │ ├── themes/ # Theme variables
│ │ └── src/components/ # Per-component .styles.ts (tailwind-variants)
│ ├── standard/ # Shared ESLint, Prettier, TS configs
│ ├── storybook/ # Storybook configuration
│ └── testing/ # Shared test harness (@heroui/testing)
├── turbo.json
└── pnpm-workspace.yaml
```
## Commands
| Action | Command |
|---|---|
| Install dependencies | `pnpm i --hoist` |
| Build libraries (styles + React) | `pnpm build` |
| Build React and its dependencies | `pnpm build:react` |
| Build docs | `pnpm build:docs` |
| Build Storybook | `pnpm build:storybook` |
| Dev (Storybook, port 6006) | `pnpm dev` |
| Dev (Docs site, port 3000) | `pnpm dev:docs` |
| Lint | `pnpm lint` |
| Typecheck | `pnpm typecheck` |
| Test all (jsdom + browser) | `pnpm test` |
| Test one file (filter) | `pnpm --filter @heroui/react exec vitest run button` |
| Test with coverage | `pnpm test:coverage` (jsdom floors only — not “done”) |
| Test changed files (local) | `pnpm --filter @heroui/react test:changed` (jsdom only; not a gate) |
| Check formatting | `pnpm run format` |
| Fix formatting | `pnpm run format:fix` |
| Bump version | `pnpm version:bump` |
| Scaffold a new component | `cd packages/react && pnpm add:component ComponentName` |
## Behavioral tests (`@heroui/react`)
- Suites live in `packages/react/tests/components/<name>/`:
- `*.test.tsx` — jsdom (~90% of contracts)
- `*.ssr.test.tsx` — Client SSR smoke via `ssrSmoke()` (not RSC)
- `*.browser.test.tsx` — Playwright (overlays + high-risk portals; not every component)
- optional `fixtures.tsx` — shared JSX across layers
- Import harness from `@heroui/testing/helpers` (`render`, `setupUser`, `runAllTimers`, `ssrSmoke`, `User`). Browser suites: `render` from `@heroui/testing/browser` (wraps `vitest-browser-react`; owned by `@heroui/testing`). Prefer `@/` for sources. Pattern testers: `const user = new User(...); user.createTester(...)` — not a top-level export.
- Query: `getByRole` / label / text first; `data-testid` when needed; avoid class-primary queries.
- Assert: roles/names, HeroUI `data-*` hooks, callbacks, focus, light BEM + documented `data-slot` on compound parts — not colors, full class lists, or RAC internals.
- Fake timers: per-suite only; wire `advanceTimers` into `setupUser` + `User`; use `runAllTimers()`.
- Pattern testers for groups / overlays / collections; skip for Button / Checkbox / Switch / TextField.
- Naming: `describe("Component")`; nested concern; `it` as `supports…` / `calls…` / `exposes…` / `renders…`. SSR: `"Component SSR"`; browser: `"Component (browser)"`.
- Intentional skips (no dedicated suite required): internals (`rac`, `icons`), non-exported helpers (`color-input-group`, `date-input-group`), in-progress `calendar-year-picker`, parent-covered parts (`list-box-item`, `menu-item`, `menu-section`, `list-box-section`), Toast SSR (client portal only — covered by jsdom + browser). Public `input-group` has its own suite. SSR and browser are risk-based, not universal.
- Browser setup (once locally): `pnpm --filter @heroui/testing exec playwright install chromium` before `pnpm test`. PR QA installs Chromium with `pnpm --filter @heroui/testing exec playwright install --with-deps chromium`, then runs `pnpm test:browser` + `pnpm test:coverage`. Release CI installs Chromium and runs `pnpm test`.
- Commands: `pnpm test` (jsdom + browser, needs Chromium); filter with `pnpm --filter @heroui/react exec vitest run <name>`.
- Coverage (`pnpm test:coverage`): jsdom only; `src/components/**` minus barrels. Thresholds are **CI floors** (statements/lines can pass with thin smoke). Green coverage ≠ sufficient depth — still require role/callback/focus (and browser for high-risk portals). Browser suites contribute **nothing** to the coverage number, so a component can be well covered by Playwright and still read as a gap in the report.
- Floors are a **ratchet**: they sit ~1pt under the current measured run. Raise them when coverage improves; never lower them to make a red build pass.
- `test:changed`: local jsdom-only shortcut (`vitest related --changed`). Does **not** run browser suites; never use it as the merge gate — use `pnpm test` / CI.
### When a component needs an SSR or browser suite
SSR and browser suites are risk-based. Add one only when a criterion below applies, and skip it deliberately otherwise.
Add a `*.ssr.test.tsx` when the component renders on the server path: it is exported for use outside `"use client"` boundaries, reads `document`/`window` during render, generates ids, or has previously hydrated inconsistently.
Add a `*.browser.test.tsx` when correctness depends on something jsdom does not implement:
| Trigger | Why jsdom is not enough | Example |
|---|---|---|
| Real layout / measurement | `offsetWidth`, `offsetHeight`, and scroll sizes are always `0` | Tabs overflow chevrons, `scroll-shadow` |
| Pointer capture / drag | `setPointerCapture` and pointer event sequencing are not simulated | Drawer swipe-to-dismiss, `color-area` |
| Portals with focus containment | Focus trap and dismiss ordering differ from a real browser | Modal, popover, toast |
| Actual paint or transitions | `transitionend` and animation timing do not fire | Drawer snap-back |
If a coverage gap traces to one of those rows, write the browser test — do **not** contort a jsdom test with mocked geometry just to move the coverage number.
## Git Commit Convention
All commits must follow [Conventional Commits](https://www.conventionalcommits.org/) and are validated by Husky + commitlint. Pre-commit also runs `lint-staged`.
```
<type>(<scope>): <message>
```
**Allowed types:** `feat`, `feature`, `fix`, `refactor`, `style`, `docs`, `build`, `test`, `ci`, `chore`, `revert`
Examples:
```
feat(components): add select component
fix(button): resolve disabled state not applying
docs: update installation guide
```
## Component Architecture
### File Structure
Each component lives in `packages/react/src/components/<component-name>/`:
```
component-name/
├── component-name.tsx # Component implementation (uses React Aria)
├── component-name.stories.tsx # Storybook stories
└── index.ts # Barrel exports
```
Styling lives in `@heroui/styles`, split across two locations:
| Path | Contents |
|---|---|
| `packages/styles/src/components/<component-name>/<component-name>.styles.ts` | The `tv()` map from variant props to BEM class names |
| `packages/styles/components/<component-name>.css` | The BEM class definitions (flat directory, one file per component) |
Note that `.styles.ts` files do **not** live alongside the component in `packages/react`.
### Creating a New Component
Always use the scaffold script:
```bash
cd packages/react
pnpm add:component ComponentName
```
The scaffold is a starting point and still emits legacy patterns. Before using the generated component:
1. Move `<component-name>.styles.ts` to `packages/styles/src/components/<component-name>/`, replace utility-based variants with BEM class mappings, and use the existing `componentNameVariants` / `ComponentNameVariants` naming convention.
2. Add that directory's `index.ts` and export it from `packages/styles/src/components/index.ts`.
3. Create `packages/styles/components/<component-name>.css` and import it in `packages/styles/components/index.css`. Import shared primitives before components that override them.Signals
- Stars
- 31,009
- Forks
- 2,239
- Open issues
- 20
- Last commit (this folder)
- Oct 16, 2026 (15 days ago)
- Last release
- Sep 17, 2026 (1 month ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- Apache-2.0
- Repository
- github.com/heroui-inc/heroui
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from heroui-inc
Done for you
Rather not set it up yourself?
Chalk Labs scopes, builds and runs agents for your team: the task audit, the eval harness, the integrations and the weekly ops report. Fixed scope, priced before we start.
See how we build AI agents →Read the case studies
Chalk Labs is a two-founder AI and growth studio. We build AI agents, CRMs and MVPs for Web3 and AI companies, and have shipped 50+ product and token launches.
- launches shipped
- 50+
- launches shipped
- media placements
- 500+
- media placements
- founders on every account
- 2
- founders on every account
Press we've placed: Forbes · CoinDesk · Decrypt · Cointelegraph · The Block
Rahil Jain, Co-founder, Chalk Labs. Ex-Goldman Sachs engineer. You talk to the person who builds it.
Get AGENTS.md · heroui-inc/heroui running in your business
Tell us what you want to automate. A founder replies within one working day with a plan, not a pitch deck.
Cite this page
AGENTS.md · heroui-inc/heroui. Agent Mart. https://agentmart.dev/templates/heroui-inc-heroui-agents-md (last updated 2026-10-24)