Backend for solo devs · Invite-only beta
The backend plumbing, pre-built. So your side project gets to the interesting part faster.
Paean is a shared backend I'm building for solo devs juggling more side projects than they have time for. Support inbox, feedback, feature flags, waitlists, cron, files, webhooks — one typed SDK, one API key.
Running on my own projects first. Inviting the waitlist once it's ready for strangers.
// How it will look on day one of your side project import { createPaeanClient } from "@paean/sdk"; const paean = createPaeanClient({ baseUrl: "https://api.paean.dev", apiKey: env.PAEAN_API_KEY, }); await paean.support.threads.create({ body: "Can't log in", category: "bug", reporter_email: "alice@acme.com", reporter_name: "Alice", }); // → { id: "thr_01k…", ref: "PAE-42", created_at: "…" }
↑ The whole integration. Everything else is a Paean concern.
The same nine things. Again.
You've built this backend five times.
Every side project starts the same way. You're excited about the idea, and then you spend the first week wiring the nine services every SaaS needs. By the time the plumbing is done, the spark is gone.
- Support inbox
- Waitlist with invite flow
- Feedback + NPS capture
- Feature flags with rollout %
- Cron jobs
- File uploads to object storage
- Signed outbound webhooks
- Email / Discord / HTTP notifiers
- Public changelog feed
Paean is all nine. Written once, running on Cloudflare's edge, exposed through a typed SDK that runs anywhere JavaScript runs — Workers, Node, Bun, Deno, or an Astro / Next / Hono server endpoint.
What's inside
Nine services. One SDK.
Each has its own admin UI and SDK module. The goal is that using one doesn't force you to adopt all nine — cherry-pick the two that solve your immediate pain and wire up the rest when you need them.
Support inbox
Threads with categories, custom statuses, tags, agent replies, public reporter lookup, and an inbound-email reply path. Per-tenant scoping, soft-delete, seeded from your contact form, the SDK, the `<paean-support-form>` web component, or MCP.
Feedback & NPS
1–10 ratings with optional comment. Stats endpoint per project. Auto-capture hook designed for MCP-driven apps.
Feature Flags
On/off flags with stable rollout percentage. KV hot-path cache. Missing-config path returns disabled rather than guessing.
Waitlist
Capture → invite flow with email. Status transitions (pending → invited → joined). Referrer tag if you want to track source.
Cron
Per-tenant scheduled jobs. Minute-tick scheduler. Separates transient vs permanent failures so retries stop when they should.
Files
R2-backed uploads, streaming in and out. 10MB cap, allow-listed content types, SVG XSS scrub on the way in.
Webhooks
Inbound relay with HMAC verification. Outbound signing in the Stripe-style `t=<unix>,v1=<hex>` format. Retry table for failed deliveries.
Notifiers
Rule-based email, Discord, and generic HTTP. SSRF-guarded outbound with IPv4 normalisation. Template substitution per event.
Changelog
Public JSON feed with a 60-second KV cache. Admin CRUD. Fires a `changelog.published` event when an entry flips from draft.
The diff
Two hundred lines. Now four.
A support-thread ingestion endpoint you've written before — auth, validation, D1 writes, email fan-out, the error envelope you'll regret.
import { Hono } from "hono"; import { z } from "zod"; import { drizzle } from "drizzle-orm/d1"; import { Resend } from "resend"; // + api-key auth middleware // + rate-limit middleware // + D1 schema migrations // + cross-tenant isolation // + soft-delete cascade // + IP hashing for privacy // + request_logs table // + error envelope // + Sentry capture // + outbound webhook signing // + tests for all of the above app.post("/support/threads", auth, tenant, rateLimit, async (c) => { /* … 180 more lines … */ });
import { createPaeanClient } from "@paean/sdk"; const paean = createPaeanClient({ baseUrl: "https://api.paean.dev", apiKey: env.PAEAN_API_KEY, }); await paean.support.threads.create({ body, category, reporter_email, reporter_name }); // Included for free: // ✓ scoped API key auth // ✓ per-tenant rate limit // ✓ cross-tenant isolation // ✓ IP-subnet-hashed request log // ✓ retry on transient 5xx (GET) // ✓ X-Paean-Request-Id correlation // ✓ notifier fan-out (email/Discord/HTTP) // ✓ admin SPA to manage it all
Pricing · Planned
How it'll be priced, when it opens.
Nothing is taking cards yet. The shape below is what I'm planning — subject to change based on what usage actually looks like once there's real traffic. If you want in early, the waitlist is the way.
Hobby
For your first side project.
- 1 project
- 1,000 ops / month
- All 9 services
- TypeScript SDK + REST
- Community support
Indie
For the portfolio dev.
- 5 projects
- 50,000 ops / month
- Email delivery via Resend
- Signed outbound webhooks
- Priority email support (48h)
Maker
When a side project becomes a business.
- Unlimited projects
- 250,000 ops / month
- 3 team seats
- Priority email support (12h)
- Audit-log export
An op is any billable API call — a support thread create, flag eval, cron fire, webhook delivery. Exact rules settle once I've watched a few weeks of real traffic.
Early access
Leave an email. I'll invite you when it's ready.
Paean is running — I use it for my own projects — but it isn't open to strangers yet. I want to stress-test it on real traffic with people I can actually respond to before flipping the signup switch. Leave your email and I'll invite you when the next slot opens.
Uses Paean's own waitlist service. No marketing emails — just the invite when it's your turn.
Questions
Things people ask me.
How ready is this, really?
I've built it, deployed it, and run it for my own projects. I haven't put it through a stress test with real user traffic yet — that's what the waitlist is for. When the first handful of invited users are in and the sharp edges are sanded down, the gates open to strangers. Until then: building in public, not selling.
How is this different from Supabase, Firebase, or Pocketbase?
Those are general-purpose BaaS — database + auth, and you build features on top. Paean is opinionated feature-layer BaaS: support inbox, feedback, flags, waitlists, cron, files, webhooks, notifiers. The stuff every indie SaaS rebuilds. You'd use Paean for the repeat plumbing and your favourite DB for your own domain logic.
Do I need to be on Cloudflare to use it?
No. Paean runs on Cloudflare; your app can live anywhere. If you're on CF Workers the SDK will use a service binding (zero egress). Otherwise it's HTTPS from Node, Bun, Deno, Astro, Next, Hono, or a plain fetch.
What does the free tier actually look like?
Planned: 1 project, 1,000 ops a month, all nine services. Enough for a landing page waitlist, a side project's support inbox, or a feature-flag experiment. Numbers can still shift before launch based on what real usage costs me.
What about GDPR, data residency, deletion?
Data will live in Cloudflare D1 and R2. Soft-delete is first-class across every model — rows are marked and excluded from reads immediately. Hard-delete and full data-export endpoints are on the roadmap; if you need either before I ship them, the waitlist form asks about use cases and I'll prioritise.
Can I use it from Python or Go?
Not with a first-class SDK yet — TypeScript is the only typed client. Every endpoint has a stable REST surface with JSON envelopes, so any HTTP client works. Python and Go SDKs ship when there's enough signal from real users that it's worth maintaining them properly.
Who's building this?
A solo dev from Melbourne. I run it while running my own SaaS projects, which means: I use it before you do, I reply to bug reports personally, and I won't pivot it to enterprise. What I can't promise is a big team's response time — if you file a non-critical bug on a Saturday, it's Monday.
What happens if this project gets abandoned?
Your data sits in Cloudflare D1 + R2 — structured, exportable. If Paean winds down I commit to 90 days written notice, the final billing cycle refunded, and an export script targeting your own CF account. It's in the terms of service.
Before you go
Leave an email so you hear when it's ready.
The waitlist is the only way in right now. Paid tiers light up after the first group of invited users has run real workloads through it without anything falling over.