discover · compare · collections · requirements · contribute · feed · watching · stats · help with your tokens
dodopayments/chimely · source
Snapshot 0 · 2026-11-04T12:47:28Z · Rust · AGPL-3.0
Content fingerprint
2c267b133157d939c06d377141f2441ba73cf2adcf016f25ec45e819d2fb819aGitHub description at capture
Open-source, self-hostable in-app notification inbox infrastructure: one Rust binary + Postgres + Redis, a small HTTP API, and a drop-in <Inbox /> React component.
README at capture
# Chimely
[](https://github.com/dodopayments/chimely/actions/workflows/ci.yml)
[](https://www.npmjs.com/package/@chimely/react)
[](https://www.npmjs.com/package/@chimely/client)
[](https://github.com/dodopayments/chimely#license-faq)
Open-source, self-hostable **in-app notification inbox infrastructure**.
One Rust binary + Postgres + Redis, a deliberately small HTTP API, and a
drop-in `<Inbox />` React component. No workflow engine: the inbox is the
primitive.
Your backend sends one POST:
```bash
curl -X POST https://chimely.example.com/v1/notifications \
-H 'Authorization: Bearer <api-key>' \
-H 'Content-Type: application/json' \
-d '{
"subscriber_id": "usr_123",
"category": "billing.invoice",
"payload": { "title": "Invoice ready", "body": "March invoice is ready." }
}'
```
Your frontend renders one component:
```tsx
import { Inbox } from '@chimely/react';
<Inbox
serverUrl="https://chimely.example.com"
environment="production"
subscriberId="usr_123"
subscriberHash={subscriberHash}
/>
```
That is a live bell with unread counts, read state, tabs, archive, infinite
scroll, per-category preferences, and SSE live updates. Nothing else to build.
## Quickstart
Nothing to clone: the server runs from the published image and the component
installs from npm.
```bash
docker network create chimely
docker run -d --name chimely-pg --network chimely \
-e POSTGRES_PASSWORD=chimely postgres:16-alpine
docker run -d --name chimely --network chimely -p 8080:8080 \
--restart unless-stopped \
-e DATABASE_URL=postgres://postgres:chimely@chimely-pg:5432/postgres \
-e CHIMELY_DEV_ENVIRONMENT=demo \
-e CHIMELY_DEV_API_KEY=dev-secret-key \
ghcr.io/dodopayments/chimely:0.2.1
```
The restart policy covers the first seconds while Postgres is still
initializing (the server fails fast when its database is unreachable). Then
follow the [quickstart](https://chimely.dev/docs/quickstart): send a
notification with curl and mount `<Inbox />` in your app, about five minutes
end to end.
## How it works
```
your backend ── POST /v1/notifications ──▶ ┌─────────────┐ ◀──▶ Postgres (source of truth)
│ chimely │
your frontend ◀── SSE hints + REST/ETag ──▶│ one binary │ ◀──▶ Redis (hints; optional)
<Inbox /> └─────────────┘
```
- **Postgres is authoritative.** Redis only carries real-time hints and
recomputable caches; losing it delays updates but never loses data.
- **SSE is a hint, not a transport.** Every hint triggers a conditional
refetch (ETag, mostly `304`s), so missed hints are harmless by
construction.
- **Single-org, multi-environment.** Environments are the isolation unit;
multi-tenancy is "run another instance".
- The server embeds its migrations (run on boot under an advisory lock), an
operator dashboard, Prometheus metrics, and OpenAPI docs at `/docs`.
## What Chimely is not
These are deliberate. Chimely does the inbox and nothing else:
- No workflows, steps, or conditional routing.
- No email, SMS, or push channels. In-app inbox only.
- No server-side templating. Your payload is stored and shown as-is.
- No digests or batching.
## Repository layout
```
server/ Rust binary: API, SSE, workers (AGPL-3.0)
packages/client/ @chimely/client, headless TS core (MIT)
packages/react/ @chimely/react, hooks + <Inbox /> (MIT)
examples/ quickstarts and integration examples (MIT)
docs/ Fumadocs site (MIT)
```
## Admin dashboard
The server embeds an operator dashboard at `/admin` (status/timeline browser,
broadcast composer, subscriber lookup, DLQ replay, environment + API key
management, HMAC rotation, and admin-user management). It ships inside the
binary: `docker run chimely` serves it with no extra artifact.
**Built-in users with roles.** The dashboard has its own login (email +
password, Argon2id-hashed) backed by a server-side session cookie. Four fixed
roles gate what each operator can do (still single-org, no organizations, no
per-environment user scoping):
- **viewer** reads everything (inbox, timelines, subscriber lookup, DLQ list).
- **operator** adds DLQ replay and composing broadcasts.
- **developer** adds create/revoke API keys and reading an environment's
subscriber HMAC secret.
- **admin** adds creating environments, rotating HMAC secrets, and managing
users.
**Bootstrap (root) admin.** On boot, if `CHIMELY_ADMIN_EMAIL` and
`CHIMELY_ADMIN_PASSWORD` are set, Chimely ensures an `admin` account with that
email exists, creating it or resetting its password to the env value if it
drifted. This is the lockout-recovery path: restart with the env vars to
restore admin access. Everyone else gets their own account from the Users
page.
```bash
CHIMELY_ADMIN_EMAIL=ops@example.com \
CHIMELY_ADMIN_PASSWORD="$(openssl rand -hex 24)" \
CHIMELY_ADMIN_TLS_TERMINATED=true \
chimely serve
```
**TLS is required.** The session cookie is `HttpOnly; SameSite=Strict;
Path=/admin`, marked `Secure` only when `CHIMELY_ADMIN_TLS_TERMINATED=true`.
The binary serves plain HTTP, so terminate TLS at a proxy and set that flag;
without it Chimely logs a boot-time warning and the cookie omits `Secure`.
Passwords and session ids are never logged.
## Versioning
Chimely is pre-1.0 (currently 0.2.x). The HTTP API and the SDK surface may
change on minor version bumps until 1.0.0. Pin your versions: the Docker tag
and the npm versions.
## Contributing
See [CONTRIBUTING.md](https://github.com/dodopayments/chimely/blob/main/CONTRIBUTING.md)
for the dev setup and workflow. External code contributions require a CLA so
the project keeps relicensing and commercial-licensing flexibility.
## License FAQ
**What is licensed how?** The server (`server/`) is
[AGPL-3.0](https://github.com/dodopayments/chimely/blob/main/LICENSE), the GNU
Affero General Public License v3. The SDKs (`packages/client`,
`packages/react`) and everything in `examples/` are MIT; they embed in your
frontend, and they carry their own `LICENSE` files.
**What does AGPL mean for me?** You can use, self-host, modify, and
redistribute Chimely freely: internally, in production, commercially, at
any scale, for free, forever. AGPL's one obligation is reciprocity: if you
modify Chimely and offer it to others over a network, you must give those
users that modified server's source (AGPL §13). Running it
unmodified carries no such obligation.
**Does the server license affect my application?** No. You run the Chimely
binary as a standalone network service and integrate over HTTP through the
MIT-licensed SDKs. Your application is a separate program that talks to
Chimely over the API. AGPL covers Chimely's own source, not the client
code that calls it, and calling the HTTP API creates no obligations.
**Is this open source?** Yes. AGPL-3.0 is an OSI-approved open source
license. It is copyleft: the freedom to use, study, modify, and share is
preserved for everyone you distribute or network-serve the server to.
**What about the API spec and docs?** The generated OpenAPI document and
the documentation content are MIT, so third-party clients, bindings, and
integrations are unambiguous.
**The name and logo?** Not licensed. "Chimely" and the logo remain with the
project regardless of code license; that, not the code license, is the
protection against confusing forks.