Syntax color and Git markers improve ordinary file reading
bat solves a small problem well: source code is harder to scan when every token has the same weight. It detects many programming and markup formats, applies a terminal theme, adds optional line numbers, and marks changes against Git's index. File headers help when several inputs are printed together. The result is closer to a lightweight code viewer than a traditional concatenation command, yet it remains quick to invoke with one short name.
The project is substantial for a terminal utility. Our checkout at commit b671e53 held 7,771 files, roughly 348,015 lines of source, and 181.4 MB. Much of that footprint comes from syntax and theme assets rather than a background service. bat opens a file, renders it, and exits. It does not need an account, daemon, network key, or database, which keeps the operational risk far below the repository size.
Redirected output stays plain by default
bat detects whether its output is going to an interactive terminal. In a terminal it can show color, headers, line numbers, Git markers, and a pager. When output is redirected to a file or piped into another process, the default behavior drops those decorations and prints plain content. That choice makes an alias such as cat='bat --paging=never' workable for many daily commands without leaking escape sequences into scripts.
Compatibility still deserves care. POSIX cat is ubiquitous, tiny, and specified around concatenating bytes. bat reads syntax, expands tabs to 4 spaces for display, may inspect Git state, and uses terminal capabilities. A script should call cat when exact, portable behavior matters. Use bat for a person looking at text. Its --plain, --color, --decorations, and --paging switches make the boundary explicit when automation and presentation meet.
What happened when we ran it
Our sandbox installed 271 Rust packages in 22 seconds, then built bat in 76 seconds on 3 CPUs with 12 GB of RAM. The source checkout used the rust:1-bookworm image in a fresh unprivileged Debian container with no secrets. These numbers measure the contributor path at commit b671e53. A user downloading a prebuilt release avoids that compilation work.
The cargo test run finished in 48 seconds. All 443 tests passed and 0 failed. The repository also contained a tests directory and 2 CI workflow files, while it had no Dockerfile. A container recipe would add little for a local command that already ships as platform packages and static musl archives. The clean test outcome is more useful: the checked-out source passed its available suite in our stated environment.
Packages avoid the 76-second source build
The README covers common Linux package managers, Homebrew and MacPorts, Windows installers, crates.io, and release archives. Building locally requires Rust 1.79.0 or newer. cargo install --locked bat gets the executable onto a Rust user's path, but it cannot automatically install every generated man page and shell completion. Distribution packages are the better default when those system integrations matter.
Debian-based systems have one famous wrinkle. Some releases install the executable as batcat because another package already claimed bat; the README suggests a user-level symlink or alias. Windows requires the Visual C++ Redistributable. Those are packaging details rather than defects in the viewer, but they can make a successful installation appear missing when a copied command expects the other executable name.
Pager behavior is the main source of surprises
Automatic paging sends long output through less when appropriate. bat adds options for raw colors, one-screen exit, interrupt handling, and sometimes terminal initialization. Supplying custom pager arguments can stop bat from adding those defaults. Older less versions also require a tradeoff between one-screen exit and mouse-wheel behavior. The built-in pager and --paging=never provide escape routes for users who do not want to debug an external pager.
Windows includes more, which lacks the color behavior bat expects, so the README recommends installing less or turning paging off. Long-running input such as tail -f also needs paging disabled and often needs an explicit language because syntax cannot be inferred from a filename. These details explain most cases where bat appears to hang, loses color, or exits differently from a simple file-print command.
Custom syntax files require a cache rebuild
bat bundles many Sublime Text syntax definitions and themes through its highlighting engine. A missing language can be added by placing a .sublime-syntax file under bat's configuration directory and running bat cache --build. Custom themes follow the same cache step but must use the older .tmTheme format; newer .sublime-color-scheme files are not accepted. Syntax mapping rules can also associate filenames or paths with an existing language.
The configuration file is simply a list of command-line arguments, which keeps customization inspectable. System configuration is read before user configuration, and environment variables can select themes, style, pager, and config paths. Release v0.26.1 fixed pager, piping, completion, Docker asset, and syntax issues. GitHub showed a 2026-08-11 push, 60,272 stars, and 422 open issues and pull requests, evidence of use and maintenance rather than a count of defects.
bat is best kept beside cat
The 443 passing tests and broad packaging make bat unusually easy to trust for an optional developer tool. It adds immediate value when reading code, inspecting a diff context, previewing fzf results, or coloring a help page. The defaults also respect pipelines better than a naive colored wrapper because non-interactive output becomes plain.
Keep the distinction simple. bat is for viewing, while cat remains the safest name inside portable scripts and recovery environments. Our 22-second install and 48-second test run support adopting bat without ceremony, but they do not make its pager and decoration choices disappear. Install the binary package your operating system maintains, tune paging once, and use the plain command whenever exact output matters.

