basecamp / once-campfire-rust
git clone https://github.com/basecamp/once-campfire-rust.git
v0.1.2 · 23d ago
ONCE Campfire in Rust: one binary, the Rails app's data, 19–44× faster
+0
stars, 24h · #31,340
+~0
stars, 7 days · #31,815
+129
stars, 30 days · #3,860
129
★ total
25
forks · 6 open issues
Star history (as recorded here)
LanguageRust
LicenseMIT
Created2026-09-26 (26d ago)
Last push13d ago
Watchers1
OwnerOrganization
GitHub topics
Links
README excerpt
# Campfire in Rust A Rust implementation of ONCE Campfire. It uses the existing SQLite database, storage layout and signed/encrypted cookies, so existing installs can upgrade without migrating data or signing everyone out. One `campfire` executable replaces Ruby, Puma, Redis, Resque and Thruster, with libvips and ffmpeg for media. The Rails frontend ships with a few port-owned overrides. The app includes TLS, HTTP/2, Web Push, bot webhooks, search and Action Cable-compatible WebSockets. ## Running it With ONCE, on a server with Docker: [code] ONCE manages secrets, TLS, backups and upgrades. Or run Docker directly: [code] - `TLS_DOMAIN` enables automatic Let's Encrypt certificates; `DISABLE_SSL` enables plain HTTP. - `/rails/storage` holds the database, uploads, backups and certificates. Existing installs must keep their storage and secrets. - Web Push needs a valid P-256 VAPID key pair in URL-safe Base64. `VAPID_SUBJECT` sets the contact URL; its default is `https://` plus the first `TLS_DOMAIN`, or the project's URL. - The app listener on `TARGET_PORT` (3000) binds loopback. `TARGET_BIND` overrides this; that listener trusts `X-Forwarded-*` from whoever reaches it. Other settings are in `config.rs`. - Images support amd64 and arm64. `:latest` and version tags track releases; `:main` tracks the main branch. ## Performance Measured with 16 concurrent clients on an AMD Ryzen AI MAX+ 395 with 32 GB RAM, with four hardware cores allocated to each app. | HTTP workload (requests/sec) | Rails | Django | Laravel | Express | Elixir | Go | Rust | C | |---|---:|---:|---:|---:|---:|---:|---:|---:| | Room page | 4,101 | 1,507 | 3,872 | 42,636 | 5,350 | 53,060 | 106,494 | 137,524 | | Messages page | 4,115 | 1,596 | 3,995 | 74,362 | 5,712 | 54,800 | 102,697 | 144,642 | | Sidebar | 4,333 | 1,873 | 4,493 | 94,329 | 5,949 | 59,144 | 120,294 | 152,002 | | Search | 4,282 | 1,862 | 4,172 | 84,665 | 5,848 | 60,509 | 121,378 | 149,487 | | Post a message | 330 | 262 | 794 | 2,155 | 1,278 | 9,021 | 8,037 | 7,530 | | Backend KLOC | 5.5 | 5.3 | 4.1 | 6.8 | 11.6 | 23.2 | 30.7 | 94.8 | KLOC counts backend code plus executable code in templates; excludes plain HTML, frontend, tests, dependencies and generated files. Shared verification · Detailed results. Database scheduling, rich text rendering and cached-page gzip improvements contributed by Daniel Collin (emoon) in #43. ## Development Check out the `reference/` submodule before building. Rust 1.98.1 is available through mise; native media dependencies are specified in the `Dockerfile`. [code] Seed generation and parity checks need Docker. Tests without the seed skip app integration tests. For local development, run `cargo run -p campfire -- server` with `SECRET_KEY_BASE` set (or `SECRET_KEY_BASE_DUMMY=1`). Build an image with `docker build -t campfire-rust .`. The parity harness compares HTML, DOM, accessibility trees, assets, Cable frames and screenshots against Rails. See `parity/SCREENS.md` for coverage and m