Clients
One typed backend behind a web app, a desktop app, and three public sites.
The problem
Most starters give you one frontend. The day you need a desktop app or a public site, you find out how much of your auth and API setup assumed a single browser tab.
What Bones does
| Client | Built with | Auth |
|---|---|---|
web-app — the auth-gated app | Vite and React | Session cookie |
desktop — the same app, native | Tauri, Vite, and React | Bearer token |
web-static — the marketing site | Next.js, prerendered | None |
blog | Next.js, static export | None |
docs | Next.js and Fumadocs, static export | None |
All of them call the same backend. The apps call it through tRPC with full types, so a renamed field breaks the build rather than production.
The desktop app is a real second app, not a wrapper. It has its own routes and its own build. That's deliberate: it proves routing, styling, and auth work a second, independent way. Google sign-in opens the system browser and hands a token back through a bones:// link.
Shared pieces live in shared-ui. Components move there once a second app needs them. Whole pages stay in each app.
How it compares
Electron would let the desktop app reuse the web build directly, at the cost of shipping a whole Chromium per install. Tauri uses the operating system's own webview, so the app is a fraction of the size.