v0.1.1 Work in progress

In app notifications in minutes, not weeks

Add realtime in-app notifications to your product with two SDK calls. Reliable queue-backed delivery, SSE streaming, and full self-host control with no vendor lock-in.

$ npm i @flypigeon/node @flypigeon/react
Integrate in less than 15 min
PostgreSQL + Redis
MIT licensed
Your server sends
await pigeon.send({
  userId: 'user_tz9k3m',
  type:   'order.shipped',
  title:  'Your order shipped!',
  body:   'Package #4521 is on its way.'
})
Notifications 3
order.shipped
Your order shipped!
Package #4521 is on its way.
now
team.invite
Mara invited you
Join the Acorn design team.
3m
payment.success
Payment confirmed
$128.40 received from Osei.
12m
report.ready
Monthly report ready
Download your July summary.
1h

From zero to notifications
in under 15 minutes.

Two packages. Two functions. Real-time in-app notifications in any app with no third-party vendor, no lock-in.

01

Install both SDKs

One package for your server, one for your React frontend.

$ npm i @flypigeon/node @flypigeon/react
02

Send from your server

Call send() with your API key. The notification is enqueued and delivered reliably — no duplicates with idempotency keys.

POST /v1/notifications
→ 202 { notificationId }
03

Render in your frontend

Wrap with NotifyProvider and call useNotifications(). Updates arrive in real-time over SSE — no polling.

SSE event: notification.created
→ useNotifications() re-renders

Built for reliability.
Designed for developers.

Real-time via SSE

Persistent server-sent event streams with automatic reconnect and missed-event replay using Last-Event-ID. No WebSocket complexity.

notification.created user_tz9k3m 14:23:01.847
notification.created user_p8r2wq 14:23:03.112
keepalive · 14:23:30.000

Queue-backed delivery

BullMQ processes every notification. Idempotent sends prevent duplicates.

Deliveryat-least-once
Idempotencyper-env key
TTL90 days
Rate limit100 req/s

Webhooks with exponential backoff

HMAC-signed x-pigeon-signature POST requests. Every attempt fully logged — response codes, error messages, timestamps.

1
Attempt 1 — 200 OK
POST https://hooks.acorn.io/pigeon
14:23:01
2
Attempt 2 — 503 timeout
Retry in 30s (backoff factor 2)
14:25:47
3
Attempt 3 — pending
Scheduled in 2 min
scheduled

Projects & environments

Isolated dev and production environments with scoped API keys per project.

development production
pk_test_ ••••••••••••••
pk_live_ ••••••••••••••

End-to-end in three steps.

Pigeon owns the infrastructure layer. You write the product logic.

01

Send from your server

Your backend calls pigeon.send(). The API validates your key, upserts the end user, inserts the notification, and enqueues the delivery job synchronously.

POST /v1/notifications
→ 202 { notificationId }
02

Worker delivers it

A BullMQ worker picks up the job, renders any configured template, marks the notification as delivered, publishes to Redis pub/sub, and enqueues webhook jobs.

notification-delivery queue
→ render → deliver → publish
03

Frontend receives live

The SSE stream forwards the event instantly. On reconnect, Last-Event-ID lets the API replay missed events from Redis Stream — zero notifications lost.

SSE event: notification.created
→ useNotifications() re-renders

Run it on your
own infrastructure.

One docker compose up brings the full stack online: API, background worker, admin dashboard, PostgreSQL, and Redis. No external services required.

PostgreSQL 16 Redis 7 Hono BullMQ Next.js 15 Drizzle ORM Turborepo
bash
$ cp .env.example .env
$ docker compose up --build
[+] Building services...
> pigeon-postgres Started
> pigeon-redis Started
> pigeon-api Started :3001
> pigeon-worker Started
> pigeon-dashboard Started :3000
All services healthy. Stack is ready.