@harveyrandall/bsky-cli
v1.6.1
Published
A CLI client for Bluesky
Downloads
723
Maintainers
Readme
bsky-cli
A command-line client for Bluesky, built with TypeScript.
Install
npm / yarn / pnpm / bun
Requires Node.js >= 22.
npm install -g @harveyrandall/bsky-cli
# or
yarn global add @harveyrandall/bsky-cli
# or
pnpm add -g @harveyrandall/bsky-cli
# or
bun add -g @harveyrandall/bsky-cliHomebrew (macOS / Linux)
brew install harveyrandall/bsky-cli/bsky-cliDownload a binary
Standalone binaries for macOS, Linux, and Windows are attached to every GitHub Release.
git clone https://github.com/harveyrandall/bsky-cli.git
cd bsky-cli
corepack enable
yarn install
yarn build
yarn link:global # registers `bsky` globallyTo uninstall:
yarn unlink:globalAuthentication
Interactive login
bsky login alice.bsky.social # prompts for password (hidden input)
bsky login alice.bsky.social mypassword # or pass directlyEnvironment variables
All configuration can be set via environment variables, useful for CI and scripts:
| Variable | Description |
|----------|-------------|
| BSKY_HANDLE | Bluesky handle |
| BSKY_PASSWORD | App password |
| BSKY_HOST | PDS host URL (default: https://bsky.social) |
| BSKY_BGS | BGS host URL (default: https://bsky.network) |
| BSKY_PROFILE | Profile name (same as --profile) |
Precedence: CLI args > environment variables > saved session.
# No login needed - authenticate directly from env
BSKY_HANDLE=alice.bsky.social BSKY_PASSWORD=secret bsky tlPiped input
echo "$APP_PASSWORD" | bsky login alice.bsky.socialMultiple accounts
Use --profile / -p to manage separate accounts:
bsky login alice.bsky.social -p personal
bsky login bob.bsky.social -p work
bsky tl -p personal
bsky tl -p work
bsky -p ? tl # list all profilesData storage
bsky-cli stores session tokens (never passwords) in platform-appropriate locations:
| Platform | Default path | Override |
|----------|-------------|----------|
| macOS | ~/Library/Application Support/bsky-cli/ | $XDG_CONFIG_HOME/bsky-cli/ |
| Linux | ~/.config/bsky-cli/ | $XDG_CONFIG_HOME/bsky-cli/ |
| Windows | %APPDATA%\bsky-cli\ | $XDG_CONFIG_HOME/bsky-cli/ |
Files stored:
session.json— session tokens (did, handle, accessJwt, refreshJwt) with0o600permissionssession-{profile}.json— per-profile sessionsdrafts/— locally saved drafts
Where available, session tokens are also stored in the OS keychain (macOS Keychain, GNOME Keyring/libsecret, Windows Credential Manager) with filesystem as fallback.
Passwords are never saved to disk. They are used only during bsky login
to obtain session tokens, then discarded from memory.
Commands
Feed
bsky timeline|tl [-H handle] [-n count]
bsky stream [--cursor] [-H handle] [--pattern regex] [--pattern-flags flags]
bsky thread <uri> [-n depth]Posting
bsky post <text> [--stdin] [-i image...] [--image-alt alt...] [--video path] [--video-alt alt]
bsky reply <uri> <text>
bsky quote <uri> <text>
bsky delete <uri...>Threads
bsky create-thread <text> [--stdin] [--thread-label] [--draft] [--no-preview]
[--split-on <marker>] [--skip-validation]Splits long text into a thread. Uses /// as the default manual split marker:
bsky create-thread "First post /// Second post /// Third post"
bsky create-thread "Part A --- Part B" --split-on "---"
bsky create-thread --stdin < essay.txt --thread-labelDrafts
bsky drafts list
bsky drafts show <id>
bsky drafts send <id>
bsky drafts delete <id>Engagement
bsky like <uri...>
bsky unlike <uri...>
bsky likes <uri>
bsky repost <uri...>
bsky remove-repost|unrepost <uri...>
bsky reposts <uri>Bookmarks
bsky bookmarks create <uri...>
bsky bookmarks delete <uri...>
bsky bookmarks get [-n count]Social
bsky follow <handle...>
bsky unfollow <handle...>
bsky follows [-H handle]
bsky followers [-H handle]
bsky block <handle...>
bsky unblock <handle...>
bsky blocks
bsky mute <handle...>Discovery
bsky search <terms...> [-n count]
bsky search-users <terms...> [-n count]Account
bsky profile [-H handle]
bsky profile-update [displayname] [description] [--avatar file] [--banner file]
bsky session
bsky notifs|notification [-a]
bsky invite-codes [--used]
bsky app-password list|add|revoke
bsky report <handle> [--comment text]
bsky mod-list <handles...> [--name] [--desc]Utilities
bsky completions bash|zsh|fishGlobal flags
| Flag | Description |
|------|-------------|
| --json | Output as JSON |
| -p, --profile <name> | Use a named profile |
| -v, --verbose | Verbose output |
| --version | Show version |
Shell completions
# Bash
bsky completions bash >> ~/.bashrc
# Zsh
bsky completions zsh >> ~/.zshrc
# Fish
bsky completions fish > ~/.config/fish/completions/bsky.fishDevelopment
yarn dev # run via tsx (no build needed)
yarn build # build to dist/
yarn typecheck # tsc --noEmit
yarn test:run # run tests once
yarn test:coverage # run tests with coverage
yarn link:global # build + register globally
yarn unlink:global # remove global symlinkSee CONTRIBUTING.md for the full contributor guide.
Roadmap
- [x] Threads with automatic and manual splitting
- [x] Drafts with offline sync and partial failure recovery
- [x] Secure credential storage (OS keychain + session tokens, no plaintext passwords)
- [ ] List creation and management
- [ ] Starter packs
- [ ] Moderation lists
- [ ] Post labels
- [ ] Auto alt-text for images and videos
- [ ] OAuth login support
- [ ] Docker BuildKit for standalone binary builds
