all-right-LLC/keydrop
all-right-LLC/keydrop has 21 GitHub stars and 5 forks. GitHot measured +2 stars in 24 hours. Last checked 2026-11-14 10:09 UTC. Last push 2026-11-10.
What you can do
- Four code kinds: redemption, discount, license (online activation with per-device limits) and external-platform codes
- Generate, import (.xlsx / CSV with column mapping and preview) and sync Stripe promotion codes
- AES-GCM encryption at rest, exact-match search, export, revoke / restore, expiry and per-code usage limits
- Unique or shared codes, with shared-claim limits across campaigns and sales
Measured star growth
- in 24h
- +2
- in 7 days
- Collecting history
- in 15 days
- Collecting history
- in 1 month
- Collecting history
Net star changes over overlapping periods, not daily totals. Missing measurements are left blank. Stars measure attention, not software quality.
About
Self-hosted code distribution for indie developers: redemption codes, discount codes and license keys on your own Cloudflare Workers + D1.
Self-hostedREADME.md
Original
English · 繁體中文 · 简体中文 · 日本語 · 한국어 · Italiano · Deutsch · العربية
Self-hosted code distribution for indie developers. Manage and hand out redemption codes, discount codes, license keys and App Store promo codes from your own Cloudflare account — free claim campaigns, Stripe checkout, entitlements, an API, webhooks and an MCP server, all in one small Next.js app.
Status: pre-1.0. The core flows run end to end on Cloudflare, but expect breaking changes before 1.0. Test it in your own environment before relying on it for real sales.

![]() |
![]() |
![]() |
![]() |
Why Keydrop
You built an app and now you have a spreadsheet of promo codes, a few hundred license keys and a Stripe account. Keydrop gives those codes a home:
- One inventory for every kind of code — generate codes, import them from CSV/Excel (App Store offer codes, partner keys, Stripe promotion codes) and keep them encrypted at rest.
- Hand them out however you need — public or private claim pages with eligibility rules, paid checkout via Stripe, direct assignment, email distribution, or a phone-friendly Quick handout page for giving a code to someone in a chat.
- Know who has what — every claim, order, handout and redemption is recorded; revoke codes, reclaim entitlements and handle refunds without losing history.
- Wire it into your product — scoped API tokens, a REST API, signed webhooks and an MCP server so your backend or AI agents can issue and check codes.
- Yours to run — MIT licensed, single administrator, deploys to your own Cloudflare Workers + D1. No hosted service, no per-code fees.
Features
Codes & inventory
- Four code kinds: redemption, discount, license (online activation with per-device limits) and external-platform codes
- Generate, import (.xlsx / CSV with column mapping and preview) and sync Stripe promotion codes
- AES-GCM encryption at rest, exact-match search, export, revoke / restore, expiry and per-code usage limits
- Unique or shared codes, with shared-claim limits across campaigns and sales
Distribution
- Claim campaigns: public or private links, anonymous / verified-email / account-only, per-person and total limits, nested AND/OR eligibility rules (time windows, passphrases, invitations, purchase history, your own HTTP check)
- Stripe Checkout: one code per purchase, discounts, refunds that can revoke the code, and three out-of-stock strategies (refund, manual fulfilment, auto-fulfil after restock)
- Direct assignment and email distribution to people who don't have an account yet
- Quick handout — a mobile-first page to take a code, share it (including three shareable image cards drawn on-device) and note who got it; installable to the home screen
Rewards & entitlements
- Built-in memberships (time-limited or permanent) and credit ledgers with idempotent spend / refund APIs
- Stack, replace or reject repeated rewards; reclaim unused entitlements when a code is revoked
- External rewards delivered to your own service, with manual review when the result is unknown
Integrations
- REST API and an MCP server with fine-grained, product-scoped tokens (MCP is read-only by default)
- Signed outgoing webhooks with retries
- Optional Cloudflare Email Sending for one-time-code sign-in, code emails and admin alerts
Admin console
- SaaS-style dashboard with activity charts, ⌘K command palette, light / dark themes and a mobile layout, built with beUI components
- Interface in English, 简体中文, 繁體中文, 日本語, 한국어, Italiano, Deutsch and العربية (right-to-left supported); the language follows the visitor's browser and can be switched at any time
Tech stack
Next.js (App Router) on Cloudflare Workers via OpenNext · Cloudflare D1 · Better Auth · Stripe (optional) · next-intl · beUI + Tailwind CSS
Quick start
Deploy to Cloudflare
Click Deploy to Cloudflare above. Cloudflare copies the
apps/webfolder into a new repository in your GitHub account and creates a Worker and a D1 database.Fill in the settings it asks for:
Name What to enter APP_URLThe site's HTTPS origin, e.g. https://keydrop.your-subdomain.workers.dev(no trailing slash)ADMIN_EMAILThe email address of the single administrator BETTER_AUTH_SECRETA random secret, e.g. openssl rand -hex 32SETUP_SECRETAnother random secret, used once on the setup page CODE_ENCRYPTION_KEY64 hex characters, e.g. openssl rand -hex 32— back this up; losing it makes existing codes unreadableUse a different value for each secret. Leave the build command empty and set the deploy command to
pnpm run deploy.Open
APP_URL/setup, enterSETUP_SECRETand choose the administrator password. Then sign in and create your first product.
The free core (codes, campaigns, claims) needs nothing else. Add Stripe and Email Sending later if you want them.
Run locally
Requires Node.js 24+ and pnpm.
cd apps/web
pnpm install --frozen-lockfile
node scripts/create-local-env.mjs "$HOME/.config/keydrop/local.env" [email protected]
pnpm run db:migrate
KEYDROP_DEV_ENV_FILE="$HOME/.config/keydrop/local.env" pnpm dev
Open http://localhost:3000/setup and use the SETUP_SECRET from the generated file (kept outside the repository, never printed to the terminal).
Deploy manually
cd apps/web
pnpm exec wrangler login
pnpm exec wrangler d1 create keydrop # put the database ID into wrangler.jsonc
# set your Worker name, APP_URL and ADMIN_EMAIL in wrangler.jsonc, then:
pnpm exec wrangler secret put BETTER_AUTH_SECRET
pnpm exec wrangler secret put SETUP_SECRET
pnpm exec wrangler secret put CODE_ENCRYPTION_KEY
pnpm run deploy # builds, applies D1 migrations, deploys
Configuration
| Setting | Type | Required | Purpose |
|---|---|---|---|
APP_URL, ADMIN_EMAIL |
var | yes | Public origin and administrator email |
BETTER_AUTH_SECRET, SETUP_SECRET, CODE_ENCRYPTION_KEY |
secret | yes | Sessions and identity hashing, one-time setup, code encryption |
STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET |
secret | for sales | Stripe Checkout and the webhook at /api/stripe/webhook |
EMAIL binding + EMAIL_FROM |
binding / var | for email | Cloudflare Email Sending: OTP sign-in, code emails, admin alerts |
WEBHOOK_SECRETS |
secret | for webhooks | Signing secrets for outgoing webhooks |
ELIGIBILITY_SECRETS, EXTERNAL_REWARD_SECRETS |
secret | optional | Signing secrets for your own eligibility checks and external reward receivers |
KEYDROP_TELEMETRY |
var | on by default | One anonymous ping (random ID + version) when setup completes, used only to count installations; set to off to disable. Details |
A cron trigger runs every five minutes to expire reservations, fulfil back-orders, send queued email and deliver webhooks. Run pnpm run cf-typegen after editing wrangler.jsonc.
Feature switches (public pages, "My codes", admin alert emails) live in apps/web/src/config/site.ts; branding and all copy live in apps/web/messages/<locale>.json.
Make it your own
Everything a typical deployment changes lives in a handful of files. Keeping your edits there makes it easier to pull in upstream updates later.
| What you want to change | Where (inside apps/web/) |
|---|---|
| Brand name, homepage and page copy, email text | messages/<locale>.json: common.brand, home, publicSite, email (edit the same key in every language you ship) |
| Homepage sections and their order, optional public pages, "My codes" and admin alert switches | src/config/site.ts |
| “Powered by Keydrop” footer link and GitHub links (optional under MIT; you may turn them off) | src/config/site.ts: poweredBy.enabled, publicSite.repositoryUrl |
| Homepage layout and visuals | src/components/site/landing/sections.tsx, src/components/site/landing/hero-visual.tsx, src/app/page.tsx |
| Features page and optional pages (docs, pricing, demo, changelog) | src/app/features/page.tsx, src/app/[section]/page.tsx |
| Logo, favicon and app icons | src/components/site/brand-logo.tsx, public/brand/, public/favicon.svg, src/app/favicon.ico, public/icons/, public/handout.webmanifest |
| Colors and light / dark theme | src/app/globals.css (the :root tokens and --brand-accent) |
| Social share image | Generated on every build from the wordmark and the home copy by scripts/generate-share-image.mjs |
| Interface languages | src/i18n/locales.ts plus one file per language in messages/ |
| Worker name, public URL, cron schedule, bindings | wrangler.jsonc (run pnpm run cf-typegen afterwards) |
Products, prices, campaigns, eligibility rules, email delivery and API tokens are managed in the dashboard, not in code.
Change these only when you know why: migrations/ (add new files, never edit existing ones), src/lib/server/ (authentication, encryption, payments and inventory rules) and src/components/motion/ (beUI components; update them from upstream instead).
Documentation
Full guides live in docs/api in English, 繁體中文 and 简体中文:
- Deployment, backup & restore · Local development · Customization & admin console
- Authentication & API tokens · MCP · Webhooks
- Campaign conditions · Eligibility hooks · Entitlements & credits · Licenses
- Stripe · Stripe discounts · Email · Quick handout
Translations
The interface ships in eight languages. Public pages also have language URLs such as /ja/features with matching hreflang tags and sitemap entries, and emails go out in each recipient's language. Each locale is a JSON file in apps/web/messages with exactly the same keys as en.json; a test checks that every translation has the same keys and the same ICU placeholders. To add a language, add its code to src/i18n/locales.ts and create the matching JSON file. Corrections from native speakers are very welcome.
Development
cd apps/web
pnpm run lint
pnpm run typecheck
pnpm test # unit and integration tests against real SQLite + migrations
pnpm run build:worker # production Worker build
CI runs the same checks on Node.js 24 and 26, plus a fresh local D1 setup that claims codes end to end. See CONTRIBUTING.md before opening a pull request, and SECURITY.md to report a vulnerability.
License
MIT © all right LLC. Bundled beUI components keep their upstream MIT license (apps/web/vendor/beui.LICENSE).
Acknowledgements
Keydrop stands on the shoulders of these projects. Thank you to everyone who builds and maintains them:
- Next.js and React: the app framework
- OpenNext for Cloudflare, Cloudflare Workers, D1 and Wrangler: hosting, database and deployment
- Better Auth: sign-in, sessions and email one-time codes
- Stripe: payments
- next-intl and FormatJS: translations and message checks
- beUI, Tailwind CSS, Motion, Lucide, Floating UI, TanStack Virtual, next-themes, clsx and tailwind-merge: the interface
- Zod: input validation
- Kysely and kysely-d1: database access for Better Auth
- Model Context Protocol TypeScript SDK: the MCP server
- SheetJS: Excel import
- Geist and Poppins: typefaces for the interface and the logo
- Vitest, TypeScript and ESLint: testing and tooling
Explore related projects
awesome-selfhosted/awesome-selfhosted
A list of Free Software network services and web applications which can be hosted on your own servers
336,883 starsimmich-app/immich
High performance self-hosted photo and video management solution.
119,132 starsStirling-Tools/Stirling-PDF
#1 PDF Application on GitHub that lets you edit PDFs on any device anywhere
96,551 starslouislam/uptime-kuma
A fancy self-hosted monitoring tool
94,013 stars


