subgraph.site

docs · users

Getting started

In under a minute: install the CLI, sign in with your handle, and upload your first item.

1. Install Bun

The @subgraph/cli is Bun-native. On macOS or Linux:

curl -fsSL https://bun.sh/install | bash

On Windows, use the PowerShell installer from bun.sh. Minimum: Bun 1.3.

2. Clone and install

The CLI isn't on npm yet. From source:

git clone <repo>/subgraph-site
cd subgraph-site
bun install

3. Sign in

From the repo root:

cd packages/cli
bun run src/index.ts login me.bsky.social

Your browser will open to your PDS's OAuth flow. Authenticate. You'll see a "Signed in. Close this tab." page; the CLI will show logged in as did:plc:…. Session tokens (DPoP-bound, refreshable) are stored at ~/.config/subgraph/session.json.

The sign-in flow uses an atproto OAuth 2.0 loopback redirect on 127.0.0.1:21849. If that port is in use, kill the other process and try again — this is a known limitation we'll fix with an ephemeral port.

4. Upload

Photos, video, audio, recipes, files — the CLI auto-detects the kind:

bun run src/index.ts upload ~/Photos/*.jpg --series "Joshua Tree, Spring 2026"
bun run src/index.ts upload ~/Videos/demo.mp4 --title "Demo"
bun run src/index.ts upload ~/audio/episode-001.mp3 --title "Episode 1"
bun run src/index.ts recipe publish ./tacos.md

5. Long-form articles

Articles write to site.standard.document — they need a publication container first:

subgraph pub init --name "My Blog" --url "https://example.com"
subgraph doc publish ./post.md

6. Other commands

subgraph whoami                         # show current identity
subgraph list                           # list your items
subgraph list series                    # list your series
subgraph series create "My trip" --publication at://...
subgraph delete at://did:plc:.../site.subgraph.item/<rkey>
subgraph logout                         # clear the session

Troubleshooting

  • Port 21849 in use — something (often a previous run) holds the loopback port. Find and kill: lsof -i :21849 then kill <pid>.
  • Sign-in timed out — the browser closed or the user cancelled before completing auth. Run subgraph login again.
  • "state mismatch on OAuth callback" — the callback URL carries a state value that doesn't match what we sent. This is CSRF protection working as intended; a stale browser tab or a concurrent sign-in attempt is the usual cause. Close any open OAuth tabs, retry.