EasyUI Logoeasyui
HomeComponentsDocs
TracwellAnalytics sponsoreasyui
ComponentsDocsGitHubLLMs
© 2026 EasyUI. Built by Suraj Maurya
//Contributing Guide
Documentation

Getting Started

Architecture & Engine

Architecture & Engine · 03

Contributing Guide

Learn how to add new components and contribute to EasyUI. Because of our automated single source of truth engine, adding a component takes just two files and a few minutes.

The Two-File Contribution Rule

When adding a component, you only ever create or touch two files in src/components/ui/:

1. Component (.tsx)React + Tailwind CSS + Framer Motion implementation.
2. Metadata (.meta.ts)Name, description, props documentation, and usage code.

All JSON endpoints, registry files, and website documentation pages are automatically generated by the engine.

Step 01

Scaffold a Starter Template

Use the built-in scaffolding command to generate starter boilerplate:

Terminal
npm run component:new TiltCard

This creates src/components/ui/TiltCard.tsx and src/components/ui/TiltCard.meta.ts.

Step 02

Write the Component Code

Write your React component using Framer Motion spring physics and clean Tailwind CSS styling:

src/components/ui/TiltCard.tsx
import React, { useRef } from 'react';
import { motion, useSpring } from 'framer-motion';
import { cn } from '../../lib/utils';

export interface TiltCardProps extends React.HTMLAttributes<HTMLDivElement> {
  children: React.ReactNode;
  maxTilt?: number;
  className?: string;
}

export const TiltCard: React.FC<TiltCardProps> = ({
  children,
  maxTilt = 15,
  className,
  ...props
}) => {
  const rotateX = useSpring(0, { stiffness: 300, damping: 25 });
  const rotateY = useSpring(0, { stiffness: 300, damping: 25 });

  return (
    <motion.div
      style={{ rotateX, rotateY, transformStyle: 'preserve-3d' }}
      className={cn('rounded-2xl border border-[#1F1F1F] bg-[#0E0E0E] p-6', className)}
      {...(props as any)}
    >
      {children}
    </motion.div>
  );
};
Step 03

Define Component Metadata

Define props, category, badges, and usage snippet in the metadata file:

src/components/ui/TiltCard.meta.ts
import type { EasyComponentMeta } from '../../types/component';

export const TiltCardMeta: EasyComponentMeta = {
  id: 'tilt-card',
  name: 'Tilt Card',
  category: 'Motion',
  description: 'Tactile 3D perspective tilt card that tracks pointer momentum with springs.',
  badges: ['Framer Motion', '3D Perspective'],
  cliCommand: 'npx shadcn@latest add Surajmaurya1/easyui/tilt-card',
  dependencies: ['framer-motion', 'clsx', 'tailwind-merge'],
  files: ['src/components/ui/TiltCard.tsx'],
  props: [
    { name: 'children', type: 'React.ReactNode', required: true, description: 'Inner card contents' },
    { name: 'maxTilt', type: 'number', defaultValue: '15', description: 'Max rotation angle' },
  ],
  usageExample: `<TiltCard maxTilt={20}>
  <p className="text-white">Hover to experience 3D tilt.</p>
</TiltCard>`,
  sourceCode: '', // Automatically populated by sync script
};
Step 04

Sync & Validate

Execute the sync and validation script to generate registry artifacts:

Terminal
# Sync all components and metadata
npm run component:sync

# Validate all schemas and disk paths
npm run registry:validate

Pull Request Checklist

Component is written in TypeScript (.tsx) with clean exports
Corresponding .meta.ts is complete with props and usage
npm run component:sync ran with 0 errors
npm run registry:validate passed cleanly
Spring motion feels smooth and responsive
Accessible with keyboard and reduced-motion fallback