bat: a cat clone with syntax highlighting
bat earns a permanent alias in most terminal setups: it does everything cat does, then adds syntax highlighting and Git change markers without extra keystrokes. The catch is that it isn't a perfect drop-in for cat in scripts — pipe it into another program and it silently falls back to plain output, which is correct behavior but easy to forget. For interactive reading of source files, logs, or diffs, bat is simply nicer to look at than cat.
What is bat?
bat is a Rust command-line tool that works like cat, but adds syntax highlighting and Git-aware output on top. It reads files and stdin the way cat does, and layers in colorized highlighting for many languages, line numbers, and a sidebar showing Git modification markers. Piped or redirected output falls back to plain file contents, just like cat.
Syntax highlighting and Git integration
- ✓The syntect library enables syntax highlighting across many programming and markup languages, reading Sublime Text .sublime-syntax files.
- ✓Git integration: shows modification markers in the left sidebar relative to the index.
- ✓Automatic paging: pipes output through a pager like less when it won't fit one screen; --paging=never disables it.
- ✓Non-printable character display via -A/--show-all.
- ✓Configurable output style with --style, toggling components like changes, grid, header-filename, numbers, and snip.
- ✓Theme switching with --theme, plus separate --theme-dark/--theme-light for terminals that switch background color.
- ✓--decorations controls whether line numbers, headers, and grid borders show up even when output is piped.
Using bat with fzf, ripgrep, and man pages
- •Previewing fzf search results: fzf --preview "bat --color=always --style=numbers --line-range=:500 {}" forces colorized output while capping how much of a large file loads.
- •Piping find or fd results through bat for a colorized read of every match, e.g. find … -exec bat {} +.
- •Colorizing man pages by setting MANPAGER="bat -plman", which makes a command like man 2 select render through bat's highlighter.
- •Watching a growing log file with tail -f piped into bat --paging=never -l log for syntax-highlighted tailing.
- •Reviewing an older Git revision of a file, e.g. git show v0.6.0:src/main.rs | bat -l rs.
Installing bat on Linux, macOS, and Windows
On Ubuntu and Debian, install with `sudo apt install bat` — the README notes bat has shipped in Ubuntu since 20.04 ('Focal') and Debian since 11 ('Bullseye'). On some older Debian/Ubuntu releases the executable installs as `batcat` instead of `bat` because of a package name clash; if `bat --version` fails, try `batcat --version`, or symlink it with `ln -s /usr/bin/batcat ~/.local/bin/bat`. Alpine (`apk add bat`), Arch (`pacman -S bat`), Fedora (`dnf install bat`), Gentoo (`emerge sys-apps/bat`), FreeBSD (`pkg install bat`), OpenBSD (`pkg_add bat`), openSUSE (`zypper install bat`), and Nix (`nix-env -i bat`) all carry it in their official repositories, per the README. On macOS, use `brew install bat` or `port install bat` via MacPorts. On Windows, use `winget install sharkdp.bat`, `choco install bat`, or `scoop install bat`, and install the Visual C++ Redistributable first. Building from source needs Rust 1.79.0 or higher: `cargo install --locked bat`.
Basic bat commands and examples
`bat README.md` prints a single file with line numbers and highlighting. `bat src/*.rs` displays multiple files back to back, each with its own header. `bat -n main.rs` shows line numbers only, matching cat's `-n` flag. `bat -A /etc/hosts` reveals non-printable characters the same way `cat -A` does. Piping into bat works too: `curl -s https://sh.rustup.rs | bat` auto-detects syntax from a shebang line, and `-l` lets you force a language when auto-detection has nothing to go on, e.g. `yaml2json .travis.yml | json_pp | bat -l json`. Flags mostly mirror cat's own. `bat f - g` concatenates the file `f`, then stdin, then the file `g`, exactly like cat's multi-argument form.
Strengths
- ✓Auto-detects and highlights syntax for many languages without extra flags, using Sublime Text grammars via syntect.
- ✓Shows Git modification markers in the sidebar automatically, no separate git diff step needed to spot changed lines.
- ✓Falls back to plain, cat-compatible output automatically when piped or redirected, so it's safe to drop into scripts that expect cat's behavior.
- ✓Packaged for most major Linux distros, macOS, and Windows.
Known limitations
- △Auto-detecting the right syntax from stdin only works when the first line carries a clue like a shebang; unlabeled stdin often needs an explicit -l flag.
- △On some older Ubuntu/Debian releases the binary installs as batcat, not bat, so aliasing or symlinking is a manual extra step the README documents but doesn't automate.
- △No official snap package is maintained; the README says unofficial ones may have issues.
- △Custom themes still need the older .tmTheme format — newer .sublime-color-scheme files aren't supported yet.
Alternatives to bat
Frequently asked questions
Install bat on Ubuntu 20.04+ or Debian 11+ with `sudo apt install bat` — both distributions carry it in their official repositories. For a newer release than your distro ships, download the .deb package from bat's GitHub releases page and install it with `sudo dpkg -i bat_<version>_amd64.deb`.
On some older Ubuntu and Debian releases, bat's package installs the binary as `batcat` because the name `bat` already belonged to another package in those repositories. If `bat --version` doesn't work after installing, run `batcat --version` instead, or create a symlink so `bat` still works.
To alias cat to bat, add `alias cat='bat --paging=never'` to your shell's startup file, such as `.bashrc` or `.zshrc`. The `--paging=never` flag keeps bat's behavior closer to plain cat by skipping the automatic pager.
bat can act as a colorizing pager for man pages: set the `MANPAGER` environment variable to `bat -plman` (for example `export MANPAGER="bat -plman"`), then run a normal man command such as `man 2 select`. bat renders the page with syntax highlighting instead of the plain default pager.
Custom syntax definitions go in bat's config directory: create a `syntaxes` folder with `mkdir -p "$(bat --config-dir)/syntaxes"`, drop in a Sublime Text `.sublime-syntax` file, then run `bat cache --build` to compile the binary cache. Check `bat --list-languages` to confirm the new syntax is available.
bat and ccat both add color to cat's output, but bat goes further: it adds a Git-aware sidebar showing modification markers, automatic paging for long output, line numbers, and syntax highlighting sourced from Sublime Text's .sublime-syntax grammars via the syntect library. ccat focuses on coloring alone.
The problem it solves
Reading source code with plain cat gives you a wall of monochrome text with no indication of syntax, no line numbers by default, and no sense of what changed since your last commit. Piping through `less` for paging or running `git diff` separately to see changes means switching tools and losing formatting along the way. bat folds highlighting, line numbers, and Git status markers into the same command you already reach for, so a quick `bat file.py` shows more context than `cat file.py` without adding a second tool to the workflow.
Who should try it — and who should skip
Developers who spend real time reading code, diffs, or config files in a terminal will feel the difference immediately — syntax highlighting and Git markers turn a wall of text into something scannable, and bat's man-page and fzf-preview integrations pay off the moment you wire them in. Anyone writing shell scripts that pipe cat's output into other programs can adopt bat safely too, since it auto-detects non-interactive output and reverts to plain text. Skip it if you're on a locked-down system where installing anything beyond coreutils is off the table, or if you genuinely never read files longer than a few lines — the highlighting and sidebar have nothing to add there.
Related repositories
Curious whether bat is right for you?
Let ChatGPT, Claude, or Perplexity look into it — click below and see what AI actually says about bat.
