A TypeScript toolkit for consuming the Bluesky network in real-time.
1# Examples
2
3Runnable scripts demonstrating every major feature of the library — from minimal WebSocket connections to rich CLI dashboards. All examples use `npx tsx` and require no authentication unless noted.
4
5> **Prerequisites**: Run `npm install` from the project root before running any example.
6
7---
8
9## 1. Hello Jetstream
10
11**File**: `hello-jetstream.ts`
12
13The simplest possible Jetstream connection. Connects to the Bluesky firehose via the `@skyware/jetstream` package (a high-level wrapper) and logs post events as they arrive. Shows author DID, text, and language by default.
14
15**Use cases**: Quick sanity check that Jetstream is reachable; understanding the event shape before using the lib's parsers.
16
17```sh
18npx tsx examples/hello-jetstream.ts
19
20# Full JSON output
21npx tsx examples/hello-jetstream.ts --raw
22```
23
24Press `Ctrl+C` to stop.
25
26---
27
28## 2. Hello Firehose
29
30**File**: `hello-firehose.ts`
31
32Connects to the AT Protocol firehose directly using `@atproto/sync`. This is the low-level counterpart to Hello Jetstream — it shows the raw repo commit stream before Jetstream normalises it.
33
34**Use cases**: Comparing the raw firehose format to Jetstream's simplified events; exploring non-post record types (likes, follows, blocks, etc.).
35
36```sh
37npx tsx examples/hello-firehose.ts
38```
39
40Press `Ctrl+C` to stop. Logs each commit's repo DID, operation, and collection.
41
42---
43
44## 3. Keyword Stream
45
46**File**: `keyword-stream.ts`
47
48Streams live Bluesky posts and filters them by one or more keywords passed on the command line. Highlights matched keywords in the output. Reconnects automatically with cursor-based replay so no events are lost during brief disconnects.
49
50**Demonstrates**: `createJetstreamConnection`, `onMessageWithCursor`, `createCursorRef`, `attachLifecycleWithCursor`, `parsePost`, `highlightKeywords`, `formatKeywordPost`.
51
52**Use cases**: Real-time keyword monitoring; content moderation prototyping; watching trending topics.
53
54```sh
55# Single keyword
56npx tsx examples/keyword-stream.ts bluesky
57
58# Multiple keywords (matches posts containing ANY of them)
59npx tsx examples/keyword-stream.ts bluesky atproto decentralized
60
61# Multi-word phrase (quote it to keep it as one keyword)
62npx tsx examples/keyword-stream.ts "Jersey City" "New York"
63```
64
65Press `Ctrl+C` to stop.
66
67---
68
69## 4. Post Lifecycle
70
71**File**: `post-lifecycle.ts`
72
73Streams post events from the Bluesky network, focusing on the interesting ones: edits and deletes. Creates are counted silently and shown in a periodic stats summary (posts/sec, total counts) every 10 seconds. Use `--all` to print every create too.
74
75**Demonstrates**: `parsePost`, `parsePostUpdate`, `parsePostDelete`, `toBskyUrl`, cursor-based reconnection.
76
77**Use cases**: Understanding how often posts are edited or deleted; studying post churn; building analytics on post operations.
78
79```sh
80# Default: prints updates & deletes, with periodic stats on create rate
81npx tsx examples/post-lifecycle.ts
82
83# Print everything (warning: very fast output)
84npx tsx examples/post-lifecycle.ts --all
85
86# Only edits
87npx tsx examples/post-lifecycle.ts --updates-only
88
89# Only deletes
90npx tsx examples/post-lifecycle.ts --deletes-only
91
92# Only creates
93npx tsx examples/post-lifecycle.ts --creates-only
94```
95
96Press `Ctrl+C` to stop.
97
98---
99
100## 5. Identity Monitor
101
102**File**: `identity-monitor.ts`
103
104Streams identity events (handle changes) and account events (activation, deactivation, suspension, deletion) from the network in real-time. These are non-commit events that most examples ignore.
105
106**Demonstrates**: `parseIdentityEvent`, `parseAccountEvent`, `isIdentityEvent`, `isAccountEvent`, cursor-based reconnection.
107
108**Use cases**: Tracking handle changes across the network; monitoring account status transitions; studying network growth/churn.
109
110```sh
111npx tsx examples/identity-monitor.ts
112```
113
114Press `Ctrl+C` to stop. Identity events (handle changes) are relatively infrequent — account events are more common.
115
116---
117
118## 6. Profile Dashboard
119
120**File**: `profile-dashboard.ts`
121
122Fetches a user's profile, recent posts, and social graph stats, then renders a formatted dashboard in the terminal. Demonstrates multiple HTTP API calls composed together.
123
124**Demonstrates**: `fetchResolveHandle`, `fetchGetProfile`, `fetchGetAuthorFeed`, `fetchGetFollowers`, `fetchGetFollows`, `parseAtUri`, `toBskyUrl`.
125
126**Use cases**: Quick user lookup; building profile summary tools; understanding the public API response shapes.
127
128```sh
129npx tsx examples/profile-dashboard.ts jay.bsky.team
130npx tsx examples/profile-dashboard.ts bsky.app
131```
132
133Outputs a formatted card with bio, post/follower/following counts, and the 5 most recent posts with engagement stats and links.
134
135---
136
137## 7. Thread Explorer
138
139**File**: `thread-explorer.ts`
140
141Fetches a post thread and renders it as an indented tree — parent chain above, replies below. Accepts either a `bsky.app` URL or a raw AT URI.
142
143**Demonstrates**: `fetchGetPostThread`, `fetchResolveHandle`, `parseAtUri`, `buildAtUri`, `toBskyUrl`.
144
145**Use cases**: Reading conversation threads in the terminal; exploring reply tree structure; debugging thread rendering logic.
146
147```sh
148# Using a bsky.app URL (handles are resolved automatically)
149npx tsx examples/thread-explorer.ts https://bsky.app/profile/jay.bsky.team/post/3mffccqrpx22t
150
151# Using an AT URI with a DID
152npx tsx examples/thread-explorer.ts at://did:plc:oky5czdrnfjpqslsw2a5iclo/app.bsky.feed.post/3mffccqrpx22t
153```
154
155Copy any post URL from bsky.app and paste it as the argument. Renders the parent chain (if any), the target post marked with `>>>`, and replies indented beneath.
156
157---
158
159## 8. Search Posts
160
161**File**: `search-posts.ts`
162
163Searches Bluesky posts with rich filtering options — sort order, language, author, tags, date range — and displays results with engagement stats. Optionally fetches detailed engagement (who liked, reposted, quoted).
164
165> **Requires authentication.** The `searchPosts` API endpoint is not available on the public API. You need a `BSKY_AUTH_TOKEN` env var set to a valid access JWT. The script will print setup instructions if the token is missing.
166>
167> Quick setup:
168> ```sh
169> # 1. Create an App Password at https://bsky.app/settings/app-passwords
170> # 2. Get an access JWT:
171> curl -s -X POST https://bsky.social/xrpc/com.atproto.server.createSession \
172> -H "Content-Type: application/json" \
173> -d '{"identifier":"your.handle","password":"your-app-password"}' \
174> | jq -r .accessJwt
175> # 3. Export it:
176> export BSKY_AUTH_TOKEN="eyJ..."
177> ```
178
179**Demonstrates**: `fetchSearchPosts`, `fetchGetLikes`, `fetchGetRepostedBy`, `fetchGetQuotes`, `toBskyUrl`, `getBskyAuthToken`.
180
181**Use cases**: Content discovery; research queries; studying engagement patterns on specific topics.
182
183```sh
184# Basic search
185npx tsx examples/search-posts.ts "bluesky"
186
187# With filters
188npx tsx examples/search-posts.ts "typescript" --sort=latest --lang=en --limit=5
189
190# Filter by author
191npx tsx examples/search-posts.ts "atproto" --author=jay.bsky.team
192
193# Filter by tags (repeatable)
194npx tsx examples/search-posts.ts "bluesky" --tag=tech --tag=social
195
196# Date range
197npx tsx examples/search-posts.ts "launch" --since=2024-01-01T00:00:00Z --until=2024-02-01T00:00:00Z
198
199# Detailed engagement (who liked/reposted/quoted each result)
200npx tsx examples/search-posts.ts "bluesky" --limit=3 --engagement
201```
202
203---
204
205## 9. User Feed
206
207**File**: `user-feed.ts`
208
209The most complex example. Searches for Bluesky users matching a query, paginates through results, then opens a live stream filtered to only those users' posts. Combines HTTP search with real-time WebSocket streaming.
210
211**Demonstrates**: `fetchSearchActors`, `buildSearchActorsUrl`, `sendOptionsUpdate`, `createJetstreamConnection`, `onMessageWithCursor`, `attachLifecycleWithCursor`, `parsePost`, `formatUserPost`, cursor-based reconnection.
212
213**Use cases**: Monitoring a cohort of users in real-time; building targeted feeds; combining search with streaming.
214
215```sh
216# Search for users matching "developers" and stream their posts
217npx tsx examples/user-feed.ts developers
218
219# Custom page size
220npx tsx examples/user-feed.ts artists 50
221```
222
223The script first fetches all matching users (paginating through results), then connects to Jetstream filtered to those users' DIDs. Press `Ctrl+C` to stop the stream.
224
225---
226
227## 10. Throughput Counter
228
229**File**: `throughput.ts`
230
231A minimal real-time throughput meter. Connects to Jetstream filtered to posts and counts post creates per second, printing the current rate and a running total every second.
232
233**Demonstrates**: `startStreamWithReconnect`, `isPostCreate`.
234
235**Use cases**: Quick network activity check; benchmarking event throughput; understanding Bluesky post volume.
236
237```sh
238npx tsx examples/throughput.ts
239```
240
241Press `Ctrl+C` to stop. Output updates every second.
242
243---
244
245## Library coverage
246
247These examples collectively exercise every public export from `lib/`:
248
249| Category | Functions used |
250|----------|---------------|
251| **WebSocket** | `createJetstreamConnection`, `onMessageWithCursor`, `createCursorRef`, `attachLifecycleWithCursor`, `sendOptionsUpdate`, `buildSearchActorsUrl`, `startStreamWithReconnect` |
252| **Parsing** | `parsePost`, `parsePostUpdate`, `parsePostDelete`, `parseIdentityEvent`, `parseAccountEvent`, `parseAtUri`, `buildAtUri`, `isPostCreate` |
253| **Formatting** | `toBskyUrl`, `highlightKeywords`, `formatKeywordPost`, `formatUserPost`, `formatPost` |
254| **HTTP API** | `fetchSearchActors`, `fetchResolveHandle`, `fetchGetProfile`, `fetchGetAuthorFeed`, `fetchGetPostThread`, `fetchGetFollowers`, `fetchGetFollows`, `fetchSearchPosts`, `fetchGetLikes`, `fetchGetRepostedBy`, `fetchGetQuotes` |