CLI tool
maaslalani/sheets avatar
maaslalani/sheets

sheets: a terminal spreadsheet that reads Vim and writes CSV

Terminal based spreadsheet tool

2,311 stars63 forksGoMIT

At a glance

What is it?
A Go program that puts a spreadsheet grid in the terminal, takes Vim-style modal editing, and talks to files and stdin the way a Unix filter should.
Who is it for?
sheets is at its best on a remote box or over SSH, anywhere a full spreadsheet application would mean uploading a file to a machine you cannot reach. The modal editing is not a novelty layer over a grid, it is a spreadsheet editor with formulas, registers, marks and a jump list, and the CLI surface lets it sit in a pipeline.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 81 days ago.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 28, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The command line is the interface, not an afterthought

sheets accepts a path, and that path is the entire storage layer. There is no database, no project file, and no format negotiation: the thing on disk is CSV, and edits go back to it.

bash
> sheets budget.csv

It will also read from standard input, which is what makes it composable with other Unix tools:

bash
> sheets <<< ID,Name,Age
1,Alice,24
2,Bob,32
3,Charlie,26

The more interesting capability is querying a cell or a range without entering the interface at all. `sheets budget.csv B9` prints one value, and `sheets budget.csv B1:B3` prints several, which means you can use the spreadsheet's notion of a cell reference as a command line argument in a script rather than opening a TUI to look at one number.

Assignment works the same way, so a whole edit is expressible as arguments:

bash
> sheets budget.csv B7=10 B8=20

The v0.2.0 release added TSV support and delimiter-aware output, which is the fix for anyone who has ever been handed a tab separated file and resented it.

Vim motions, then a spreadsheet vocabulary layered on top

If you have used Vim, the movement scheme will feel immediate. The cell cursor moves with h, j, k and l, and the jump commands are the ones you would expect, extended to include cell addresses:

bash
* <kbd>gg</kbd>, <kbd>G</kbd>, <kbd>5G</kbd>, <kbd>gB9</kbd>: Jump to the top, bottom, a row number, or a specific cell
* <kbd>0</kbd>, <kbd>^</kbd>, <kbd>$</kbd>: Jump to the first column, first non-empty column, or last non-empty column in the row
* <kbd>H</kbd>, <kbd>M</kbd>, <kbd>L</kbd>: Jump to the top, middle, or bottom visible row
* <kbd>zt</kbd>, <kbd>zz</kbd>, <kbd>zb</kbd>,: Align the current row to the top, middle, or bottom of the window

The window-relative jumps matter more here than in Vim, because a spreadsheet is much taller than a screen and losing your place is the main risk. Marks, the jump list, and search all work the same way they do in Vim, with `ma` to set a mark and `/` and `?` to search forward and backward.

What is spreadsheet specific is the editing set: insert a row above or below with o and O, insert columns, select rows with V, yank a whole row with yy, delete a row with dd, and toggle bold formatting. Undo and redo are bound to u and ctrl+r, and `.` repeats the last change.

The most interesting single feature is in visual mode. Pressing `=` after selecting a range inserts a formula derived from that selection, written as `=|(B1:B8)`, so you can build a formula from what you highlighted rather than typing addresses.

A command mode for saving and opening, which is what separates this from a viewer

The colon command prompt covers the operations that do not have a natural key. `:w` saves, `:w path.csv` saves somewhere new, `:e path.csv` opens a different file, and `:q` or `:wq` quits. Cell addressing has its own command, `:goto B9`, with `:B9` accepted as a shorthand.

bash
- <kbd>:w</kbd> to save
- <kbd>:w path.csv</kbd> to save to a new file
- <kbd>:e path.csv</kbd> to open another CSV
- <kbd>:q</kbd> or <kbd>:wq</kbd> to quit
- <kbd>:goto B9</kbd> or <kbd>:B9</kbd> to jump to a cell

Storing state in the file rather than in a session means there is no second artifact to lose, which is the main practical argument for a CSV-backed spreadsheet in a terminal. The cost is that anything a CSV cannot express, such as multiple sheets, cell background colors, or a formula's cached result, simply is not part of the model.

Editing has its own mode, entered with i for the current cell, I to start from the beginning, or c to clear and retype. Within insert mode, enter commits and moves down, tab commits and moves right, and ctrl+n and ctrl+p commit and move vertically, so you can fill a column without leaving insert mode.

Rebinding keys through a Helix style config file

Keybindings live in TOML at `~/.config/sheets/config.toml`, or under `$XDG_CONFIG_HOME` if you have set it. The format borrows Helix's, and the overlay principle is the important part: you only declare what you want to change, and everything you leave out keeps its default.

toml
[keys.normal]
"C-c" = "quit"
"C-s" = "command_prompt"

[keys.insert]
"C-c" = "commit_down"

[keys.select]
"d" = "cut_selection"

Three mode sections are shown: normal, insert, and select. A key maps to an action name, and the README documents the full action vocabulary inside a collapsed section, roughly a hundred entries grouped by navigation, editing, mode, select and insert. Setting a binding to `nop` disables a key rather than leaving it live.

The action list is worth reading as a feature inventory, because it is the most complete description of what the program does. It contains `insert_space`, `delete_word_before`, `copy_selection_ref`, `delete_selection`, `toggle_selection_bold`, `formula_from_selection` and `repeat_change`, none of which are mentioned in the prose above.

The release notes record that this config system arrived as a cherry-pick of Helix style config in v0.3.0, which tells you where the design came from.

A young project with a data loss fix and a visible history

Three tagged releases exist: v0.1.0 in April 2026, v0.2.0 in early May, and v0.3.0 in July 2026, which is also the last push recorded for the repository. The version history is short enough to read, and one entry in it deserves attention because it changes what you should expect from the editor.

The v0.3.0 changelog includes a fix for a data loss bug when inserting a column at the last position. A commit-level changelog naming the exact failure mode is better evidence about how the editor handles edits than a general claim of stability, and it is the kind of note worth checking against the version you have installed. The same release records a change to the normal button color from blue to purple and then a revert of that same change, which is a small reminder that recent releases are still settling.

The tree is small and legible: `main.go` at the root, an `internal/` directory for the implementation, an `examples/` directory, and a `.goreleaser.yaml` for distribution. There is also a `flake.nix`, `flake.lock` and `.envrc`, so the project is set up for Nix development, and 34 issues are open against 63 forks.

Editorial conclusion

sheets is at its best on a remote box or over SSH, anywhere a full spreadsheet application would mean uploading a file to a machine you cannot reach. The modal editing is not a novelty layer over a grid, it is a spreadsheet editor with formulas, registers, marks and a jump list, and the CLI surface lets it sit in a pipeline. What the repository does not settle is the file format question, because it reads and writes delimited text rather than xlsx, so anything that depends on cell formatting or multiple sheets lives outside this tool. Install it with brew or go install, bind a few keys in config.toml, and let the CSV format decide whether it earns a permanent place on your machine.

Frequently asked questions

What does the sheets command do?

It opens a terminal spreadsheet interface over a CSV file, or over delimited text piped in on standard input. You can also pass a cell reference or a range to print values without opening the interface, and pass assignments such as B7=10 to edit cells from the command line.

How do I install sheets?

Homebrew is the shortest route on macOS and Linux with brew install sheets. Otherwise install it with Go using go install github.com/maaslalani/sheets@main, or download a binary from the releases page. The repository also ships a flake.nix if you prefer Nix.

Can I change the keybindings in sheets?

Yes. Keybindings go in a TOML file at ~/.config/sheets/config.toml, or under XDG_CONFIG_HOME if you have set it. The format follows Helix, with sections for keys.normal, keys.insert and keys.select. You only need to declare overrides, since unset keys keep their defaults, and setting a key to nop disables it.

Does sheets save spreadsheets in xlsx format?

No. sheets reads and writes delimited text, CSV by default, and version 0.2.0 added TSV support along with delimiter-aware output. Anything that depends on multiple sheets, cell formatting or cached formula results has to live outside this tool.

Official sources

  1. Issues
  2. License: MIT
  3. maaslalani/sheets on GitHub
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/maaslalani-sheets.svg)](https://hysenlabs.com/projects/maaslalani-sheets)