Platforms control your audience. Payment processors control your revenue. Bits gives you both back.
What you get:
- Subscriptions, one-time purchases, digital downloads
- Video hosting and delivery
- Your data, your domain, your rules
- Permissive content policies for persecuted creators
Why it works:
- Self-host on a $5/month VPS or use managed hosting
- Single binary deployment - no complex setup
- Built with care to minimize resource usage and maximize reliability
- Open source - audit the code, modify what you need, contribute back
The model: Like WordPress.org - free to self-host, managed option available. You’re never locked in.
Current state: Active development. Your funding accelerates delivery.
just cli --no-color --help 2>&1just setup # First time: generates certs, builds container images
just dev # Starts all services via Docker ComposeAll infrastructure runs in Docker containers (built with Nix). The just dev
command starts PostgreSQL, Datomic transactor, Jaeger, Traefik, the Clojure
nREPL, and Tailwind CSS watcher.
Subdomains of localhost automatically resolve to 127.0.0.1 per RFC 6761 —
no custom DNS resolver needed. Traefik terminates TLS with mkcert certificates.
The marketing site and “catch-all” homepage where we have no realm aren’t a priority so will return non-200 status codes.
urls=(
# These will work, provided you've applied the seeds in `bits.dev.realm`.
https://bits.page.localhost
https://charlie.bits.page.localhost
https://jcf.bits.page.localhost
)
for url in $urls; do
http_code="$(curl --silent --output /dev/null --write-out "%{http_code}" "$url")"
if [ "$http_code" -eq 200 ]; then
echo "✅ $url"
else
echo "❌ $url ($http_code)"
fi
doneAnd with a non-existent tenant, we expect a 404 response:
url="https://foo.bits.page.localhost"
http_code="$(curl --silent --output /dev/null --write-out "%{http_code}" "$url")"
if [ "$http_code" -eq 404 ]; then
echo "✅ $url"
else
echo "❌ $url ($http_code)"
fi- Get the message out
- Python-style environment variables
- Mission over SaaS startup playbook
- CI can wait
- Clojure over Rust
- Vanilla JS over ClojureScript for bits.js
- Crypto-Shredding for GDPR Compliance
- Datahike vs Datomic for distributed coordination
- Body-style indentation for UI component functions
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Language Files Lines Code Comments Blanks ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Astro 10 165 139 0 26 Clojure 66 6751 5330 505 916 CSS 2 84 69 4 11 Dockerfile 1 82 58 7 17 Edn 2 136 121 1 14 HCL 12 386 320 13 53 JavaScript 5 305 250 20 35 JSON 4 59 59 0 0 Just 1 292 181 61 50 MDX 1 56 0 39 17 Nix 11 1131 861 122 148 Org 15 2335 2039 5 291 SQL 4 43 37 0 6 SVG 2 12 12 0 0 TOML 1 43 38 0 5 TypeScript 3 36 30 1 5 XML 1 18 14 1 3 YAML 3 5073 3988 0 1085 ───────────────────────────────────────────────────────────────────────────────── HTML 1 76 72 0 4 |- CSS 1 171 151 0 20 (Total) 247 223 0 24 ───────────────────────────────────────────────────────────────────────────────── Markdown 1 404 0 266 138 |- Clojure 1 238 152 50 36 |- Org 1 19 12 0 7 |- Rust 1 68 49 10 9 |- YAML 1 1 1 0 0 (Total) 730 214 326 190 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ Total 146 17984 13983 1105 2896 ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 83a623b @ 2026/02/26 23:46
src/bits/app.clj:;; TODO Use Malli (or clojure.spec) to coerce and parse/validate configuration. src/bits/asset.clj:;; TODO Make content-type explicit or more intelligent. src/bits/brotli.clj: ;; TODO: Default buffer size for brotli library, needs to be tuned. src/bits/middleware.clj: ;; TODO Rename :sid to :session/id src/bits/module/creator.clj: ;; TODO: Real data from database src/bits/module/creator.clj: ;; TODO Extract platform/realm domain src/bits/morph.clj:;; FIXME Relocate `morphable`. src/bits/schema.clj: ;; FIXME Avoid stringly typed entities - use `:db/ident`. src/bits/ui.clj: ;; TODO: I18n - error presentation test/bits/session_test.clj: ;; FIXME Remove `:sid` from `data`.