Automatically award badges to contributors when PRs merge — turn contributions into verifiable credentials. Built for open-source communities that want to recognize their contributors meaningfully.
Sign in with GitHub to see your dashboard, track points, and claim badges.
New to the project? Get up and running in three steps:
- Visit the app at Live App
- Click "Sign in with GitHub" — no forms, no passwords, just one click
- You're in! Your dashboard shows your points, progress, and available badges
That's it. Your profile is created automatically, and you're ready to start earning badges as your PRs get merged.
Already signed in? Head to the dashboard to check your progress.
📖 Read the guides: Registration Guide · Claiming Badges · Maintainer Labels · Ideas Contributions
- How It Works
- Tech Stack
- Points & Tiers
- Roles & Permissions
- Architecture
- API Overview
- Documentation
- License
- A contributor merges a PR in a tracked GitHub repository.
- A webhook fires — the app awards points based on the PR's label
(e.g.,
frontend:imp→ +1 Frontend point). - Points accumulate — reach a threshold and a badge becomes available.
- The contributor claims the badge from their dashboard — issued as a verifiable digital credential via certifier.io.
- The credential is shareable — on LinkedIn, GitHub, or anywhere credentials are accepted.
| Layer | Technology |
|---|---|
| Framework | Next.js 14 (App Router) + TypeScript |
| Auth | NextAuth.js (v4) with GitHub OAuth |
| Database | Supabase (PostgreSQL + RLS + Realtime) |
| UI | Tailwind CSS + shadcn/ui + @base-ui/react |
| Badging | certifier.io REST API (digital credentials) |
| CI/CD | GitHub Actions + Vercel |
Badges are earned by accumulating points within each family. Points come from merged PRs — the label determines the family and tier.
| Tier | Per PR | Badge threshold |
|---|---|---|
| Imp | 1 point | 5 |
| Fiend | 3 points | 15 |
| Overlord | 9 points | 45 |
| Demon King | 27 points | 135 |
| Family | Icon | Focus Area |
|---|---|---|
| Frontend | 🎨 | UI code, components, accessibility |
| Backend | ⚙️ | Server logic, APIs, databases |
| Documentation | 📚 | Docs, tutorials, translations |
| Community | 🤝 | Support, reviews, feature proposals, CI/CD, UX research |
| Role | Permissions |
|---|---|
| Contributor | View dashboard, claim badges, view contributions |
| Maintainer | All contributor + nominate/vote for special badges, view admin settings |
| Admin | All maintainer + edit admin settings, manage users, full access |
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ GitHub │────▶│ Webhook │────▶│ Supabase │
│ (PR merge) │ │ /api/... │ │ (database) │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
┌──────────────────────────────┘
▼
┌──────────────────┐ ┌──────────────┐
│ Next.js App │◀───▶│ certifier.io│
│ (dashboard) │ │ (badges) │
└──────────────────┘ └──────────────┘
- Auth is handled by NextAuth.js, not Supabase Auth — the session's
user.idis mapped to theprofilestable (text ID, not UUID). All browser-side data queries use API routes backed by the Supabase admin client (service role key) to bypass RLS, sinceauth.uid()returns null for non-Supabase sessions. - RLS policies exist for direct database access but cast
auth.uid()totextfor compatibility with the profiles table's text ID column. - Badge claims use a unique constraint on
(user_id, family, tier)— each contributor can claim each badge tier only once.
| Route | Method | Purpose |
|---|---|---|
/api/user/profile |
GET | Current user's profile and points |
/api/badges/available |
GET | Badges available to claim |
/api/badges/claimed |
GET | Badges already claimed |
/api/badges/claim |
POST | Claim an available badge |
/api/github/webhook |
POST | GitHub PR merge webhook |
/api/admin/settings |
GET/PUT | Admin configuration |
/api/special-badges/nominate |
POST | Nominate for a special badge |
/api/special-badges/vote |
POST | Vote on a special nomination |
| Service | Integration |
|---|---|
| GitHub | OAuth login + webhook (PR merge events) |
| Supabase | Database, RLS, Realtime subscriptions |
| certifier.io | Digital credential creation and issuance |
| Document | Description |
|---|---|
| CONTRIBUTING.md | How to contribute, PR workflow, and label conventions |
| SECURITY.md | Security policy and vulnerability reporting |
| CODE_OF_CONDUCT.md | Community standards and enforcement |
| Registration Guide | How contributors sign up and create a profile |
| Claiming Badges Guide | Step-by-step for claiming your earned badges |
| Maintainer Labels Guide | Label format, setup, and point award system |
| Ideas Contributions Guide | How to submit ideas as community contributions |
| Idea Template | Template for submitting a structured idea proposal |
| LICENSE | MIT license |