Introduction
cols is a Rust library for building and printing terminal tables with
adaptive column widths, tree rendering, group brackets, and multiple output
formats.
Features
cols is batteries-included: everything you need to build rich CLI table
output is in the box. With default features, cols has zero dependencies.
The two optional features (regex for filter regex operators, color for
terminal styling) each add one small dependency.
- Adaptive column widths: fixed, fractional, or content-sized, with a multi-phase layout algorithm
- Tree rendering: depth-first traversal with Unicode or ASCII connectors
- Built-in output modes: Normal, Raw, Export, JSON, ShellVar, CSV, Markdown
- Streaming: output rows incrementally without buffering the whole table
- Group brackets: M:N member/child relationships with left-margin connectors
- Filter expressions: boolean logic, comparisons, regex, integer suffixes (K/M/G/T)
- Color support: foreground, background, bold, italic, underline (via
coloredcrate, optional) - Builder API: configure columns fluently:
Column::new("NAME").width_fixed(10).right(true)
When to use cols
cols is designed for CLI tools that need adaptive, terminal-aware table
output. It is particularly good for information-dense tools like lsblk,
lsmem, or pstree, where the output needs to be clean, scannable, and
available in multiple formats.
Use cols when you need:
- Tabular CLI output that adapts to the terminal width
- Tree-structured data (like
lsblkorpstree) - Multiple output formats from the same data (human-readable, JSON, CSV, shell-parseable)
- Filtering or sorting built into the table layer
- Streaming output for large or unbounded datasets
If you just need a static table with fixed formatting, or if your main goal
is pretty-printing Rust structs with a derive macro, a crate like tabled
or comfy-table may be a better fit. cols shines when the output needs
to be adaptive, the data is dynamic, and you want the same table to render
as Normal, JSON, CSV, or Markdown without rebuilding it.
Comparison with other crates
There are several other table-formatting crates in the Rust ecosystem.
Here’s how cols compares:
| Feature | cols | tabled | comfy-table | cli-table | prettytable-rs |
|---|---|---|---|---|---|
| Adaptive column widths | Yes | Yes | Yes | Limited | No |
| Tree rendering | Yes | No | No | No | No |
| JSON output | Yes | No | No | No | No |
| CSV / Markdown output | Yes | No | No | No | No |
| Raw/Export/ShellVar output | Yes | No | No | No | No |
| Streaming mode | Yes | No | No | No | No |
| Group brackets | Yes | No | No | No | No |
| Filter expressions | Yes | No | No | No | No |
| Color styling | Yes (optional) | Yes | Yes | Yes | Yes |
| Derive macro | Yes | Yes | No | Yes | No |
| Unicode box-drawing | Yes | Yes | Yes | Yes | Yes |
| Wrapping | Yes | Yes | Yes | No | No |
| Maintained | Yes | Yes | Yes | Yes | No |
tabled is the most popular choice. It focuses on pretty-printing Rust
structs via #[derive(Tabled)] and has extensive styling options. If you’re
printing struct collections and want derive-macro convenience, tabled is a
great fit. It doesn’t support trees, multiple output formats, filtering, or
streaming.
comfy-table focuses on being a rock-solid, minimalistic library with
well-tested code. It has good dynamic content arrangement and ANSI styling.
Like tabled, it’s pure tabular output — no trees, structured output
formats, or streaming.
cli-table provides derive macros and CSV integration. It’s lighter than
tabled but has fewer formatting options.
prettytable-rs was popular historically but has been abandoned since 2021 and has a pending security advisory.
cols is the right choice when you need advanced output: trees, streaming, multiple output formats (especially JSON and shell-parseable), adaptive widths that respect terminal size, and built-in filtering. It’s designed for the kind of CLI tools found in util-linux, where information density and flexibility matter more than decoration.
History
cols started as a clean-room Rust reimplementation of libsmartcols, the
table formatting library from the util-linux project (written by Karel Zak,
Ondrej Oprala, and Igor Gnatenko). libsmartcols powers the output of Linux
tools like lsblk, lsmem, lslogins, and findmnt.
The reimplementation was based solely on the public API (header files and documentation); no source code of the original library was studied. It was originally built for the linuxutils project, where it provided a mostly-compatible FFI layer that could be used as a drop-in replacement. This FFI layer was used to test the code against the actual utilities.
Over time, the library proved useful on its own, so it was extracted into a
standalone crate with a native Rust API and has since grown beyond the
original libsmartcols feature set.