Skip to content

Adding a Component

Hamroqulovv edited this page Oct 8, 2026 · 2 revisions

Adding a Component

Framebits is curated: the core team adds components through pull requests. There is no uploading, marketplace, or moderation queue.

1. Scaffold (never create folders by hand)

pnpm new-component <slug> --category=<category> [--title="..."] [--description="..."] [--type=component|lib|hook]
Argument Rules
<slug> kebab-case, 2–64 chars, unique across components, libs, and hooks.
--category Required for components: text-animations, backgrounds, cursors, buttons, scroll, 3d, layout, utilities.
--type component (default) | lib | hook.
--title / --description Title up to 120 chars; description 10–200 chars (replace the placeholder).

This creates <slug>.tsx, demo.tsx, and meta.json (status: "draft", today's date) from an SSR-safe, reduced-motion-aware template — and refuses to overwrite an existing folder.

2. Write the source

// meta.json — validated by MetaSchema (unknown keys rejected)
{
  "slug": "aurora-text",
  "title": "Aurora Text",
  "type": "component",
  "category": "text-animations",
  "tags": ["gradient", "text"],
  "description": "Animated aurora gradient text.",
  "dependencies": { "motion": "^14.0.0" },  // allowlist only
  "registryDependencies": ["cn"],           // must exist, no cycles
  "difficulty": "easy",                     // easy | medium | hard
  "performance": "light",                   // light | medium | heavy
  "status": "published",                    // draft | published | deprecated
  "addedAt": "2026-10-04"
}

Source rules:

  • SSR-safe — no window/document at module scope or during render.
  • Reduced motion — honor it (useReducedMotion from motion/react, prefers-reduced-motion media, or CSS equivalent).
  • Allowlisted deps only — motion, framer-motion, gsap, three, ogl, clsx, tailwind-merge, class-variance-authority, lucide-react (+ React peer deps). Anything else fails the build.
  • Clean imports — registry siblings only via @/lib/*, @/hooks/*, @/components/ui/*; no relative escapes; every external import declared.

3. Preview, lock, validate

pnpm preview:install        # once per machine (Playwright Chromium)
pnpm generate:previews      # renders demos → commit hash-keyed WebP in registry/previews/
pnpm build:registry --write-lock   # new slugs start at 1.0.0; changes bump patch
pnpm build:registry --check # CI gate: validates everything, writes nothing

4. Open the PR

  • Scaffold came from pnpm new-component; description/tags finalized
  • Preview WebP committed; --check passes
  • pnpm lint, pnpm typecheck, pnpm test green
  • A reviewer has read the full source of every new/changed file (the security scan is a mistake-guard, not a boundary)

After merge, deploys publish it and npx @framebits/cli add <slug> just works.

Never delete a component — set status: "deprecated". Never edit registry/components/** by hand outside this flow.

Full guide: CONTRIBUTING.md in the repo.

Clone this wiki locally