A TypeScript toolkit for consuming the Bluesky network in real-time.
README.md

Examples#

Runnable 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.

Prerequisites: Run npm install from the project root before running any example.


1. Hello Jetstream#

File: hello-jetstream.ts

The 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.

Use cases: Quick sanity check that Jetstream is reachable; understanding the event shape before using the lib's parsers.

npx tsx examples/hello-jetstream.ts

# Full JSON output
npx tsx examples/hello-jetstream.ts --raw

Press Ctrl+C to stop.


2. Hello Firehose#

File: hello-firehose.ts

Connects 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.

Use cases: Comparing the raw firehose format to Jetstream's simplified events; exploring non-post record types (likes, follows, blocks, etc.).

npx tsx examples/hello-firehose.ts

Press Ctrl+C to stop. Logs each commit's repo DID, operation, and collection.


3. Keyword Stream#

File: keyword-stream.ts

Streams 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.

Demonstrates: createJetstreamConnection, onMessageWithCursor, createCursorRef, attachLifecycleWithCursor, parsePost, highlightKeywords, formatKeywordPost.

Use cases: Real-time keyword monitoring; content moderation prototyping; watching trending topics.

# Single keyword
npx tsx examples/keyword-stream.ts bluesky

# Multiple keywords (matches posts containing ANY of them)
npx tsx examples/keyword-stream.ts bluesky atproto decentralized

# Multi-word phrase (quote it to keep it as one keyword)
npx tsx examples/keyword-stream.ts "Jersey City" "New York"

Press Ctrl+C to stop.


4. Post Lifecycle#

File: post-lifecycle.ts

Streams 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.

Demonstrates: parsePost, parsePostUpdate, parsePostDelete, toBskyUrl, cursor-based reconnection.

Use cases: Understanding how often posts are edited or deleted; studying post churn; building analytics on post operations.

# Default: prints updates & deletes, with periodic stats on create rate
npx tsx examples/post-lifecycle.ts

# Print everything (warning: very fast output)
npx tsx examples/post-lifecycle.ts --all

# Only edits
npx tsx examples/post-lifecycle.ts --updates-only

# Only deletes
npx tsx examples/post-lifecycle.ts --deletes-only

# Only creates
npx tsx examples/post-lifecycle.ts --creates-only

Press Ctrl+C to stop.


5. Identity Monitor#

File: identity-monitor.ts

Streams 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.

Demonstrates: parseIdentityEvent, parseAccountEvent, isIdentityEvent, isAccountEvent, cursor-based reconnection.

Use cases: Tracking handle changes across the network; monitoring account status transitions; studying network growth/churn.

npx tsx examples/identity-monitor.ts

Press Ctrl+C to stop. Identity events (handle changes) are relatively infrequent — account events are more common.


6. Profile Dashboard#

File: profile-dashboard.ts

Fetches 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.

Demonstrates: fetchResolveHandle, fetchGetProfile, fetchGetAuthorFeed, fetchGetFollowers, fetchGetFollows, parseAtUri, toBskyUrl.

Use cases: Quick user lookup; building profile summary tools; understanding the public API response shapes.

npx tsx examples/profile-dashboard.ts jay.bsky.team
npx tsx examples/profile-dashboard.ts bsky.app

Outputs a formatted card with bio, post/follower/following counts, and the 5 most recent posts with engagement stats and links.


7. Thread Explorer#

File: thread-explorer.ts

Fetches 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.

Demonstrates: fetchGetPostThread, fetchResolveHandle, parseAtUri, buildAtUri, toBskyUrl.

Use cases: Reading conversation threads in the terminal; exploring reply tree structure; debugging thread rendering logic.

# Using a bsky.app URL (handles are resolved automatically)
npx tsx examples/thread-explorer.ts https://bsky.app/profile/jay.bsky.team/post/3mffccqrpx22t

# Using an AT URI with a DID
npx tsx examples/thread-explorer.ts at://did:plc:oky5czdrnfjpqslsw2a5iclo/app.bsky.feed.post/3mffccqrpx22t

Copy 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.


8. Search Posts#

File: search-posts.ts

Searches 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).

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.

Quick setup:

# 1. Create an App Password at https://bsky.app/settings/app-passwords
# 2. Get an access JWT:
curl -s -X POST https://bsky.social/xrpc/com.atproto.server.createSession \
  -H "Content-Type: application/json" \
  -d '{"identifier":"your.handle","password":"your-app-password"}' \
  | jq -r .accessJwt
# 3. Export it:
export BSKY_AUTH_TOKEN="eyJ..."

Demonstrates: fetchSearchPosts, fetchGetLikes, fetchGetRepostedBy, fetchGetQuotes, toBskyUrl, getBskyAuthToken.

Use cases: Content discovery; research queries; studying engagement patterns on specific topics.

# Basic search
npx tsx examples/search-posts.ts "bluesky"

# With filters
npx tsx examples/search-posts.ts "typescript" --sort=latest --lang=en --limit=5

# Filter by author
npx tsx examples/search-posts.ts "atproto" --author=jay.bsky.team

# Filter by tags (repeatable)
npx tsx examples/search-posts.ts "bluesky" --tag=tech --tag=social

# Date range
npx tsx examples/search-posts.ts "launch" --since=2024-01-01T00:00:00Z --until=2024-02-01T00:00:00Z

# Detailed engagement (who liked/reposted/quoted each result)
npx tsx examples/search-posts.ts "bluesky" --limit=3 --engagement

9. User Feed#

File: user-feed.ts

The 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.

Demonstrates: fetchSearchActors, buildSearchActorsUrl, sendOptionsUpdate, createJetstreamConnection, onMessageWithCursor, attachLifecycleWithCursor, parsePost, formatUserPost, cursor-based reconnection.

Use cases: Monitoring a cohort of users in real-time; building targeted feeds; combining search with streaming.

# Search for users matching "developers" and stream their posts
npx tsx examples/user-feed.ts developers

# Custom page size
npx tsx examples/user-feed.ts artists 50

The 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.


10. Throughput Counter#

File: throughput.ts

A 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.

Demonstrates: startStreamWithReconnect, isPostCreate.

Use cases: Quick network activity check; benchmarking event throughput; understanding Bluesky post volume.

npx tsx examples/throughput.ts

Press Ctrl+C to stop. Output updates every second.


Library coverage#

These examples collectively exercise every public export from lib/:

Category Functions used
WebSocket createJetstreamConnection, onMessageWithCursor, createCursorRef, attachLifecycleWithCursor, sendOptionsUpdate, buildSearchActorsUrl, startStreamWithReconnect
Parsing parsePost, parsePostUpdate, parsePostDelete, parseIdentityEvent, parseAccountEvent, parseAtUri, buildAtUri, isPostCreate
Formatting toBskyUrl, highlightKeywords, formatKeywordPost, formatUserPost, formatPost
HTTP API fetchSearchActors, fetchResolveHandle, fetchGetProfile, fetchGetAuthorFeed, fetchGetPostThread, fetchGetFollowers, fetchGetFollows, fetchSearchPosts, fetchGetLikes, fetchGetRepostedBy, fetchGetQuotes