Imported from github.com/cyguin/waitlist
Find a file
2026-06-03 17:36:31 -07:00
demo gsd: pre-implementation lint/format cleanup 2026-05-16 13:43:56 -07:00
migrations full release: add referralCount, pagination, WaitlistAdmin, demo app, README 2026-04-02 23:27:04 -05:00
src test: increase test coverage from 14.3% to 31.4% 2026-05-18 23:05:05 -07:00
.gitignore gsd: pre-implementation lint/format cleanup 2026-05-16 13:43:56 -07:00
lefthook.yml chore: add lefthook pre-commit hooks 2026-06-03 17:36:31 -07:00
LICENSE chore: normalize cyguin package metadata 2026-04-21 09:26:39 -05:00
package-lock.json docs: align waitlist dark theme docs 2026-04-21 09:32:43 -05:00
package.json docs: align waitlist dark theme docs 2026-04-21 09:32:43 -05:00
README.md gsd: pre-implementation lint/format cleanup 2026-05-16 13:43:56 -07:00
tsconfig.json gsd: pre-implementation lint/format cleanup 2026-05-16 13:43:56 -07:00
tsup.config.ts gsd: pre-implementation lint/format cleanup 2026-05-16 13:43:56 -07:00
vitest.config.ts gsd: pre-implementation lint/format cleanup 2026-05-16 13:43:56 -07:00

@cyguin/waitlist

Drop-in email waitlist with position tracking and optional referral loop for Next.js apps.

Install

npm install @cyguin/waitlist

Quick start

1. Configure the adapter

// lib/waitlist.ts
import { createSQLiteAdapter } from "@cyguin/waitlist/adapters/sqlite";

export const waitlistAdapter = createSQLiteAdapter();

2. Add the API route

// app/api/waitlist/[...cyguin]/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createWaitlistHandler } from "@cyguin/waitlist/next";
import { waitlistAdapter } from "@/lib/waitlist";

const handler = createWaitlistHandler({ adapter: waitlistAdapter });

export async function GET(req: NextRequest) {
  return handler(req);
}

export async function POST(req: NextRequest) {
  return handler(req);
}

3. Drop in the component

// app/page.tsx
import { WaitlistForm } from "@cyguin/waitlist";

export default function Home() {
  return (
    <main>
      <h1>Join the waitlist</h1>
      <WaitlistForm placeholder="Enter your email" buttonText="Join waitlist" />
    </main>
  );
}

API

POST /api/waitlist

Join the waitlist.

Request:

{
  "email": "user@example.com",
  "referred_by": "TOKEN" // optional
}

Response 201:

{
  "id": "abc123",
  "email": "user@example.com",
  "position": 42,
  "referral_token": "abc123"
}

Response 409 — email already registered:

{ "error": "already_registered" }

GET /api/waitlist?email=xxx

Get your position on the waitlist.

Response 200:

{
  "id": "abc123",
  "email": "user@example.com",
  "position": 42,
  "referral_token": "abc123",
  "joined_at": 1712000000000
}

Response 404 — not found:

{ "error": "not_found" }

Referral system

When a user joins via ?ref=TOKEN, their entry records who referred them. Position is never adjusted based on referral count — referrals are informational only.

  1. On POST, a referral_token (the entry's id) is returned.
  2. Share links like https://yoursite.com/?ref=TOKEN.
  3. New joins with ?ref=TOKEN store the referrer's id.

<WaitlistForm /> Props

Prop Type Default Description
className string '' CSS class for the form container
placeholder string 'Enter your email' Input placeholder text
buttonText string 'Join waitlist' Button label
redirectTo string — If provided, redirects here after success with ?ref=TOKEN
theme 'light' | 'dark' 'dark' Visual theme. Pass 'light' to opt into the light theme.
onSuccess (data: JoinResponse) => void — Callback on successful join
onError (error: string) => void — Callback on error

Theming

All styling defaults to the cyguin dark theme and uses --cyguin-* CSS custom properties. Default tokens:

--cyguin-bg: #0a0d17 --cyguin-bg-subtle: #101521 --cyguin-border: #252b3a
  --cyguin-border-focus: #f5a800 --cyguin-fg: #f1f3f6 --cyguin-fg-muted: #888888
  --cyguin-accent: #f5a800 --cyguin-accent-dark: #c47f00
  --cyguin-accent-fg: #0a0a0a --cyguin-radius: 6px --cyguin-shadow: 0 1px 4px
  rgba(0, 0, 0, 0.08);

Apply a light theme with the theme prop:

<WaitlistForm theme="light" />

Exports

Export Description
@cyguin/waitlist Main package entry — types, adapters, handler
@cyguin/waitlist/next Next.js route handler for API route
@cyguin/waitlist/react WaitlistForm component
@cyguin/waitlist/adapters/sqlite SQLite adapter (better-sqlite3)
@cyguin/waitlist/adapters/postgres Postgres adapter (postgres.js)