- TypeScript 66.1%
- Go 21.8%
- CSS 8.4%
- Shell 1.7%
- HTML 1%
- Other 1%
| backend | ||
| frontend | ||
| stashbrowse | ||
| .gitignore | ||
| build.sh | ||
| deploy.sh | ||
| README.md | ||
| stashbrowse.service | ||
stashbrowse
Browse StashDB by combining tags, performers, and studios to discover scenes and send them to Whisparr in one click.
Disclaimer
This project was primarily coded using Claude. I don't really know how to code, especially in go. However, I used Claude to bring my idea to life so others can audit and build off of it.
Features
- Search and combine include / exclude filters for tags, performers, and studios
- Paginated scene grid with thumbnails, duration, studio, and performer badges
- Add to Whisparr directly from the browse or scene detail view
- Favorites list persisted to disk
- In-memory caching — repeated queries are instant
- Single self-contained binary (frontend embedded at build time)
Prerequisites
Installation
Option A — download a release binary
Download the latest binary for your platform from the Releases page, make it executable, and place it somewhere on your PATH:
install -m 755 stashbrowse ~/.local/bin/stashbrowse
Option B — build from source
Requirements: Go 1.22+, Node.js 18+
git clone <repo-url>
cd stashbrowse
# Build frontend
cd stashbrowse
npm install
npm run build
cd ..
# Embed frontend and build binary
cd backend
cp -r ../stashbrowse/build/client/. ui/
go build -o stashbrowse .
install -m 755 stashbrowse ~/.local/bin/stashbrowse
cd ..
Configuration
Run the interactive setup wizard to create your config file:
stashbrowse init
This prompts for:
| Field | Description |
|---|---|
| Config file path | Defaults to ~/.config/stashbrowse/config.toml |
| Server port | Defaults to 8585 |
| StashDB API key | From stashdb.org user settings |
| Whisparr URL | e.g. http://localhost:6969 |
| Whisparr API key | From Whisparr → Settings → General |
| Quality profile ID | Numeric ID of the quality profile to use |
| Root folder | Where Whisparr stores media, e.g. /data/media/xxx |
The resulting config looks like:
[server]
port = 8585
[stashdb]
api_key = "your-stashdb-key"
endpoint = "https://stashdb.org/graphql"
[whisparr]
url = "http://localhost:6969"
api_key = "your-whisparr-key"
quality_profile_id = 8
root_folder = "/data/media/xxx"
To use a non-default config path:
stashbrowse init --config /path/to/config.toml
stashbrowse --config /path/to/config.toml
Running
stashbrowse # reads ~/.config/stashbrowse/config.toml
stashbrowse serve # same, explicit subcommand
stashbrowse version # print version
stashbrowse --help # show usage
Open http://localhost:8585 in your browser.
Process supervisors
stashbrowse runs in the foreground and exits cleanly on SIGTERM / SIGINT, making it compatible with any process supervisor.
systemd (user service)
A unit file is included in the repo as stashbrowse.service.
# Install
cp stashbrowse.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now stashbrowse
# Manage
systemctl --user status stashbrowse
systemctl --user restart stashbrowse
journalctl --user -u stashbrowse -f
The unit uses %h (home directory) and expects the binary at ~/.local/bin/stashbrowse and the config at ~/.config/stashbrowse/config.toml.
dinit (user service)
Create ~/.config/dinit.d/stashbrowse:
type = process
command = /home/<user>/.local/bin/stashbrowse
restart = true
logfile = /home/<user>/.local/share/stashbrowse/stashbrowse.log
dinitctl start stashbrowse
s6-overlay / s6
Create a service directory, e.g. ~/.config/s6/sv/stashbrowse/:
mkdir -p ~/.config/s6/sv/stashbrowse
cat > ~/.config/s6/sv/stashbrowse/run <<'EOF'
#!/bin/sh
exec ~/.local/bin/stashbrowse
EOF
chmod +x ~/.config/s6/sv/stashbrowse/run
Deploying to a remote host
deploy.sh builds the frontend, embeds it into the Go binary, and rsyncs the single binary to a remote host named thor (override with env vars):
./deploy.sh
# Overrides
THOR_USER=myuser THOR_HOST=myserver THOR_DEST=/opt/stashbrowse ./deploy.sh
On first deploy, SSH into the server and run stashbrowse init to create the config, then start the service.
Development
# Terminal 1 — backend API server
cd backend
go run . --config ../config.dev.toml # create this with `go run . init`
# Terminal 2 — frontend dev server with HMR
cd stashbrowse
npm run dev # http://localhost:5173 (proxies /api → :8585)
Frontend changes hot-reload instantly. Backend changes require restarting go run ..