Getting Started
From install to a fully populated workspace in about 10 minutes. Every command is copy-pasteable and shows the expected output.
Core concepts
A few terms show up in every command below. Here's the short version; the Core Concepts page covers each one in full.
| Term | What it is |
|---|---|
| Workspace | A directory holding a backlog.db (and a config.toml). Every project, task, plan, and comment lives in that one SQLite file. Created by backlog init. |
| Profile | A named pointer to a workspace, registered in ~/.config/backlog/config.toml, so you can switch workspaces without typing paths. |
| Project | A named group of tasks inside a workspace, identified by a short alias (e.g. api), the alias is what you pass to -p / --project. |
| Task | The unit of work. Has a type, status, priority, and actor; addressed as TASK-N. |
| Plan | A versioned markdown document attached to a task. Every edit creates a new immutable version. |
| Comment | An append-only, actor-attributed note on a task. |
| Label | A per-project tag for filtering tasks. |
| Doc | A versioned markdown document attached to a project (not a task): runbooks, ADRs, design notes. |
| Memory | A free-form, taggable, mutable note for cross-session agent context. |
| Actor | The human:name or ai:name attributed to every write. |
Install
Requirements: Go 1.22+. No CGO. No external runtime dependencies.
go install github.com/mazen160/backlog/cmd/backlog@latest
Or download a pre-built binary from GitHub Releases:
curl -L https://github.com/mazen160/backlog/releases/latest/download/backlog_darwin_arm64.tar.gz | tar xz
sudo mv backlog /usr/local/bin/
curl -L https://github.com/mazen160/backlog/releases/latest/download/backlog_linux_amd64.tar.gz | tar xz
sudo mv backlog /usr/local/bin/
Confirm the install:
backlog version
backlog v1.0.3
Initialize a workspace
By default backlog init creates the workspace under ~/.backlog/<profile>. To keep it next to your code instead, pass --path:
backlog init --path ./my-project
cd my-project
✓ workspace initialized: /Users/alice/my-project (profile: "default") [default]
This registers a profile named default and writes two files into the workspace:
| File | Purpose |
|---|---|
backlog.db | SQLite database: all tasks, projects, plans, comments, labels |
config.toml | Local workspace settings: default actor, project, and output format |
init does not create a backlog.json. That file is an optional, hand-authored project manifest: you write it yourself (or commit it with your repo), and backlog sync reads it to create any listed projects that don't exist yet in the database. Sync is one-way (manifest → database) and never deletes.
backlog.db to your repository so your team (and any AI agents working alongside you) share the same backlog. Add a backlog.json manifest too if you want project definitions tracked in plain text and reconciled with backlog sync.
To create a named workspace for use across directories, pass --profile:
backlog init --profile work # creates ~/.backlog/work/backlog.db
backlog init --path ~/projects/api # custom path
Create a project
A project groups tasks under a short alias, the identifier you type in every other command.
backlog project add "API Service" --alias api --repo-path /code/api
ID: 01KR4H1TMRW3QAZ7D274SYCRJ1
Alias: api
Name: API Service
Repo: /code/api
Created: 2026-05-08 12:29
backlog project add "Web Frontend" --alias web
backlog project list
ALIAS │ NAME │ REPO │ CREATED
───────┼──────────────┼───────────┼──────────────────
api │ API Service │ /code/api │ 2026-05-08 12:29
web │ Web Frontend │ │ 2026-05-08 12:29
Set a default project so you can omit -p from most commands:
backlog project set-default api
Create tasks
backlog task add --project api --title "Fix login timeout" --type bug --priority P2
ID: 01KR4H1ZYWGC3BQK01YBMM94P0
Project: api
Title: Fix login timeout
Type: bug
Status: todo
Priority: P2
Actor: human:alice
Created: 2026-05-08 12:29
The actor defaults to human:$USER. Pass --as to override:
backlog task add \
--project api \
--title "Reject unsigned JWTs in auth middleware" \
--type vulnerability \
--priority P1 \
--source "security-review-2026-Q1" \
--as human:alice
List open tasks:
backlog task list
ID │ P │ TYPE │ STATUS │ TITLE │ PROJECT │ LABELS │ ACTOR
──────────┼────┼───────────────┼────────┼─────────────────────────────────────┼─────────┼────────┼───────
01KR4H1Z │ P1 │ vulnerability │ todo │ Reject unsigned JWTs in auth middl… │ api │ │ alice
01KR4H1Z │ P2 │ bug │ todo │ Fix login timeout │ api │ │ alice
The ID column shows the first 8 characters of the ULID. You can use the prefix, the full ULID, or TASK-N interchangeably.
Move through the lifecycle
backlog task move TASK-1 --status doing
backlog task move TASK-1 --status done
All status transitions are valid in any direction:
todo → doing → done
↑___________|
Attach a plan
Plans are versioned markdown documents. Every edit creates an immutable new version, and old versions are always readable.
backlog plan add \
--task TASK-1 \
--title "Fix unsigned JWT rejection" \
--content "## Steps
1. Extract JWT from Authorization header
2. Verify RS256 signature with JWKS endpoint
3. Return 401 on missing, malformed, or unsigned tokens
4. Add unit tests with forged tokens" \
--as ai:claude-code
A human reviews and revises:
PLAN_ID="01KR4H25J062ANP3ZN6Z6GFDCM"
backlog plan update "$PLAN_ID" \
--title "Fix unsigned JWT rejection (revised)" \
--content "## Steps
1. Extract JWT from Authorization header
2. Verify RS256 signature with JWKS endpoint
3. Return 401 on missing, malformed, or unsigned tokens
4. Add unit tests with forged tokens
5. Rotate the signing key — current key may be compromised" \
--change-note "added key rotation after security review" \
--as human:alice
View version history:
backlog plan history "$PLAN_ID"
VER │ TITLE │ ACTOR │ NOTE │ CREATED
─────┼──────────────────────────────────────┼────────────────┼──────────────────────────────────────────┼──────────────────
v1 │ Fix unsigned JWT rejection │ ai:claude-code │ │ 2026-05-08 12:29
v2 │ Fix unsigned JWT rejection (revised) │ human:alice │ added key rotation after security review │ 2026-05-08 12:29
Add comments
backlog comment add --task TASK-1 \
"JWKS endpoint is at /auth/.well-known/jwks.json — tested, returns correct keys."
backlog comment add --task TASK-1 \
"Got it. Should we cache the keys?" \
--as ai:claude-code
backlog comment add --task TASK-1 \
"Yes — 1hr TTL, re-fetch on key-ID miss." \
--as human:alice
backlog task show TASK-1 --with-plans --with-comments
--- Comments (3) ---
2026-05-08 12:30 [human:alice]: JWKS endpoint is at /auth/.well-known/jwks.json — tested.
2026-05-08 12:30 [ai:claude-code]: Got it. Should we cache the keys?
2026-05-08 12:30 [human:alice]: Yes — 1hr TTL, re-fetch on key-ID miss.
Organize with labels
backlog label create --project api "security" --color "#e03e3e"
backlog label create --project api "auth"
backlog label attach --task TASK-1 security
backlog label attach --task TASK-1 auth
backlog task list --label auth
Bulk import from a scanner
Create a findings file, suitable for output from security scanners, AI triage agents, or any structured source:
{
"version": 1,
"project": "api",
"items": [
{
"title": "SQL injection in /users search endpoint",
"type": "vulnerability",
"priority": "P1",
"source": "semgrep",
"external_ref": "SEMGREP-001",
"plans": [
{
"title": "Remediation",
"body": "Replace string interpolation with parameterized queries."
}
]
},
{
"title": "Hardcoded credentials in config sample",
"type": "vulnerability",
"priority": "P2",
"source": "semgrep",
"external_ref": "SEMGREP-002"
},
{
"title": "Outdated dependency: golang.org/x/net (CVE-2023-44487)",
"type": "vulnerability",
"priority": "P3",
"source": "dependency-scan"
}
]
}
# Dry run to preview
backlog import-findings findings.json --dry-run
[dry-run] imported 3 tasks · 1 plans · 0 errors
backlog import-findings findings.json --as ai:semgrep
Search and filter
# Full-text search (FTS5)
backlog task list --search "injection"
backlog task list --search "sql*" # prefix match
backlog task list --search "jwt OR csrf" # boolean OR
# Combine filters
backlog task list --project api --type vulnerability --priority P1
backlog task list --actor-kind ai # tasks created by AI agents
backlog task list --source semgrep # tasks from a specific tool
backlog task list --status doing # in-progress only
Export
backlog export --format json # machine-readable
backlog export --format csv --out tasks.csv # spreadsheets
backlog export --format md # paste into PRs / reports
Open the web UI
The embedded web UI runs entirely from the binary, no additional setup:
backlog web # opens http://localhost:8080 in browser
backlog web --port 3000 # custom port
backlog web --port 3000 --no-browser # don't auto-open
The web UI provides list, Kanban, and grid task views, versioned docs, memory entries, attachments, and an activity timeline. All API endpoints are also usable directly. See the API reference.
Connect an AI assistant
Start the MCP stdio server so an AI coding assistant can read and write your backlog directly, without CLI invocations:
backlog mcp serve --as ai:claude-code
BACKLOG_DB so the server always finds the right workspace), see the MCP guide.