search and/or read your saved and liked bluesky posts
wails
go
svelte
sqlite
desktop
bluesky
1<!-- markdownlint-disable MD033 -->
2# bsky-browser
3
4A desktop app for searching your Bluesky bookmarks and likes.
5
6> I made this to stop having to `CTRL`/`CMD`+`F` and infinite scroll through my saved
7> and liked posts.
8
9## What It Does
10
11- Authenticates with Bluesky using loopback OAuth.
12- Stores session state, tokens, and DPoP metadata in a shared SQLite database.
13- Indexes bookmarks and likes into a local FTS5-backed search index.
14- Lets you browse recent indexed posts or search by text.
15- Renders rich-text facets for links, mentions, and hashtags.
16- Includes desktop-side refresh progress events and a frontend log viewer.
17
18## Screenshots
19
20
21
22
23
24
25
26
27
28
29
30## Usage
31
321. Launch the app.
332. Enter your Bluesky handle and complete OAuth in the browser.
343. Click `Refresh` to index bookmarks and likes.
354. Use the search box to run FTS queries, or leave it empty to browse recent posts.
365. Filter results by `All`, `Saved`, or `Liked`.
376. Click a row to open the original post on `bsky.app`.
38
39## Keyboard Shortcuts
40
41- `Cmd+K` or `Ctrl+K`: focus the search input
42- `Cmd+R` or `Ctrl+R`: refresh indexed data
43- `Cmd+L` or `Ctrl+L`: toggle the log viewer
44
45## Project
46
47### Requirements
48
49- Go
50- [Wails v2](https://wails.io/)
51- Node.js
52- `pnpm`
53
54### Install
55
56```bash
57git clone <your-repo-url>
58cd bsky-browser-gui
59pnpm --dir frontend install
60```
61
62If you prefer `task`, the same setup is available through:
63
64```bash
65task init
66```
67
68### Development
69
70Start the desktop app with hot reload:
71
72```bash
73wails dev
74```
75
76Or:
77
78```bash
79task dev
80```
81
82Useful checks:
83
84```bash
85go test ./...
86pnpm --dir frontend check
87```
88
89<details>
90<summary>OAuth and Local Data</summary>
91
92- OAuth callback URL: `http://127.0.0.1:8787/callback`
93- Default database path: `~/.config/bsky-browser/bsky-browser.db`
94- Default log directory: `~/.config/bsky-browser/logs/`
95
96You can override paths with:
97
98- `BSKY_BROWSER_DATA`
99- `BSKY_BROWSER_LOG`
100- `XDG_CONFIG_HOME`
101
102</details>
103
104<details>
105<summary>Project Structure</summary>
106
107- [app.go](/Users/owais/Desktop/bsky-browser-gui/app.go): app startup/shutdown wiring
108- [auth_service.go](/Users/owais/Desktop/bsky-browser-gui/auth_service.go): Bluesky OAuth flow and session refresh
109- [database.go](/Users/owais/Desktop/bsky-browser-gui/database.go): SQLite access, migrations, FTS search
110- [index_service.go](/Users/owais/Desktop/bsky-browser-gui/index_service.go): bookmark/like indexing
111- [search_service.go](/Users/owais/Desktop/bsky-browser-gui/search_service.go): Wails search bindings
112- [log_service.go](/Users/owais/Desktop/bsky-browser-gui/log_service.go): log event streaming
113- [frontend/src/App.svelte](/Users/owais/Desktop/bsky-browser-gui/frontend/src/App.svelte): main UI shell
114
115</details>
116
117<details>
118<summary>Notes</summary>
119
120- Session state is persisted so token refreshes and DPoP nonce updates survive app restarts.
121- Empty searches intentionally return recent posts instead of sending an invalid FTS wildcard query.
122
123</details>
124
125### Production Build
126
127Create a macOS app bundle:
128
129```bash
130wails build
131```
132
133Verified output:
134
135```text
136build/bin/bsky-browser-gui.app
137```
138
139Equivalent task:
140
141```bash
142task build
143```