Check before you call. A tiny open-source status page — not a calling app.
Share one link (Instagram bio, X, WhatsApp, etc.). Friends open it and see Call me or Don't call, plus an optional note. They call you the normal way — on their phone, FaceTime, WhatsApp — after checking your status.
This is not a dialer. There is no call button. knock only answers: "Is now a good time to call?"
Built by Mohsen · Source on GitHub
People don't know when you're free to pick up. Instead of ignoring calls or leaving people guessing, you share a link that shows your current callability:
| Status | What visitors see | What they should do |
|---|---|---|
| Call me | Green signal | Call you on their phone / FaceTime / WhatsApp |
| Don't call | Red signal | Wait, or send a text |
Optional notes like 💼 In a meeting or 🚽 In bathroom add context.
| Page | URL |
|---|---|
| Public status | http://localhost:3000/demo (after seed) |
| Owner panel | /demo/door (secret: demo) |
| Claim a name | /claim |
| Find your door | /open |
After bun run seed, open http://localhost:3000/demo.
- One link, one signal — Call me / Don't call with a pulsing status orb
- Optional note — quick presets with emoji, or type your own (80 chars)
- No app for visitors — works in any browser
- Owner door — update status with a secret at
/{handle}/door - OG images — share previews on social apps
- Embeds — SVG badge, live script, iframe widget
- Quick page — phone-friendly toggles at
/{handle}/quick - PWA — Add door to Home Screen (per-handle manifest)
- iOS Shortcuts — docs for Siri & automations
- Self-hostable — deploy your own instance on Vercel
| Tool | URL / path |
|---|---|
| Badge SVG | GET /api/badge/{handle} |
| Live embed script | /badge.js + data-handle |
| iframe widget | /{handle}?embed=1 |
| Quick toggle page | /{handle}/quick |
| PWA manifest | /api/manifest/{handle} |
| API docs | /integrations/api |
| iOS Shortcuts | /integrations/ios |
Copy-paste snippets are in your door panel (/{handle}/door) under Tools & embeds.
See also integrations/api.md and integrations/ios/README.md.
- Next.js 16 (App Router)
- React 19
- Tailwind CSS 4
- Bun for local dev
- Redis in production (file store for local dev)
- Bun 1.1+ (or Node.js 20+ with npm/yarn)
git clone https://github.com/mohsenfallahnjd/knock.git
cd knock
bun install
bun run seed # optional: creates /demo profile
bun run devOpen http://localhost:3000.
Without Redis, profiles are stored in data/profiles.json. Fine for development — not for production on Vercel (ephemeral filesystem).
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_APP_URL |
Production | Public URL, e.g. https://knocknock.app (no trailing slash) |
knock_REDIS_URL |
Vercel / prod | Redis connection string (redis:// or rediss://) |
Also supported: KNOCK_REDIS_URL, REDIS_URL, knock_KV_URL, KV_URL.
- Fork or push this repo to GitHub.
- Import the project in Vercel.
- Add Redis (Vercel → Storage → Redis). This sets
knock_REDIS_URL. - Set
NEXT_PUBLIC_APP_URLto your production domain. - Deploy.
bunx vercel # preview
bunx vercel --prod # productionAdd your custom domain in Vercel → Settings → Domains.
| Route | Who | Purpose |
|---|---|---|
/ |
Everyone | Landing page |
/claim |
New users | Claim a handle + secret |
/open |
Owners | Find your door by handle |
/{handle} |
Visitors | Public status page |
/{handle}/door |
Owner | Update status (requires secret) |
/{handle}/quick |
Owner | Fast mobile toggles |
/integrations/api |
Devs | API documentation |
/integrations/ios |
Owners | iPhone Shortcuts guide |
src/
├── app/ # Next.js App Router pages & API
│ ├── api/claim/ # POST — claim a handle
│ ├── api/status/[handle]/ # GET/POST — read & update status
│ └── [handle]/ # Public profile + owner door
├── components/ # UI (DoorPanel, StatusSignal, …)
└── lib/
├── copy.ts # All user-facing strings
├── store.ts # Profile persistence (file or Redis)
└── redis.ts # Redis client
User-facing copy lives in src/lib/copy.ts — good place to tweak wording or translations.
| Command | Description |
|---|---|
bun run dev |
Start dev server |
bun run build |
Production build |
bun run start |
Run production server |
bun run lint |
ESLint |
bun run seed |
Seed /demo profile (secret: demo) |
Contributions welcome — issues, ideas, and pull requests.
- Fork the repo
- Create a branch (
git checkout -b feat/my-idea) - Commit with a clear message (
feat: add …,fix: …) - Open a pull request
Please keep PRs focused. Run bun run lint before submitting.
The in-app name is knock. A good domain for sharing is knocknock (e.g. knocknock.app) — short, memorable, and usually available on cheaper TLDs.
MIT — see LICENSE.
Mohsen — themohsen.me
If knock saves you from awkward calls, consider starring the repo.