A decentralized, self-hosted community platform.
Every feature. Free forever. Your data, your server.
Pufferblow lets you run your own Discord-like community server — text channels, voice rooms, roles, bots, federation — without subscriptions, paywalls, or someone else's terms of service. Each instance is independent. Users are identified as username@your-domain.tld. Instances can federate with each other by invitation.
| Repo | What it is |
|---|---|
| pufferblow | Instance backend — FastAPI, PostgreSQL, WebSocket, federation, media SFU |
| client | Web + desktop app — React 18, Vite 5, TypeScript, Tauri 2 (Windows / macOS / Linux) |
| pufferblow-py | Python bot SDK — decorator-based, FastAPI-style event routing |
| media-sfu | Go WebRTC selective forwarding unit — voice channels, scope-enforced |
| pufferblow-updater | Stub installer + bootstrapper — GitHub Releases-based auto-update, no update server required |
Messaging Real-time text channels with message history, file attachments, reactions, and stickers. Direct messages and group DMs. Full-text search across your instance.
Voice
Low-latency WebRTC voice channels powered by the Go media SFU. Per-user scope enforcement (send_audio, send_video, recv). Server-side mute and kick. Up to 100 participants per room, 1000 concurrent across the instance.
Communities Channels organized into categories. Role-based permissions with a 13-flag bitmask. Invite links. Full audit log. Slash commands and bot support via the Python SDK.
Federation
Instances connect to each other by invitation. Users on federated instances can join channels and appear in member lists as username@remote.tld. Federation can be enabled, disabled, or restricted from the admin panel.
Self-hosted, no strings Every feature ships with the server. No tiers, no premium upgrades, no data leaving your machine. Storage is local filesystem. The only external dependency is an SMTP server for email verification, which is optional.
Desktop app
The Tauri client ships as a native app on Windows (.msi / NSIS), macOS (.dmg, Intel + Apple Silicon), and Linux (.deb / .AppImage). OS keychain integration, system tray, native notifications. Auto-updates via GitHub Releases — no update server required.
| Layer | Technology |
|---|---|
| Backend API | Python 3.12, FastAPI, PostgreSQL 16, Memcached |
| Real-time | WebSockets (native FastAPI) |
| Voice | Go, Pion WebRTC v4 |
| Web client | React 18, Vite 5, TypeScript, Zustand |
| Desktop client | Tauri 2, Rust |
| Bot SDK | Python 3.10+, httpx, asyncio |
| Auth | JWT, bcrypt, email token verification |
| Storage | Local filesystem |
The fastest way to run an instance is with Docker Compose:
git clone https://github.com/pufferblow/pufferblow
cd pufferblow
cp config.example.toml config.toml # fill in bootstrap_secret, db credentials, domain
docker compose up -dThe stack starts four containers: the FastAPI backend, the Go media SFU, PostgreSQL, and Memcached. An nginx reverse proxy handles TLS termination and routes /sfu/ws to the SFU WebSocket port — the SFU admin API is never publicly reachable.
For a full walkthrough including domain setup, SMTP configuration, and federation, see the deployment guide.
from pufferblow_py import Bot, Context
bot = Bot(token="your-bot-token", instance="https://your-instance.tld")
@bot.command("ping")
async def ping(ctx: Context):
await ctx.reply("Pong!")
bot.run()Full documentation is in the pufferblow-py repo.
Users are addressed as username@instance-domain.tld. This means:
- You own your identity — it lives on your server
- You can join federated communities on other instances without creating a new account
- Instance admins can see only their own users' data
All repos follow the same conventions. Check the CONTRIBUTING.md in the relevant repo before opening a PR. Issues and discussions are welcome in any repo — if you're unsure where something belongs, open it here.
Pufferblow is released under the AGPL-3.0 License. If you run a modified version of Pufferblow as a network service, you must make your modifications available under the same license.