{"id":51303436,"url":"https://github.com/mathiasconradt/kanbanqube","last_synced_at":"2026-06-30T22:03:24.278Z","repository":{"id":363867985,"uuid":"1263298776","full_name":"mathiasconradt/kanbanqube","owner":"mathiasconradt","description":"KanbanQube is a local-first Kanban board app for solo users and very small teams. A board lives as normal files in a regular vault folder on your machine and can optionally be placed inside a Git repository, so changes can be versioned and synced with tools you already use.","archived":false,"fork":false,"pushed_at":"2026-06-29T17:41:11.000Z","size":13864,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"dev","last_synced_at":"2026-06-29T19:24:17.190Z","etag":null,"topics":["kanban","kanban-board","kanban-board-application","nodejs","trello","trello-board","trello-clone"],"latest_commit_sha":null,"homepage":"https://github.com/mathiasconradt/kanbanqube","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mathiasconradt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-08T20:22:41.000Z","updated_at":"2026-06-29T17:41:15.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mathiasconradt/kanbanqube","commit_stats":null,"previous_names":["mathiasconradt/kanbanqube"],"tags_count":41,"template":false,"template_full_name":null,"purl":"pkg:github/mathiasconradt/kanbanqube","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathiasconradt%2Fkanbanqube","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathiasconradt%2Fkanbanqube/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathiasconradt%2Fkanbanqube/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathiasconradt%2Fkanbanqube/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mathiasconradt","download_url":"https://codeload.github.com/mathiasconradt/kanbanqube/tar.gz/refs/heads/dev","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mathiasconradt%2Fkanbanqube/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34984784,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-30T02:00:05.919Z","response_time":92,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["kanban","kanban-board","kanban-board-application","nodejs","trello","trello-board","trello-clone"],"created_at":"2026-06-30T22:03:24.179Z","updated_at":"2026-06-30T22:03:24.265Z","avatar_url":"https://github.com/mathiasconradt.png","language":"JavaScript","funding_links":["https://ko-fi.com/mathiasconradt"],"categories":[],"sub_categories":[],"readme":"# KanbanQube\n\n[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=mathiasconradt_kanbanqube\u0026metric=alert_status\u0026token=7c0afec22581861a3d7d49e67df8ad32aa9b5972)](https://sonarcloud.io/summary/new_code?id=mathiasconradt_kanbanqube)\n[![License: Apache-2.0](https://img.shields.io/badge/License-Apache--2.0-blue.svg)](LICENSE)\n[![Buy me a coffee](https://img.shields.io/badge/Buy%20me-a%20coffee-ff5f5f?logo=ko-fi\u0026logoColor=white)](https://ko-fi.com/mathiasconradt)\n![GitHub stars](https://img.shields.io/github/stars/mathiasconradt/kanbanqube)\n\n![KanbanQube preview](promo.jpg)\n\nKanbanQube is a local-first desktop Kanban board app for solo users and tiny teams. It is designed for normal desktop browser use; there is no dedicated mobile version or mobile app.\n\nA board lives as normal files in a regular vault folder on your machine and can optionally be placed inside a Git repository, so changes can be versioned and synced with tools you already use. The app intentionally does not provide a strong user-security or RBAC model; it assumes trusted local users or a very small trusted team.\n\nSee the [full feature list](#features) below. Uploaded files are stored in an `uploads/` folder, while board data is split into per-object JSON files under `board/` so Git can merge independent card and checklist edits more cleanly.\n\n![KanbanQube board screenshot](screenshot.png)\n\n## Table Of Contents\n\n- [Features](#features)\n- [Requirements](#requirements)\n- [Quick Start](#quick-start)\n- [Run With npx](#run-with-npx)\n- [Install With Homebrew](#install-with-homebrew)\n- [Global npm Install](#global-npm-install)\n- [Run On macOS Login](#run-on-macos-login)\n- [Vaults](#vaults)\n- [Board Workflow](#board-workflow)\n- [Git Sync](#git-sync)\n- [Trello Import](#trello-import)\n- [Demo Board](#demo-board)\n- [Identity](#identity)\n- [Assignees And Due Dates](#assignees-and-due-dates)\n- [Attachments And Covers](#attachments-and-covers)\n- [Keyboard Shortcuts](#keyboard-shortcuts)\n- [Development](#development)\n- [Build](#build)\n- [Release Automation](#release-automation)\n- [Star History](#star-history)\n\n## Features\n\n- Local-first board vaults stored as normal files\n- Configurable lanes and inline lane-title editing\n- Optional lane background colors\n- Collapsible lanes with drag-and-drop support into collapsed lanes\n- Resizable lane width, applied consistently across lanes\n- Cards with descriptions, comments, checklists, labels, due dates, and assignees\n- Comment editing and deletion by the comment author\n- Drag-and-drop card movement between lanes\n- Board keyboard navigation and shortcuts\n- Search across cards\n- File attachments stored in the vault `uploads/` folder\n- Image attachments as optional card covers\n- Archive view with restore, delete, and delete-all actions\n- Git sync for versioning and syncing vault changes\n- User detection from Git config and Git commit authors\n- Gravatar avatars with initials fallback\n- Empty-board demo import\n- Import from Trello board export (JSON) into an empty board\n- Optional macOS LaunchAgent background startup\n- Optional Electron desktop window via separate `kanbanqube-desktop` package\n\n## Requirements\n\n- Node.js 18 or newer\n- Git, if you want repository sync\n- A folder to use as your board vault\n\n## Quick Start\n\nChoose one mode:\n\n| Mode | npx | Homebrew |\n| --- | --- | --- |\n| Lightweight browser/server | `npx kanbanqube` then open `http://localhost:3888` | `brew tap mathiasconradt/kanbanqube https://github.com/mathiasconradt/kanbanqube`, `brew install kanbanqube`, `kanbanqube`, then open `http://localhost:3888` |\n| Desktop window | `npx kanbanqube-desktop` for quick testing only | Recommended: `brew tap mathiasconradt/kanbanqube https://github.com/mathiasconradt/kanbanqube`, `brew install --cask kanbanqube-desktop`, then open `KanbanQube.app` |\n\nBoth modes use the same default vault folder:\n\n```text\nmacOS/Linux: ~/.kanbanqube\nWindows: C:\\Users\\\u003cyou\u003e\\.kanbanqube\n```\n\nPass a vault path only if you want to use a different folder:\n\n```sh\nnpx kanbanqube /path/to/your/vault\nnpx kanbanqube-desktop /path/to/your/vault\nkanbanqube /path/to/your/vault\n```\n\n## Run With npx\n\nLightweight browser/server mode:\n\n```sh\nnpx kanbanqube\n```\n\nThen open:\n\n```text\nhttp://localhost:3888\n```\n\nDesktop window mode:\n\n```sh\nnpx kanbanqube-desktop\n```\n\nUse this mainly for quick testing. On macOS, `npx kanbanqube-desktop` launches Electron directly, so pinning it to the Dock can pin Electron instead of KanbanQube. For normal desktop use, install the Homebrew cask.\n\nBy default, both commands use a `.kanbanqube` folder in the current user's home directory. This works across macOS, Linux, and Windows:\n\n```text\nmacOS/Linux: ~/.kanbanqube\nWindows: C:\\Users\\\u003cyou\u003e\\.kanbanqube\n```\n\nPass a vault path only if you want to use a different folder:\n\n```sh\nnpx kanbanqube /path/to/your/vault\n```\n\nYou can choose a different port:\n\n```sh\nPORT=4000 npx kanbanqube\n```\n\nCustom port plus custom vault:\n\n```sh\nPORT=4000 npx kanbanqube /path/to/your/vault\n```\n\nThe desktop package depends on the normal `kanbanqube` package and downloads Electron, so it is much larger than the lightweight browser/server package. Use `npx kanbanqube` if you prefer the smallest install.\n\n## Install With Homebrew\n\nHomebrew supports both modes from the same tap.\n\nLightweight browser/server mode:\n\n```sh\nbrew tap mathiasconradt/kanbanqube https://github.com/mathiasconradt/kanbanqube\nbrew install kanbanqube\nkanbanqube\n```\n\nThen open:\n\n```text\nhttp://localhost:3888\n```\n\nCustom vault:\n\n```sh\nkanbanqube /path/to/your/vault\n```\n\nDesktop window mode:\n\n```sh\nbrew tap mathiasconradt/kanbanqube https://github.com/mathiasconradt/kanbanqube\nbrew install --cask kanbanqube-desktop\n```\n\nThen open `KanbanQube.app` from `/Applications` or Launchpad.\n\nThis is the recommended desktop installation on macOS because it installs a real `KanbanQube.app`. Dock pinning, app identity, reopen behavior, and the app icon work as expected.\n\nThe cask removes the macOS quarantine attribute during install. If you download the app release zip manually and macOS says the app is damaged, run:\n\n```sh\nxattr -cr \"/Applications/KanbanQube.app\"\n```\n\n## Global npm Install\n\nInstall the lightweight browser/server command globally:\n\n```sh\nnpm install -g kanbanqube\nkanbanqube\n```\n\nInstall the desktop command globally:\n\n```sh\nnpm install -g kanbanqube-desktop\nkanbanqube-desktop\n```\n\nLocal development install from this repository:\n\n```sh\nnpm install\nnpm start\n```\n\n## Run On macOS Login\n\nUse a macOS LaunchAgent if you want KanbanQube to start automatically in the background when you log in.\n\nFirst check where `npx` is installed:\n\n```sh\ncommand -v npx\n```\n\nCreate `~/Library/LaunchAgents/com.mathiasconradt.kanbanqube.plist`. This example omits a vault path, so KanbanQube uses the default `~/.kanbanqube` vault:\n\n```xml\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\n\u003c!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\"\n  \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\"\u003e\n\u003cplist version=\"1.0\"\u003e\n  \u003cdict\u003e\n    \u003ckey\u003eLabel\u003c/key\u003e\n    \u003cstring\u003ecom.mathiasconradt.kanbanqube\u003c/string\u003e\n\n    \u003ckey\u003eProgramArguments\u003c/key\u003e\n    \u003carray\u003e\n      \u003cstring\u003e/opt/homebrew/bin/npx\u003c/string\u003e\n      \u003cstring\u003ekanbanqube\u003c/string\u003e\n    \u003c/array\u003e\n\n    \u003ckey\u003eEnvironmentVariables\u003c/key\u003e\n    \u003cdict\u003e\n      \u003ckey\u003ePATH\u003c/key\u003e\n      \u003cstring\u003e/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin\u003c/string\u003e\n      \u003ckey\u003ePORT\u003c/key\u003e\n      \u003cstring\u003e3888\u003c/string\u003e\n    \u003c/dict\u003e\n\n    \u003ckey\u003eWorkingDirectory\u003c/key\u003e\n    \u003cstring\u003e/Users/mathias.conradt\u003c/string\u003e\n\n    \u003ckey\u003eRunAtLoad\u003c/key\u003e\n    \u003ctrue/\u003e\n\n    \u003ckey\u003eKeepAlive\u003c/key\u003e\n    \u003ctrue/\u003e\n\n    \u003ckey\u003eStandardOutPath\u003c/key\u003e\n    \u003cstring\u003e/tmp/kanbanqube.out.log\u003c/string\u003e\n\n    \u003ckey\u003eStandardErrorPath\u003c/key\u003e\n    \u003cstring\u003e/tmp/kanbanqube.err.log\u003c/string\u003e\n  \u003c/dict\u003e\n\u003c/plist\u003e\n```\n\nLoad and start it:\n\n```sh\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.mathiasconradt.kanbanqube.plist\nlaunchctl kickstart -k gui/$(id -u)/com.mathiasconradt.kanbanqube\n```\n\nCheck status and logs:\n\n```sh\nlaunchctl print gui/$(id -u)/com.mathiasconradt.kanbanqube\ntail -f /tmp/kanbanqube.out.log\ntail -f /tmp/kanbanqube.err.log\n```\n\nStop and unload it:\n\n```sh\nlaunchctl bootout gui/$(id -u)/com.mathiasconradt.kanbanqube\n```\n\nThe example runs KanbanQube on `http://localhost:3888`. If that port is already used, change the `PORT` value in the plist.\n\nTo use a custom vault path with LaunchAgent, add it as a third `ProgramArguments` string. Use an absolute path; `launchd` does not expand `~` there.\n\n## Vaults\n\nA vault is just a directory. KanbanQube stores:\n\n```text\nvault/\n  board/\n    meta.json\n    cards/\n    lists/\n    checklists/\n    actions/\n    labels/\n    members/\n  uploads/\n```\n\nIf `board/` does not exist, KanbanQube creates it automatically. If `uploads/` does not exist, it is created when the first file is uploaded.\n\nUploaded filenames are made unique while preserving the original name in the UI. For example:\n\n```text\nMyExample.png\nMyExample.kbq_20260609T092141981Zb7a252.png\n```\n\nThe stored filename prevents conflicts. The app still displays `MyExample.png`.\n\n## Board Workflow\n\nUse the board view for quick work:\n\n- Click `+ Add a card` to create a card directly in the lane and type its title inline.\n- Click the board title or lane title to rename it inline.\n- Click a card to open its details.\n- Settings can enable inline editing for existing card titles in board lanes.\n- Set due dates and assignees in card details. Cards show due dates and assigned user avatars directly in the board view.\n\n## Git Sync\n\nGit sync is optional. If the vault is a Git repository with a configured `origin` remote, the Sync button is enabled.\n\nWhen Sync runs, KanbanQube:\n\n1. Saves pending board changes.\n2. Checks whether anything in the vault repository changed.\n3. Stages and commits all repository changes when needed, including `board/`, `uploads/`, and newly added files.\n4. Runs `git pull --rebase` to bring in remote changes after local work is committed.\n5. Pushes to the configured remote.\n6. Reloads the board from disk so changes pulled from another machine are visible without refreshing the browser.\n\nIf the vault is not a Git repository, or no remote is configured, Sync stays disabled. You can still use the board locally.\n\nSettings includes `Run Git sync in the background (no dialog)`. When enabled, the Sync button runs without opening the sync log automatically. The status text under the app title can still be clicked to open the sync log during or after sync.\n\nRecommended setup:\n\n```sh\nmkdir my-kanban-vault\ncd my-kanban-vault\ngit init\ngit remote add origin git@github.com:you/my-kanban-vault.git\nnpx kanbanqube .\n```\n\nCommit and push once if your remote requires an initial branch:\n\n```sh\ngit add board\ngit commit -m \"Initialize KanbanQube board\"\ngit push -u origin main\n```\n\n## Trello Import\n\nKanbanQube can import a Trello board export JSON from Settings. Import is only enabled when the current board has no cards. This keeps accidental replacement of an active board from happening inside the app.\n\nImported data is normalized and written into the split `board/` vault layout.\n\n## Demo Board\n\nThe repository includes `demo_board.json`, a sample e-commerce product board with design, UX, frontend, backend, QA, content, and analytics work spread across the default lanes.\n\nWhen a vault has no cards, KanbanQube asks whether to load the demo board. If accepted, the app loads `demo_board.json` and saves it into the current vault using the same path as a normal import.\n\n## Identity\n\nKanbanQube reads your Git identity from the vault repository first:\n\n```sh\ngit config --local user.name\ngit config --local user.email\n```\n\nIf local values are missing, it falls back to global Git config:\n\n```sh\ngit config --global user.name\ngit config --global user.email\n```\n\nIf no Git name is configured, KanbanQube falls back to the current system username returned by `whoami`. Email is optional; if no email is configured, the app still uses the detected name.\n\nThat name is used for comments and activity entries. The settings dialog shows the detected name and email as read-only values.\n\nKanbanQube also reads commit authors from the vault Git repository and makes them available as assignable users. Git can usually provide the author name and email address from existing commits. If the vault has no Git history, KanbanQube still includes your own detected identity.\n\nUser avatars are loaded from Gravatar based on email address. If no Gravatar image exists, the app falls back to initials.\n\n## Assignees And Due Dates\n\nOpen a card to assign users and set a due date. Assigned users are shown as small avatars on the card in board view, with their name available on hover.\n\nDue dates are stored on the card and shown below the card title in board view. Completed cards keep the due date visible in a completed state, while overdue open cards are highlighted.\n\n## Attachments And Covers\n\nDrop files onto a card or into the card details view to attach them. Files are uploaded into the vault `uploads/` folder.\n\nImages can be used as card covers. The cover is stored as a pointer to the attachment in `card.cover.idAttachment`, so removing a cover does not delete the attachment. You can also select another image attachment as the cover.\n\nDeleting an uploaded attachment from a card also deletes the physical file from `uploads/` when no other card still references that file.\n\n## Keyboard Shortcuts\n\nBoard view shortcuts are ignored while typing in inputs or while a dialog is open.\n\n| Key | Action |\n| --- | --- |\n| Arrow keys | Select cards across lanes and rows |\n| Enter | Open selected card details |\n| Space | Toggle selected card done status |\n| c | Archive selected card |\n| m | Assign or unassign current user on selected card |\n| 1-9 | Toggle the matching label by label-list order |\n\n## Development\n\nInstall repository dependencies:\n\n```sh\nnpm install\n```\n\nStart the lightweight browser/server app from the repository with the default `~/.kanbanqube` vault:\n\n```sh\nnpm start\n```\n\nOr pass a custom vault path:\n\n```sh\nnpm start -- /path/to/your/vault\n```\n\nRun checks:\n\n```sh\nnpm test\n```\n\nRun the desktop wrapper during local development:\n\n```sh\nnpm install --prefix desktop\nnpm run desktop\n```\n\nRun desktop checks:\n\n```sh\nnpm test --prefix desktop\n```\n\nPackage the desktop app locally on macOS:\n\n```sh\nnpm run package:mac --prefix desktop\n```\n\nMain files:\n\n- `server.js` - HTTP server, vault storage, upload handling, Git sync\n- `desktop/main.js` - Electron desktop wrapper\n- `desktop/package.json` - separate `kanbanqube-desktop` npm package\n- `Casks/kanbanqube-desktop.rb` - Homebrew cask for the packaged macOS app\n- `public/app.js` - board UI behavior\n- `public/styles.css` - app styling\n- `public/index.html` - static app shell\n\n## Build\n\nKanbanQube has no frontend build step. The lightweight app is plain Node.js plus static browser assets. The desktop package is an Electron wrapper that starts the same local server and opens it in a desktop window.\n\nValidate the lightweight browser/server package:\n\n```sh\nnpm test\n```\n\nValidate the desktop package:\n\n```sh\nnpm test --prefix desktop\n```\n\nDry-run package contents:\n\n```sh\nnpm pack --dry-run\nnpm pack --dry-run ./desktop\n```\n\nPackage managers can install the lightweight app because root `package.json` exposes the `kanbanqube` executable through the `bin` field. The desktop package has its own `desktop/package.json` and exposes the `kanbanqube-desktop` executable.\n\nThe Homebrew cask build packages the Electron app for both Apple Silicon and Intel macOS:\n\n```sh\nnpm run package:mac --prefix desktop\n```\n\n## Release Automation\n\nKanbanQube is prepared for npm and Homebrew releases. The release publishes two npm packages and two Homebrew install options:\n\n- `kanbanqube` - lightweight browser/server command\n- `kanbanqube-desktop` - optional Electron desktop command\n- `Formula/kanbanqube.rb` - Homebrew formula for the lightweight command\n- `Casks/kanbanqube-desktop.rb` - Homebrew cask for the packaged macOS app\n\nRequired GitHub secrets:\n\n- `NPM_TOKEN` - npm automation token for publishing `kanbanqube` and `kanbanqube-desktop`\n\nRelease flow:\n\n1. A non-bot push to `main` runs the version bump workflow.\n2. The workflow bumps the patch version in `package.json` and `package-lock.json`.\n3. It updates `desktop/package.json`, keeps `kanbanqube-desktop` pinned to the same `kanbanqube` version, updates the Homebrew formula and cask versions, and pushes a matching `vX.Y.Z` tag.\n4. The release workflow runs for that tag.\n5. It runs root checks and desktop checks.\n6. It publishes `kanbanqube` to npm.\n7. It publishes `kanbanqube-desktop` to npm.\n8. It creates the GitHub release asset from the lightweight package tarball.\n9. It builds macOS desktop app zips for Apple Silicon and Intel.\n10. It uploads those zips to the GitHub release.\n11. It updates the Homebrew formula SHA on `main`.\n\nAfter release, users can run:\n\n```sh\nnpx kanbanqube\nnpx kanbanqube-desktop\nbrew tap mathiasconradt/kanbanqube https://github.com/mathiasconradt/kanbanqube\nbrew install kanbanqube\nbrew install --cask kanbanqube-desktop\n```\n\n## Star History\n\n[![Star History Chart](https://api.star-history.com/chart?repos=mathiasconradt/kanbanqube\u0026type=timeline\u0026logscale\u0026legend=top-left\u0026nocache)](https://www.star-history.com/?repos=mathiasconradt%2Fkanbanqube\u0026type=timeline\u0026logscale=\u0026legend=top-left)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathiasconradt%2Fkanbanqube","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmathiasconradt%2Fkanbanqube","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmathiasconradt%2Fkanbanqube/lists"}