Open SourceCommunity DrivenMIT License

Contribution Guidelines

TweenLabs is a community-driven, open-source GSAP component library. Whether you're adding a new animation, fixing a bug, or improving docs — every contribution makes this library better for everyone.

5Steps
~10Lines to add
< 5 minTime
MITLicense
Getting Started
🛠️

Local Development Setup

1

Fork the Repository

Click the Fork button on the top-right of the GitHub page to create your own copy.
2

Clone & Enter

git clone https://github.com/YOUR_USERNAME/TweenLabs.git
cd TweenLabs
3

Install with pnpm

pnpm install
⚠️

This repo uses a pnpm lockfile. Do not use npm or yarn — it will break the lock file and conflict with CI.

4

Configure Environment Variables

Create a .env.local file in the root directory and add the required environment variables:
# Deployment used by `npx convex dev`
CONVEX_DEPLOYMENT=your_convex_deployment_name

# Convex DB Configuration
NEXT_PUBLIC_CONVEX_URL=your_convex_url
NEXT_PUBLIC_CONVEX_SITE_URL=your_convex_site_url

# Better Auth Configuration
BETTER_AUTH_SECRET=your_32_character_secret
SITE_URL=http://localhost:3000

# OAuth Credentials (Optional for local play)
GITHUB_CLIENT_ID=your_github_client_id
GITHUB_CLIENT_SECRET=your_github_client_secret
GOOGLE_CLIENT_ID=your_google_client_id
GOOGLE_CLIENT_SECRET=your_google_client_secret
5

Start the Dev Server

pnpm dev
Open localhost:3000 and go to /components to browse all animations.

Adding a New Component

Every animation must be 100% self-contained inside its own folder. No shared imports. No cross-component dependencies.

1

Create Your Folder & Page

src/app/(main)/components/YourAnimation/
└── page.tsx   ← your entire animation lives here
  • No imports from other route directories
  • No custom classes from globals.css — use inline Tailwind
  • No custom theme values — use exact hex: bg-[#e55b3c] not bg-wtf-orange
  • Sub-components go inside the same page.tsx
  • Assets go in /public/ as absolute paths, or use inline SVGs
2

Register in components.ts

Add your entry to src/data/components.ts:
{
  id: "your-animation",               // Unique slug ID (kebab-case, e.g. "your-animation")
  name: "Your Animation",             // display name
  componentName: "YourAnimation",     // PascalCase — must match folder
  route: "/components/YourAnimation",
  bgColor: "bg-wtf-green",            // see palette below
  textColor: "text-white",
  description: "One sentence describing what this animation does.",
  tiltClass: "tilt-left",
  type: ["card", "scroll"],           // text | scroll | card | interactive (supports multiple)
  preview: "/previews/YourAnimation.webp",   // Optional: static thumbnail
  embedInteraction: "scroll",         // Optional: scroll | cursor | tabs | click-sequence
}

Always use a unique kebab-case slug (e.g. your-animation) for the id field. Do not use sequential numbers to avoid Git merge conflicts. Visual numbers are calculated dynamically by the application.

componentName must match your folder name exactly (case-sensitive). A mismatch causes a 404 and breaks the sidebar link.

📸

preview is optional. If provided, save a .webp screenshot to public/previews/YourAnimation.webp. If missing, a "Hover to preview" placeholder is shown automatically.

bgColor options:

green
bg-wtf-green
orange
bg-wtf-orange
purple
bg-wtf-purple
blue
bg-wtf-blue
yellow
bg-wtf-yellow
red
bg-wtf-red

embedInteraction options:

scrollAuto-scroll (default)
cursorMouse movement
tabsTab clicks
click-sequenceSequential clicks
3

GSAP Standards

  • useGSAP() from @gsap/react — never raw useEffect
  • Always pass a scope ref: { scope: containerRef }
  • Register plugins at file top, not inside hooks
  • Use contextSafe() for callbacks that touch state/refs
  • Clean up timelines and listeners on unmount
🍴

Contribution Workflow

1

Create a Feature Branch

git checkout -b feat/your-animation-name
2

Build & Verify in Browser

Make sure the route renders correctly at /components/YourAnimation and appears in the sidebar and gallery at /components.
3

Validate — Required

pnpm lint
pnpm build
🚫

PRs that fail CI, have TypeScript errors, or contain ESLint warnings will not be merged. Fix all warnings before opening a PR.

4

Commit

git commit -m "feat: add [your animation name]"
Use conventional commits: feat: for new components · fix: for bugs · docs: for documentation.
5

Push & Open PR

git push origin feat/your-animation-name
Open a PR targeting master. Include a short GIF or screenshot of your animation in the PR description.

Good First Contributions

  • Add inline comments explaining GSAP logic
  • Test on mobile/tablet — report layout bugs
  • Create variants with different easing curves
  • Add prefers-reduced-motion support
  • Fix typos or improve docs
  • Report broken routes or console errors
📐

Code Guidelines

  • Use transforms (x, y, scale) — not layout props
  • Respect prefers-reduced-motion
  • TypeScript only — no any types
  • Descriptive conventional commit messages
  • One animation concept per component
  • Comment complex timelines & ScrollTriggers
🤝

Code of Conduct

Be kind and constructive. We're here to learn and build something great together. Discriminatory, harassing, or disrespectful behavior will not be tolerated in issues, PRs, or any community interaction.

Ready to ship?

Built in public.

Animated with love. Open to all.