Systems & CLI · Beginner
minigrep: A Search Tool from Scratch
Build a command-line text search tool that recurses directories, matches patterns, and prints colored line-numbered hits.
minigrep is a command-line search tool you build in Rust that reads a pattern and a path from the user, walks the filesystem recursively, and prints every matching line with its filename, line number, and optional color highlighting. It is worth building because it teaches you how real tools like grep and ripgrep work internally while giving you hands-on practice with Rust's ownership model, error handling, and standard library I/O. The project is small enough to finish in a weekend yet rich enough to expose you to argument parsing, file traversal, regular expressions, and terminal output all in one coherent program.
What you build
- Accepts a regex pattern and a file or directory path as CLI arguments via clap
- Recursively walks directories using Rust's standard fs module or the walkdir crate
- Matches each line against the pattern using the regex crate
- Prints matching lines with filename, 1-based line number, and the matched text
- Highlights matched substrings in color using ANSI escape codes when the terminal supports it
- Exits with a non-zero code when no matches are found, enabling scripting and pipelines
- Respects a --ignore-case flag for case-insensitive matching
What it teaches
- Rust ownership, borrowing, and error propagation with the Result type across file I/O boundaries
- Building typed CLI interfaces with clap's derive API including flags, options, and positional arguments
- Compiling and applying regular expressions at runtime using the regex crate
- Recursive filesystem traversal and handling of permission errors gracefully
- Writing composable functions that separate argument parsing, file reading, matching, and output
- Using ANSI escape codes or a terminal-color crate to produce readable CLI output
How it works
- 1
Parse Args
- pattern (regex string)
- path (file or dir)
↓ clap derive struct
- 2
Walk Filesystem
- if file: open directly
- if dir: recurse entries
↓ walkdir or std::fs
- 3
Match Lines
- compile Regex once
- test each line
↓ regex crate
- 4
Format Output
- filename + line number
- colored match highlight
↓ ANSI or colored crate
- 5
Exit Code
- 0 = matches found
- 1 = no matches
Sign in to open the build guide
Free account. Get the step-by-step build and every resource link.
Take it further
- Add a --count flag that prints only the number of matching lines per file instead of the lines themselves.
- Support reading from stdin when no path argument is given, making minigrep composable in shell pipelines.
- Respect .gitignore rules by integrating the ignore crate so that vendor directories and generated files are skipped automatically.


