Contribution guidelines for the project.
This guide explains how to get started, the project structure, and the conventions to follow so your contributions fit in.
Note: This project uses pnpm as the package manager; you must have pnpm installed globally to run commands and tests locally.
git checkout -b feature/YourFeatureName).pnpm install to set up all required packages.Open an issue describing what you expected, what actually happened, steps to reproduce, and any helpful screenshots or code.
Every suggestion matters. Describe the context, what should change, and include examples or references if available.
A good component has a clear purpose, performs well, is easy to use, is well documented, and feels considered in both design and animation quality.
Use kebab-case for all folder and file names: fluid-distortion, magnetic-button-demo, etc.
Here’s where each type of file lives:
src/registry/base holds the main components for export.src/registry/demos holds demo components.src/registry/demos/index.ts exports the demo components.src/content holds documentation.(src/registry)
├── base
│ └── your-component
│ └── your-component.tsx # Your new component
├── demos
│ ├── your-component-demo
│ │ └── your-component-demo.tsx # Your new demo component
│ └── index.ts # Exports the demo components
(src/content)
├── en
│ ├── components
│ │ ├── _dir.yml
│ │ ├── your-component
│ │ │ └── your-component.mdx # Your new component documentationEach component should have a single responsibility and live in a single file to keep it self-contained and easy to copy.
If some logic could be reused or has its own responsibility, extract it into a helper, hook, or sub-component.
const CONSTANTS = {...} as const
const hookExample = () => {...}
function utilFunction() {...}
type ComponentExample = {...}
type ComponentExampleProps = {...} & ComponentProps<'div'>
export function ComponentExample({}: ComponentExampleProps) {...}All components should use Tailwind CSS for styling. Inline styles may be used only when the style depends on runtime values that cannot be expressed with Tailwind classes. Use current available Tailwind utilities and CSS variables or add new ones as needed.
You may use animation libraries such as Motion, GSAP, or React Three Fiber. Choose the library that best fits the effect you are implementing.
For interactive components, add keyboard support and ARIA roles/labels where practical. Purely visual or complex animations that can’t fully support accessibility are exempt. Optimization like reduced motion should be handled by the developer using the component.
Create a new folder in the src/registry/base folder with the name of the component:
export default function ComponentName() {
return <></>
}Create a demo component in the src/registry/demos folder and structure it how you want:
import ComponentName from '@/registry/base/component-name/component-name'
export default function ComponentNameDemo() {
return <ComponentName />
}Export the demo component in the src/registry/demos/index.ts file:
export const demos: Record<string, React.LazyExoticComponent<React.ComponentType>> = {
'component-name': lazy(() => import('./component-name-demo/component-name-demo')),
}Add the component to the registry by including its name and dependencies in src/registry/index.ts:
export const components: TRegistryComponent[] = [
{
name: 'new-component',
files: ['new-component.tsx'],
description: 'My new component',
dependencies: [
'example-dependency-1',
'example-dependency-2',
],
},
]Add the metadata for the component in the frontmatter:
---
title: "New Component"
description: "My new component"
icon: 'Component'
---Add a preview of the component by using the <DocComponentPreview /> component with the same exact name of the demo component.
<DocComponentPreview name="component-name-demo" />Add the installation guide by using the <DocInstallGuide /> component with the same exact name of the base component.
<DocInstallGuide name="component-name" />Provide a code example of the component by using the language of the code.
import { MyComponent } from 'my-component'
<MyComponent/>Add the API of the component by using the following table format:
| Name | Type | Default | Description |
| ----------------- | ------- | --------- | -------------------------------------------------------------------- |
| `speed` | number | `1.0` | Controls the animation speed multiplier. |
| `color` | string | `#ff5733` | Sets the primary color of the component. |Provide a detailed list of the component's features and always mention credits:
- Lightweight with no external dependencies
- Fully customizable via props- Inspired by [Author Name](https://example.com)
- Animation logic adapted from [Library Name](https://example.com)Use conventional commits: start your commit message with the type of change (feat, fix, chore, docs, refactor, style, test) followed by a precise, descriptive message.
To run tests locally be sure you have all the dependencies installed, in both the root and the packages/cli-tool folder.
Tests run automatically on every pull request. They verify that every component has its files, demo, export, and documentation in sync.
You can also run them locally to catch issues early by running pnpm test