lsd: How Rust Reimagined the 40-Year-Old ls Command with Icons and Performance
Hook
The Unix ls command hasn’t fundamentally changed since 1979. What if you could get file type icons, tree-view formatting, and extensive color customization while maintaining the speed of a native Rust implementation?
Context
For decades, developers have stared at monochrome directory listings, mentally parsing file extensions to understand what they’re looking at. The ls command outputs text, and while GNU ls added basic color support via LS_COLORS, it remains fundamentally spartan. Ruby’s colorls demonstrated that rich, icon-enhanced listings were possible, but interpreted languages brought performance concerns.
Enter lsd (LSDeluxe), a complete reimplementation of ls in Rust that combines aesthetics with the performance characteristics of a compiled systems language. With over 15,000 GitHub stars, lsd has become a popular ls replacement for developers who spend hours daily in terminals. It renders file type icons via Nerd Fonts, applies sophisticated color schemes, and maintains tree-view formatting—all implemented in Rust, which provides memory safety without garbage collection overhead.
Technical Insight
At its core, lsd is a Rust-based reimplementation of GNU ls with extensive customization capabilities. The tool reads configuration from YAML files, allowing deep customization of colors, icons, and behavior without recompilation. Configuration can be split across three files: config.yaml for general settings, colors.yaml for color theming, and icons.yaml for icon mappings.
The icon system uses Nerd Fonts, where file extensions and types map to Unicode glyphs. Here’s how you’d configure display settings in your config.yaml:
icons:
when: auto # auto, always, never
theme: fancy
separator: " "
color:
when: auto
theme: default
layout: grid # grid, tree, oneline
blocks:
- permission
- user
- group
- size
- date
- name
date: relative # date, relative, +date-format
The blocks configuration demonstrates lsd’s composable output model—each metadata type (permissions, size, dates) is an independent block that can be reordered or removed. The date: relative option allows displaying dates as relative time (e.g., “2 days ago”) instead of absolute timestamps, making temporal context immediately scannable.
The tree-view mode can be invoked with lsd --tree, producing hierarchical output with full icon and color support:
lsd --tree --depth 2
This renders a hierarchical view where directories get folder icons, executables get gear icons, and symlinks show arrow indicators. The color theming system allows extensive customization through the colors.yaml file, and icons can be customized per file type through icons.yaml. Sample configuration files are provided in the project’s documentation folder to help users get started with customization.
Gotcha
The Nerd Font dependency is lsd’s biggest setup hurdle. Out of the box on a fresh system, you’ll see tofu characters (empty boxes) instead of icons until you install and configure a patched font. This isn’t a five-minute setup—you need to download a Nerd Font, install it system-wide, configure your terminal emulator to use it, and potentially adjust font rendering settings. For teams onboarding new developers, this adds friction to dotfile setups.
Script compatibility is another genuine concern. While lsd supports many ls flags, subtle output formatting differences exist. If you have shell scripts that parse ls output (already a code smell, but common in legacy codebases), replacing ls with lsd via an alias can break things. The default grid layout differs from ls’s column behavior, and formatting variations might confuse naive parsing logic. Production automation should use find, stat, or structured tools rather than parsing ls output. The README documentation is explicit about installation requirements but users should be aware that the visual features come with setup overhead.
Verdict
Use lsd if you’re building a developer-focused terminal environment where visual clarity improves productivity, you’ve already invested in Nerd Fonts (or are willing to), and you primarily interact with directories through manual exploration rather than scripting. It’s perfect for daily workflows where distinguishing file types at a glance matters—frontend developers juggling multiple file extensions, DevOps engineers scanning through config files, or any developer navigating large directory structures. Skip lsd if you need guaranteed GNU ls compatibility for legacy scripts, work in constrained environments like minimal Docker images where fonts are impractical, require output parsability for automation (use find -printf or structured alternatives instead), or simply prefer minimalism and don’t value the visual enhancements. For SSH jump boxes and production servers, stick with standard ls to avoid dependency complexity—lsd shines in local development environments where you control the tooling and font configuration.