QR codes that live inside Telegram. Generate one in any chat, in a private conversation with the bot, or in a full editor that opens as a Telegram Mini App.
| Surface | How it works |
|---|---|
| Inline | Type @kyuarbot https://example.com in any chat and pick a color |
| Private chat | Send the bot any text and get a QR code back |
| Mini App | Tap the button to open the editor, then download or share |
All three render through the same engine, so a code made inline looks identical to one made in the editor.
Most generators give you black squares on white. kyuar draws the finder patterns as rings and fuses adjacent data modules into one continuous shape, the way the logo does.
Every theme is contrast-checked before it ships. A palette below 4.5:1 does not scan reliably on a real camera, so it does not make it into the app.
- Node.js 24 or newer
- pnpm 11 or newer
- just
cloudflaredfor local development, since Telegram needs an HTTPS webhook
just setupThis copies .env.example to .env, symlinks that single file into every
workspace package, and installs dependencies. Then fill in .env:
just secret # generates a value for BOT_WEBHOOK_SECRETRun the app:
just dev # web app on :3000 plus the bot in long-polling modeTo test inline mode and the Mini App you need a public HTTPS URL:
just tunnel # in a second terminal
# put the tunnel URL in NEXT_PUBLIC_APP_URL, then:
just webhook-setThese steps cannot be automated and have to be done once in @BotFather:
/newbotto create the bot and copy the token intoBOT_TOKEN./setinlineto enable inline mode, with a placeholder such asPaste a link to turn it into a QR code./setinlinefeedbackset toEnabledif you later want usage statistics./newappto register the Mini App and point it atNEXT_PUBLIC_APP_URL.
Run just to list every recipe. The ones you need most:
just fix # oxlint --fix, then oxfmt
just check # lint, format check, typecheck, react-doctor
just build # production buildapps/web Next.js 16 app: Mini App UI, /api/qr, /api/bot, /api/share
apps/bot grammy handlers and the development long-polling runner
packages/qr QR matrix renderer, framework agnostic, SVG out
packages/shared zod schemas, option codec, Telegram initData verification
packages/env envin schema, the single source of truth for configuration
brand/ logo, icons and Lottie animation
The bot runs inside the web app as a webhook route in production, and as a separate long-polling process in development. There is only one deployment.
just docker-build
just docker-upNEXT_PUBLIC_* values are baked into the client bundle at build time and come
from build args. Everything else is read from .env at runtime through
env_file, so no secret ever enters an image layer.
Put a reverse proxy cache in front of /api/qr. The route already sends
Cache-Control: immutable, so repeated codes never reach Node.
- Saved qr codes per user, backed by Postgres
- Custom logo upload
- QR scanner using
showScanQrPopup
AGPL-3.0-only. See LICENSE.