kanban.bash: one shell script, one CSV, one board per directory
commandline asciii kanban board for minimalist productivity hackers & managers (csv-based) #scriptable #nestable #statistics #singlefile #shellscript #issuetracker #git
At a glance
- What is it?
- kanban.bash is a single file shell script that renders a kanban board from a CSV you own, so the board can live in a git repository next to the code it tracks. It is deliberately narrow: no server, no daemon, no database, and no history beyond a short per-item status string.
- Who is it for?
- kanban.bash fits individual contributors and small teams who want their task list versioned in the same repository as the code, and it does that with zero runtime dependencies. It does not fit anyone who needs concurrent editing, permissions, notifications or a reliable shared board, because the CSV is plain text with no locking.
- Can I use it commercially?
- Yes, with strict conditions. AGPL-3.0 is a network copyleft licence: if people use a modified version over a network, for example as a hosted service, you must offer them its source code under the same licence.
- Is it still maintained?
- Yes. The repository last received commits 100 days ago.
- What is it written in?
- Mainly Shell, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The board lives next to the code it tracks
The problem kanban.bash targets is a personal or small team todo list that has nowhere sensible to live. Online issue trackers assume you have a project boundary, a hosting account and a login. Plenty of work has no such boundary: a chore that spans three repositories, a reading list, a two item list for a weekend. The project's own description frames it as a question about managing personal todos across repo, macro and micro levels, and the answer it gives is to keep the board as CSV files inside repositories, cloud drives and local filesystems.
That answer has consequences worth understanding before you install anything. A board is a directory, not a service. Running the init command in a folder creates a board for that folder, and the data file that the script reads and writes is ordinary CSV you can open in a spreadsheet. Nothing is uploaded, no account is created, no daemon runs. Teams that already put their code in git get one obvious property for free: the board travels with the repository and shows up in diffs.
The tooling is aimed at people who like the terminal. There is no web interface, no plugin API and no configuration file format beyond a shell style config. If you need a shared board that several people edit at once, this is the wrong shape for the job.
Installing is one curl and one chmod
There is no package manager step, no build and no dependency list to satisfy. The project ships a single executable file named kanban, and the install section gives exactly two commands:
$ curl -LO "https://raw.githubusercontent.com/coderofsalvation/kanban.bash/master/kanban"
$ chmod 755 kanbanThe first line fetches the raw script from the master branch into a file called kanban in the current directory. The second makes it executable. What you should see is a new file in your working directory that you can call as ./kanban. There is no output to check and no version marker to compare, so if you want to know what you are running, read the file or check the repository history yourself.
Your first real board takes three commands. The init call creates the board for the current directory, the add call records one item with a status, a tag and a quoted description, and the show call renders the board:
$ ./kanban init
$ ./kanban add TODO PERSONAL "buy rose for girlfriend foo bar"
$ ./kanban showThe rendering is plain ASCII columns with the status names as headers, and the board resizes to the width of your terminal. Columns are configurable, so the set of statuses you see is whatever your configuration file defines rather than a fixed list baked into the script.
Status names and column headers come from a config file
Two files carry the state. The documented locations are ~/.kanban/.kanban.csv for the database CSV and ~/.kanban/.kanban.conf for the configuration, and a board you initialize in a directory keeps its own .kanban folder with a kanban.conf inside it. The configuration holds the status names and can also limit how many todos are allowed per status. The configuration is created automatically, so there is nothing to copy by hand before the first run.
The CSV format is what makes the tool scriptable and also what makes it fragile. The header line the project documents is:
$ grep HEADER ~/.kanban/kanban.conf
HEADER="id,status,tag,description,history,start,hours"Seven fields, with hours as an optional trailing column you add yourself. Every extra field you define has to be added to the HEADER and to every row by hand, which is why the project leans on kanban csv to edit the raw file. Column names and order are positional, so a mismatch between your config and an existing CSV will not produce an error, it will produce shifted values. Check this before you point the script at a file someone else created.
Changing status with a bare numeric id
Item ids are positional numbers, and updating an item does not need a flag. Passing an id and a status rewrites that item's status, and the tool prints the transition it performed:
$ ./kanban 2 DOING
TODO -> DOINGPassing only the id opens the item in your editor instead. The project's note asks you to make sure your preferred editor is exported in your shell profile, and gives export EDITOR=vim as the example. The editor is also what launches when you add a filename as the description, which is the note taking trick: the script treats a path as a pointer to a file you want to open, and the file itself can be a symlink to a shared note that lives outside the board.
Each item also carries a history string that records status transitions as single letters, one per change. The listing command prints that history column next to the description, and the example output shows an item whose history reads BTBDHDHDHT, which the project uses as an argument for splitting a task that keeps bouncing between columns. You can also filter the listing by status and grep the output for a project name to get a per project view of the board.
Hours and custom fields are manual csv work with a sum helper
Time tracking is not automated. The project is explicit that tracking hours is delegated to manual CSV editing and the sum command, or to whatever spreadsheet editor you already use. Once hours is listed in the header, you open the raw CSV, type a number into the hours position of a row, and let the sum command do the arithmetic:
$ kanban sum hours
7
$ kanban sum hours DONE
4The second form restricts the total to items in one status, so DONE hours can be compared against the total. This design keeps the script free of a date parser and a units model, and it lets you use any numeric field you invent, not just hours. The cost is that a spreadsheet becomes a second source of truth for the same rows, and the CSV editor the project calls idiotproof is really just the interactive add flow that asks for description, status and tag one prompt at a time.
For measuring rather than recording, the usage listing also shows status, tag and history reports under a stats subcommand, and a plain list command for a full dump of every todo.
Narrow terminals get a cut down board
The board adapts to the terminal it is printed into, and the environment variables are the knob. Three are listed in the usage section: X caps the maximum line width, NOCOLOR disables colors, and PLAIN switches off UTF-8 characters for terminals that cannot render them. A second pair handles the small screen case, where a full multi column board becomes unreadable:
XSMALL=119 # show simplified kanban for terminalwidth < 119 chars
SMALLSCREEN=('DOING' 'TODO' 'HOLD') # define simplified kanban board statusesSetting SMALLSCREEN picks which columns survive when the terminal is narrower than the XSMALL threshold. The tradeoff is that hidden columns are hidden everywhere in that view, not just truncated, so anything you move to a status outside the list disappears from the board until you change the setting. The variables are read from the environment rather than from the config file, which means every shell session that wants a different board layout has to set them again unless you export them yourself.
Boards inside boards, and the git storage trick
The nested feature lets a directory contain its own board while the parent board lists it as a ticket. The documented sequence initializes a board, creates two nested directories with mkdir, initializes a board in each, and then shows the parent view. The nested directories are plain folders, so you create them with the mkdir command before running the init calls shown here:
$ kanban init
$ cd v3 && kanban init && kanban add a foo && cd -
$ cd v3/v4 && kanban init && kanban add b bar && cd -
$ kanban add TODO dev foobarWhen you display the parent board, the nested boards appear in a separate tree section under the columns, and the kanban v3 argument opens the nested board directly. The practical use is a hierarchy that matches how a repository is laid out, with a per package board under a repository level board.
The same layout logic is what makes the git workflow possible. The usage examples show cloning a repository, initializing a board inside it and adding the generated .kanban directory to version control. Since the file is CSV, a diff of a board shows exactly which descriptions and statuses changed, and a merge conflict is a text conflict you can resolve by hand. The project also suggests symlinking shared files into a board directory so notes can be reused across boards.
Where a plain CSV board breaks down
The obvious limitation is concurrency. The data file is plain text and the script has no locking, no daemon and no conflict detection, so two people editing the same board over a network share will overwrite each other. A file in a git repository avoids this because git serialises commits, but then you are back to doing merges by hand on a table.
The second limitation is the flexibility that comes with the format itself. Column order is fixed, custom fields must be typed by hand, and the history string records only status transitions. There is no due date, no assignee, no priority and no comment thread in the documented columns. Anyone expecting a task tool with reminders or notifications will find nothing of the sort here.
Third, the upstream state is thin. The repository has no GitHub releases, so there is no tagged version to pin against, and the project is not archived, but the last push was on 2026-07-15, which is over three months before now. Treat that as the real upgrade signal: pull the script again with the same curl command and diff it against the copy you already run, because there is no changelog telling you what changed. The licence is AGPL-3.0, which matters if you plan to redistribute a modified copy of the script rather than just use it for your own board.
Editorial conclusion
kanban.bash fits individual contributors and small teams who want their task list versioned in the same repository as the code, and it does that with zero runtime dependencies. It does not fit anyone who needs concurrent editing, permissions, notifications or a reliable shared board, because the CSV is plain text with no locking. Before adopting it, check that the HEADER line in your config file matches the columns your existing CSV already has, and confirm the last push date on the repository before you commit to it.
Frequently asked questions
How do I install kanban.bash?
Fetch the single script with curl -LO from the raw GitHub URL for the master branch and make it executable with chmod 755 kanban. There is no package manager step and no dependency to install.
Where does kanban.bash keep my board data?
The database CSV lives in ~/.kanban/.kanban.csv and the configuration in ~/.kanban/.kanban.conf, both created automatically. Running init in a directory creates a board there with its own .kanban folder.
Can kanban.bash track how many hours I spent on a task?
Yes, but only manually. Add hours to the HEADER line in the config, type the numbers into the raw CSV with kanban csv, then read the total with kanban sum hours or kanban sum hours DONE.
How does kanban.bash behave on a narrow terminal?
The board resizes to the terminal width, and the XSMALL and SMALLSCREEN settings let you define a simplified set of columns for terminals narrower than a chosen threshold. X caps the maximum line width, NOCOLOR=1 disables colors and PLAIN=1 drops UTF-8 characters.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/coderofsalvation-kanban-bash)Was this useful?