Thanks for wanting to contribute. This repo welcomes issues, bug reports, and PRs.
- Be respectful. See CODE_OF_CONDUCT.md.
- Security-sensitive reports go through SECURITY.md, not public issues.
- Every change keeps the repo shippable: lint, typecheck, tests, and build pass on
main. - UI changes must follow DESIGN.md (live at https://ui.vllnt.com/DESIGN.md) and the token contract in packages/design/tokens.json. Document intentional deviations in the PR body.
Requirements: Node 22+, pnpm 9+, git.
git clone https://github.com/vllnt/ui.git
cd ui
pnpm install
pnpm devKey scripts (from repo root):
| Script | What |
|---|---|
pnpm dev |
Run registry + Storybook dev servers in parallel via turbo |
pnpm build |
Build every package |
pnpm lint / pnpm lint:fix |
ESLint flat config across the workspace |
pnpm test:once |
Vitest single-run across the workspace |
pnpm -F @vllnt/ui test:visual |
Playwright CT visual snapshots |
pnpm check:circular |
Fail on circular imports |
pnpm doctor |
react-doctor React-health scan |
A react-doctor pre-commit hook
(in .githooks/, enabled automatically on pnpm install) blocks commits that
introduce React errors on staged files; warnings are advisory. Bypass once
with git commit --no-verify. See AGENTS.md → React health for details.
- Never commit to
main— push branches and open PRs. A branch-protection hook blocks direct commits. - Branch naming:
feat/...,fix/...,chore/...,docs/...,ci/.... - Commit messages follow Conventional Commits. The release workflow groups
feat:/fix:/other into the generated notes. - PRs require passing CI (
.github/workflows/ci.yml) before merge.
-
Scaffold a folder under
packages/ui/src/components/{name}/containing:{name}/ {name}.tsx # implementation {name}.test.tsx # Vitest unit tests {name}.visual.tsx # Playwright CT story {name}.mdx # registry docs (optional if auto-generated) index.ts # barrel export -
Follow the existing patterns:
React.forwardRefon every component.cn()fromsrc/lib/utils.tsfor class merging.- Radix primitives for accessible behavior where applicable.
- CVA for variants (
class-variance-authority).
-
Add the export to
packages/ui/src/index.ts. -
Regenerate registry docs:
pnpm -F @vllnt/ui storybook:generate pnpm -F @vllnt/ui storybook:generate-docs
-
Run the full gate locally:
pnpm lint && pnpm test:once && pnpm -F @vllnt/ui test:visual && pnpm build
- TypeScript strict via
@vllnt/typescript. - No
any, noasassertions, no@ts-ignore, noeslint-disable. Fix the issue at the source. - ESLint 9 flat config only — no
.eslintrc*. - No inline
//comments in shipped code. Use TSDoc on exports.
Releases are cut via workflow_dispatch on .github/workflows/publish.yml. Maintainers pick patch / minor / major and the workflow:
- Bumps
packages/ui/package.json. - Generates release notes from commits.
- Pushes an annotated tag
v{x.y.z}back tomain. - Publishes to the public npm registry with OIDC-signed provenance.
- Creates the GitHub release.
Canary builds ship automatically on every push to main.
Use the GitHub issue templates under Issues. Include repro steps, expected vs. actual, and environment details.
Every issue carries a type: Bug, Feature, or Task. The repo's issue templates (bug_report.yml, feature_request.yml, task.yml) set this automatically — please use them.
| Type | When |
|---|---|
Bug |
Something is broken — wrong output, crash, regression, accessibility violation, security issue. |
Feature |
New user-visible capability — new component, new public API, new site surface. |
Task |
Internal work — refactor, infra, docs, CI, sweeps, dependency bumps, version bumps. |
A CI check (.github/workflows/issue-type-enforcer.yml) labels typeless issues needs-triage and posts a reminder. Maintainers triage these manually.