BugsTow
Issue trackers usually begin with an account and somebody else's server. BugsTow begins with a choice: keep issues in this browser for yourself, or run a small team server on your own computer and invite people over Wi-Fi or Tailscale.
- Type
- Local-first issue tracker
- State
- Active · v2.7.0
- Role
- Solo, end to end
- React 19
- TypeScript
- Vite
- Express
- SQLite
- better-auth
- Tailscale
At a glance
- Local browser storage or a self-hosted SQLite team server
- Single-use invites over Wi-Fi or Tailscale; no hosted relay
- Installer acceptance-tested on Windows, macOS and Linux
What I owned
Solo project. The Local and Team data models, React interface, Express and SQLite team server, invite and authentication flows, GitHub issue importer, cross-platform installer and launcher, backups, Tailscale sharing, and the end-to-end release checks.
Decisions, and what they cost
Local and Team are separate modes, not a hidden cloud sync
Local writes to IndexedDB in the current browser and needs no sign-in. Team writes to SQLite on the computer running BugsTow and gives each invited person a username and password. The same interface sits on top of both repositories, but switching modes never moves data behind the user's back; Copy Local issues is a deliberate migration step.
What I gave upThere is no magical shared state. Clearing browser data can remove Local issues, and Team only works while its host computer is reachable. Backups and an explicit copy flow make those boundaries visible instead of pretending they do not exist.
Invite links over LAN or Tailscale instead of a hosted relay
A Team workspace stays on one computer. People on the same network connect with --lan; people elsewhere connect through the owner's Tailscale network. Invite links are single-use, expire after seven days, and let the recipient choose a username and password without sending email or contacting a BugsTow service.
What I gave upThe host must stay on, and everyone invited to a workspace can see every project in it. Private work belongs in another workspace. That is less convenient than SaaS and much easier to reason about than a silent third-party copy.
The installer is tested as a product, not just a packaging script
The Windows, macOS and Linux installers bring a pinned Node.js runtime, verify the downloaded package checksum, create a launcher and start the app on localhost. CI builds the package on all three operating systems, installs it into a clean temporary home, runs the two-client acceptance flow, restarts it and checks that uninstall keeps the SQLite data.
What I gave upBundling a runtime makes the release larger and the installer matrix slower. In return, a user does not need Node.js, administrator rights or a manual server setup before capturing the first issue.
Where it went wrong
One interface, two storage boundaries
The difficult part was not rendering an issue list. It was keeping Local genuinely browser-only while Team used authenticated server data, then making mode switches, imports and backups explicit enough that a user could always tell where an issue lived. The repository layer and acceptance tests now pin that boundary.
Known limitations
- Data is not encrypted at rest. Anyone who controls the Team host can read its SQLite database, and Local data is readable from that browser profile.
- Clearing site data deletes Local issues unless they were backed up first.
- The Team host must be running and reachable; there is no BugsTow cloud relay or account recovery service.
- GitHub import needs internet access and is one-way. Editing an imported issue does not write back to GitHub.
Where it stands
v2.7.0 is released for Windows, macOS and Linux. It includes Local and Team modes, single-use invite links, explicit Local-to-Team copying, several workspaces, assignments, GitHub import, screenshots, prompt copying, daily Team backups and optional Tailscale sharing. Normal operation works offline after installation; CI checks the browser app, team server, a two-client acceptance path and the installer on all three operating systems.