A kanban board that overlays GitHub Projects v2, providing both a web UI and a terminal UI for managing issues and pull requests across repositories.
- Rust 1.85+ (edition 2024)
- GitHub Personal Access Token with
repoandprojectscopes - trunk (for building the web frontend):
cargo install trunk - wasm32 target (for the frontend):
rustup target add wasm32-unknown-unknown
A GitHub Personal Access Token (PAT) is required for all GitHub API operations.
Creating a Classic token (recommended for simplicity):
- Go to github.com > Settings > Developer settings > Personal access tokens > Tokens (classic)
- Click Generate new token (classic)
- Name it (e.g., "git-kanban")
- Select these scopes:
repo— read/write access to issues, pull requests, and repository metadataproject— read/write access to GitHub Projects v2 (required for board sync, card movement, and all GraphQL operations)
- Click Generate token and copy it immediately (it won't be shown again)
Classic tokens are prefixed with ghp_.
Fine-grained tokens (prefixed github_pat_) also work but require more granular permission setup:
- Repository permissions: Issues (Read and write), Pull requests (Read and write), Metadata (Read)
- Organization permissions: Projects (Read and write) — for org-level projects
- Account permissions: Projects (Read and write) — for user-level projects
Set your token via environment variable:
export GITHUB_TOKEN=ghp_yourtokenOr create a config file at ~/.git-kanban/config.toml:
[github]
token = "ghp_yourtoken"
[server]
host = "0.0.0.0"
port = 3000
[database]
path = "sqlite:git-kanban.db?mode=rwc"Configuration precedence: environment variables > config file > defaults.
| Variable | Default | Description |
|---|---|---|
GITHUB_TOKEN |
(none) | GitHub Personal Access Token |
DATABASE_URL |
sqlite:git-kanban.db?mode=rwc |
SQLite database path |
GIT_KANBAN_HOST |
0.0.0.0 |
Web server bind address |
GIT_KANBAN_PORT |
3000 |
Web server port |
RUST_LOG |
git_kanban_web=debug,git_kanban_core=debug |
Log level filter |
git-kanban manages repositories through GitHub Projects v2. Each repository you want to track must have a project board configured on GitHub before git-kanban can sync it.
GitHub Projects v2 is a project-management layer that sits on top of a repository's issues and pull requests. git-kanban uses it as the source of truth for columns and card positions. Here is how to create one:
-
Go to your repository on GitHub (e.g.,
github.com/hughdbrown/who-is-hiring). In the top navigation bar you will see tabs for Code, Issues, Pull requests, Actions, Projects, Security, and Insights: -
Click the Projects tab. If the repository has no projects yet, you will see "No open projects":
-
When logged in as the repository owner, you will see a green Link a project button in the top-right area of this page. Click it
-
In the dropdown that appears, click New project (at the bottom of the dropdown)
-
GitHub opens the "Create a new project" dialog. You will see several templates:
- Table — spreadsheet-like view
- Board — kanban-style columns (recommended, but any template works)
- Roadmap — timeline view
- Start from scratch — blank project
-
Select Board and click Create
-
GitHub creates the project and opens it. The project is automatically linked to your repository
What you get by default: Every new project includes a Status field of type "Single select" with three options: Todo, In Progress, and Done. git-kanban reads these options as kanban columns. You do not need to change them, but you can customize them:
- Click the ... menu at the top-right of the project board, then Settings
- Under Custom fields, click the Status field
- Add, rename, reorder, or remove options (e.g., add "Backlog" or "Review")
- Each option becomes a column in git-kanban
Important: git-kanban specifically looks for a field named "Status" of type "Single select". If you rename the Status field or delete it, git-kanban will not be able to find columns and will return a "Status field not found" error.
Issues and pull requests must be added to the GitHub project to appear on the git-kanban board. There are several ways to do this:
From the project board:
- At the bottom of any column, click the + Add item field
- Type
#to search for existing issues in the repository, or type text to create a draft item - Select an issue from the search results to add it to that column
From an issue or pull request page:
- Open the issue on GitHub
- In the right sidebar, find the Projects section
- Click the gear icon or Projects and select your project from the list
- The issue appears in the project's "Todo" column by default
From git-kanban itself: You can create issues directly through git-kanban's web UI, TUI, or API. These are automatically added to the project and placed in the selected column.
Start the git-kanban web server, then add the board using either the web UI or the API:
Web UI: Click "Add Board", enter the owner (e.g., yourname) and repo name (e.g., your-repo). Do not include .git in the repo name.
API:
curl -X POST http://localhost:3000/api/boards \
-H 'Content-Type: application/json' \
-d '{"owner": "yourname", "repo": "your-repo"}'If the repository has multiple projects, you'll be prompted to select one (web UI) or can specify "project_number": 1 in the API request.
- Must have at least one GitHub Projects v2 board (classic Projects are not supported)
- The project must have a Status field of type Single select (this is the default for new projects)
- Your GitHub token must have access to the repository (
reposcope) and projects (projectscope) - The repo name must be entered without a
.gitsuffix
- Create a repository on GitHub for your project (or use an existing one)
- From the repository's Projects tab, click Link a project > New project > choose Board > Create
- Optionally customize the Status field columns in the project's Settings > Custom fields > Status (e.g., add "Backlog" or "Review")
- Add existing issues to the project from the board's + Add item field
- Start the git-kanban web server (
cargo run -p git-kanban-web) - In git-kanban, click "Add Board" and enter the owner and repo name (e.g.,
hughdbrown/who-is-hiring) - Create and manage issues through git-kanban — changes sync bidirectionally with GitHub
cd crates/git-kanban-frontend
trunk build --release
cd ../..This compiles the Yew frontend to WASM and outputs to crates/git-kanban-frontend/dist/.
cargo run -p git-kanban-webThe server starts on http://localhost:3000. It serves both the REST API under /api/ and the compiled frontend as static files. If the frontend dist/ directory is not found, it runs in API-only mode.
- Navigate to
http://localhost:3000 - Click "Add Board" to connect a GitHub repository
- Enter the repository owner and name (e.g.,
octocat/Hello-World) - If the repository has multiple GitHub Projects v2, you'll be prompted to select one
- Drag and drop cards between columns to move them
- Click a card to view/edit its details
| Method | Path | Description |
|---|---|---|
GET |
/api/health |
Health check |
GET |
/api/boards |
List all boards |
GET |
/api/boards/{id} |
Get board config |
POST |
/api/boards |
Add board ({"owner": "...", "repo": "...", "project_number": null}) |
DELETE |
/api/boards/{id} |
Remove board |
GET |
/api/boards/{id}/state |
Sync and return full board state |
GET |
/api/boards/{id}/cards/{item_id} |
Get card details |
POST |
/api/boards/{id}/cards |
Create card ({"title": "...", "body": "..."}) |
PUT |
/api/boards/{id}/cards/{item_id} |
Update card |
POST |
/api/boards/{id}/cards/{item_id}/move |
Move card ({"column_id": "..."}) |
POST |
/api/boards/{id}/cards/{item_id}/close |
Close linked issue |
cargo run -p git-kanban-tui -- [OPTIONS]| Flag | Description |
|---|---|
--repo <owner/repo> |
Open a specific board on startup |
--db <path> |
SQLite database path (default: sqlite:git-kanban.db?mode=rwc) |
--token <token> |
GitHub PAT (overrides GITHUB_TOKEN env var) |
| Key | Normal Mode | Board Select | Card Detail | Create Card |
|---|---|---|---|---|
h / l |
Previous/next column | |||
j / k |
Next/previous card | Navigate list | ||
Enter |
Open card detail | Select board | Submit | |
Shift+h / Shift+l |
Move card left/right | |||
c |
Create card | |||
b |
Open board selector | |||
r |
Refresh board | |||
x |
Close issue | |||
Esc |
Cancel | Back to board | Cancel | |
q |
Quit |
- The TUI writes logs to
git-kanban-tui.login the current directory (since ratatui owns the terminal) - Boards must first be added via the web UI or by sharing the same SQLite database
- The TUI shares the same database as the web server, so both can be used together
Build and run the web application as a single container:
docker build -t git-kanban .
docker run -p 3000:3000 -e GITHUB_TOKEN=ghp_yourtoken git-kanbanThe multi-stage Dockerfile builds the Rust backend and Yew WASM frontend, then packages them into a minimal Debian image. The SQLite database is created inside the container at /home/kanban/git-kanban.db.
To persist the database across container restarts:
docker run -p 3000:3000 \
-e GITHUB_TOKEN=ghp_yourtoken \
-v git-kanban-data:/home/kanban \
git-kanban# Build workspace (core, web, tui)
cargo build --workspace
# Build frontend (separate step, targets wasm32)
cd crates/git-kanban-frontend && trunk build && cd ../..
# Run tests
cargo test --workspace
# Run clippy
cargo clippy --workspace -- -D warningsgit-kanban/
crates/
git-kanban-core/ # Shared library: models, DB, GitHub API, sync, config, cache
git-kanban-web/ # Axum REST server + static file serving
git-kanban-frontend/# Yew WASM frontend (excluded from workspace, built with trunk)
git-kanban-tui/ # ratatui terminal UI
migrations/ # SQLite migrations (run automatically on startup)
The core crate is shared between the web server and TUI. The frontend crate mirrors the core models independently because it compiles to WASM and cannot depend on native crates.
MIT

