ripgrep vs ack
ack pioneered developer-friendly code search and introduced the idea of skipping irrelevant files automatically. ripgrep carries those ideas forward with native performance that's 40× faster — no Perl required.
Quick Verdict
ack is well-designed and pleasant to use, but it's written in Perl and therefore limited by Perl's I/O and regex throughput. On the Linux kernel source tree, ack takes over 3 seconds while ripgrep finishes in 0.08 seconds — a 40× difference. If you're a current ack user, switching to ripgrep gives you the same developer-friendly experience at a fraction of the time. The flags are similar enough that the learning curve is minimal.
Feature Comparison
| Feature | ripgrep | ack |
|---|---|---|
| Speed (large codebase) | ✅ Fastest | 🐢 ~40× slower |
| Respects .gitignore | ✅ Yes (default) | ⚠️ Partial (.ackrc) |
| Skips hidden files | ✅ Yes (default) | ✅ Yes (default) |
| Skips binary files | ✅ Yes (default) | ✅ Yes (default) |
| Unicode support | ✅ Always on | ✅ Yes (Perl) |
| PCRE2 regex | ✅ With -P | ✅ Perl regex always |
| File type filtering | ✅ -t flag | ✅ --type flag |
| Compressed file search | ✅ With -z | ❌ No |
| Single binary | ✅ Yes | ✅ (Perl script) |
| JSON output | ✅ --json | ❌ No |
| Config file | ✅ .ripgreprc | ✅ .ackrc |
| Windows support | ✅ Native | ⚠️ Requires Perl |
| No runtime required | ✅ Yes | ❌ Requires Perl |
| Actively maintained | ✅ Yes | ✅ Yes (slowly) |
Speed
ack's Perl implementation is the primary bottleneck. On the Linux kernel source tree, ack takes 3.2 s vs ripgrep's 0.08 s — about 40× slower. ack also doesn't parallelize directory traversal, so the gap is especially pronounced on multi-core systems.
See the benchmarks page for full data.
When to use each
Use ripgrep when:
- ✓Speed matters at all
- ✓You don't want a Perl dependency
- ✓You need Windows native support
- ✓You want JSON output or compressed file search
- ✓Searching large codebases (monorepos, Linux kernel scale)
ack may suit you if:
- →You already have Perl and a complex .ackrc
- →You rely on ack-specific Perl regex features
- →Your searches are on small codebases where speed is irrelevant
Command Equivalents
| Task | ripgrep | ack |
|---|---|---|
| Basic search | rg 'pattern' | ack 'pattern' |
| Case-insensitive | rg -i 'pattern' | ack -i 'pattern' |
| Word boundary | rg -w 'word' | ack -w 'word' |
| Invert match | rg -v 'pattern' | ack -v 'pattern' |
| Count matches | rg -c 'pattern' | ack -c 'pattern' |
| List matching files | rg -l 'pattern' | ack -l 'pattern' |
| Context (3 lines) | rg -C 3 'pattern' | ack -C 3 'pattern' |
| Only Python files | rg -t py 'pattern' | ack --python 'pattern' |
| Only JS/TS files | rg -t js -t ts 'pattern' | ack --js --ts 'pattern' |
| Search hidden files | rg -. 'pattern' | ack --unrestricted 'pattern' |
| Fixed string | rg -F 'literal' | ack -Q 'literal' |
| Show file names only | rg -l 'pattern' | ack -l 'pattern' |
Migration from ack
Most ack flags have direct ripgrep equivalents. The main differences: file types use
-t typename instead of
--typename, and the fixed-string
flag is -F instead of
-Q.
# ack --python 'def ' → ripgrep equivalent
rg -t py 'def '
# ack -Q 'literal.string' → ripgrep equivalent
rg -F 'literal.string'
# ack --unrestricted → ripgrep equivalent (search everything)
rg -uu 'pattern'
# Convert your .ackrc to .ripgreprc
# .ackrc: --color
# .ripgreprc: --color=always
# Shell alias for muscle memory
alias ack='rg'