HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
BurntSushi
ripgrep
Rust2016–2026
BurntSushi / ripgrep

ripgrep

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

196Distinct people
333Mentions
9Explicit recommenders
69.9KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

ripgrep recursively searches directories for a regex pattern while respecting your gitignore

GitHub

Where it is used

  • Visual Studio Code — Visual Studio Code uses ripgrep to power its text search feature, making searches faster. This integrates ripgrep as the engine behind VS Code’s search. Source
  • Eclipse Theia — Eclipse Theia installs and uses ripgrep under its install directory (resources/app/lib/backend/native/ripgrep), requiring extensions to point to that location because Theia places ripgrep in a different directory than VSCode. Source

What people are saying

> I wrote about how to do error handling without libraries literally the day Rust 1.0 was published: https://burntsushi.net/rust-error-handling/ > > That blog did include a…

osiris88 used a recommendation phrase. 9 indexed comments match. This is a phrase match, not a verdict.

No classified warning is attached to this page. Read the discussions before treating silence as approval.

Also in these discussions

Mentioned in the same Hacker News threads. That is not proof they are substitutes.

This week on Hacker News

Nov 8–Nov 15 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/15/2026, 4:00:59 PM UTC.

No direct repository links were found in the indexed HN discussions over the past seven days. Older discussions are available below.

Mentions over time

HN mentions by year333 dated mentions

Observed mentions: 2016-09-23 15:29:58 UTC to 2026-10-05 14:38:02 UTC.

010203040502016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 25 mentions; 1 submissions, 24 comments20162017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 34 mentions; 3 submissions, 31 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 41 mentions; 5 submissions, 36 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 41 mentions; 1 submissions, 40 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 45 mentions; 3 submissions, 42 comments2021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 37 mentions; 2 submissions, 35 comments20212022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 29 mentions; 1 submissions, 28 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 32 mentions; 3 submissions, 29 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 14 mentions; 2 submissions, 12 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 21 mentions; 3 submissions, 18 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 14 mentions; 4 submissions, 10 comments. Incomplete calendar period.2026*

* An incomplete calendar period is marked with an outlined bar. Its count is not directly comparable with a full period.

Counts come from the repository’s dated source evidence. Index cutoff: 2026-11-02 08:16:59 UTC.

View mention counts and date ranges
UTC ranges include their start and exclude their end. Select a period to filter the source evidence.
PeriodStart (UTC)End (exclusive, UTC)MentionsSubmissionsComments
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC25124
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC34331
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC41536
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC41140
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC45342
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC37235
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC29128
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC32329
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC14212
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC21318
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC14410

What Hacker News says

25 sources
http://blog.burntsushi.net/ripgrep/ There are only seven instances of unsafe: https://github.com/BurntSushi/ripgrep/search?q=unsafe&type=C... Four of them are related to calling libc/kernel32 functions, which need unsafe to be called. One is due to using a memory map, which needs unsafe to be called. Only two are actual unsafe rust functions. That's a "real-world" example though, you're asking for a more specific implementation. I can't compare because my Go would be very poor; if you posted a Go implementation, I'd be willing to give this a shot and write a Rust one. (Mostly out of personal interest, I don't think it really proves anything larger about the two languages.)
In Rust vs C Pitfalls
ripgrep's README will tell you: https://github.com/BurntSushi/ripgrep The short version: 1. It's faster. 2. It's not just faster on code repos, it's also faster than grep itself on single files, so you can use ripgrep in lieu of both ag and grep. 3. It has Unicode support. (More importantly, its Unicode support is fast, and doesn't exhibit huge slow downs like GNU grep does.) 4. Its support for reading gitignore files is quite a bit less buggy than ag. 5. I've heard folks tell me ag was hard to install on Windows, but ripgrep provides first class support for Windows. I've never personally tried ag on Windows, so take that with a grain of salt. The (much) longer version is my blog post, which goes into a lot more detail, specifically on 1+2+3: http://blog.burntsushi.net/ripgrep/
In Ripgrep code review
ripgrep author here! This is a great review, thanks for doing it! I'd like to respond to a few of the bad things pointed out. :P The search code is indeed in a less than ideal state. I've mostly avoided refactoring it because I want to move it to its own separate crate. I've been steadily doing this for other things. Namely, ripgrep used to be a single main crate plus a small regex handling crate (grep), but now it's several: globset, grep, ignore, termcolor and wincolor. I'd like to roll the search code into the grep crate so that others can use it. Once that's done, ripgrep proper will be a pretty small, limited mostly to argv handling and output handling. I do sometimes get overzealous with inline(always) and inline(never). Both are almost always a result of trying things while profiling, and then forgetting to remove them. If you look
Read the rest
closely, most of them are in the core searching code where performance is quite important! Finally, this code review was done while I was in the middle of moving more of ripgrep code out into the `ignore` and `termcolor` crates. The `ignore` crate does all the gitignore handling (which is quite tricky and is now being used by the tokei project: https://github.com/Aaronepower/tokei) and provides a parallel recursive directory iterator, which made ripgrep even faster! The `termcolor` crate handles cross platform coloring shenanigans, including Windows consoles and mintty. It wasn't fun: https://github.com/BurntSushi/ripgrep/issues/94#issuecomment... --- The author did a great job reviewing the previous solution I used for colors though, and was something I really wasn't proud of!
In Ripgrep code review
As the author of ripgrep, I can assure you, the burden on me as the programmer was lifted quite a bit! I probably wouldn't have been able to build it otherwise. (Not because it's physically impossible, but because it would have taken too much time.) It's not like I just rewrote grep. ripgrep is built on a large number of libraries that are reusable in other applications. You can see my progress on that goal here: https://github.com/BurntSushi/ripgrep/issues/162 (And those are only the ones I wrote, nevermind all of the crates I use that have been written by others!)
In Rust and the Future of Systems Programming [video]
> So unless Rust is able to produce binaries on all major platforms that are as fast as C++, people who need to squeeze out as much performance as possible are not going to drop the language. I guess you missed this in the sibling, but ripgrep does this today, and it works on Windows, Mac and Linux, and should be as fast or faster than GNU grep. See benchmarks: http://blog.burntsushi.net/ripgrep/#single-file-benchmarks See binaries: https://github.com/BurntSushi/ripgrep/releases
In Ask HN: What is the state of C++ vs. Rust?
Rust will be if is not already faster than C. Especially in real-life projects. One example would be https://github.com/BurntSushi/ripgrep Aliasing rules in C make some optimizations not possible in C. Good luck putting that `restrict` everywhere to compensate. Generics with static dispatch makes it possible to get a code that is way better than what a sane person can write with C's preprocessor. Practical developer will very often sacrifice performance for sanity in C codebase. Memory safety makes it easy to write correct, reliable multithreaded programs in Rust and actual package manager makes it practical to reuse well-written and optimized code. Even if there are some microbenchmarks where C gives better results, it's because Rust version doesn't "cheat" by using `unsafe` constructs. Essentially in Rust one can write functionally exac
Read the rest
tly same code that C uses, including inline asm etc. which is useful for performance-critical libraries that wrap it in safe abstractions, but would be frowned upon in a tiny synthetic benchmark program that is supposed to benchmark idiomatic code.
In Ask HN: What is the state of C++ vs. Rust?
> It says "Linux binaries are static executables" [0]. They are. Running `ldd` on cargo doesn't confirm or deny this. You need to run `ldd` on the binary distributed: $ curl -sLO 'https://github.com/BurntSushi/ripgrep/releases/download/0.2.1/ripgrep-0.2.1-x86_64…' $ tar xf ripgrep-0.2.1-x86_64-unknown-linux-musl.tar.gz $ ldd ./ripgrep-0.2.1-x86_64-unknown-linux-musl/rg not a dynamic executable This is not the default output on Linux. You need to compile with musl instead of glibc: https://news.ycombinator.com/item?id=12565268
In Stali: A new static Linux distribution
Recently, ripgrep was on the frontpage. It says "Linux binaries are static executables" [0]. If I run ldd on cargo, it spits out the usually glibc dependencies, but Rust libraries are statically linked. It seems to be the default behavior of cargo? I would describe that as "promote static linking". Personally, I don't judge this as good or bad. There is no simple answer. Static linking has clear disadvantage wrt security patches. On the other hand, it makes little sense to dynamically link tiny libraries, e.g. a queue data structure. [0] https://github.com/BurntSushi/ripgrep
In Stali: A new static Linux distribution
I did a brief performance comparison with icgrep here: https://github.com/BurntSushi/ripgrep/issues/63 --- Yes, it does a little better on things like \p{Greek} (and has even better Unicode support than ripgrep) but is missing literal optimizations, which are a ridiculously common case for search tools like this. (As you acknowledged.) Just about every single person who has come to me with a performance comparison of ripgrep has used a simple literal pattern, because that's what people search. You need to knock that case out of the park to be competitive. Even sift and pt do this to some extent. Hyperscan is another top-notch regex implementation worth looking at too, for example. With that said, it does look like icgrep could be added to the single-file benchmark at least, but it is by far the hardest piece of software to actually get in
Read the rest
stalled. (Your build instructions required me to compile llvm.) > But your story is incomplete if you don't include comparison with icgrep My story is incomplete for a very very large number of reasons. icgrep is only one of them. As I said in the blog post, the benchmarks are not only biased, but curated. Of course, I agree icgrep is worth looking into. It's on my list to learn more about. > It also does very well in cases involving alternations and ambiguity. So does ripgrep. :-) $ ls -hl OpenSubtitles2016.raw.en -rw-r--r-- 1 andrew users 9.3G Sep 10 11:51 OpenSubtitles2016.raw.en $ time rg '\w+ Holmes|\w+ Watson|\w+ Adler|\w+ Moriarty|\w+ Lestrade' OpenSubtitles2016.raw.en | wc -l 26464 real 0m30.606s user 0m29.987s sys 0m0.567s $ time icgrep '\w+ Holmes|\w+ Watson|\w+ Adler|\w+ Moriarty|\w+ Lestrade' OpenSubtitles2016.raw.en | wc -l 26464 real 0m41.346s user 0m40.770s sys 0m0.513s $ time rg -i '\w+ Holmes|\w+ Watson|\w+ Adler|\w+ Moriarty|\w+ Lestrade' OpenSubtitles2016.raw.en | wc -l 27370 real 0m17.611s user 0m17.100s sys 0m0.510s $ time icgrep -i '\w+ Holmes|\w+ Watson|\w+ Adler|\w+ Moriarty|\w+ Lestrade' OpenSubtitles2016.raw.en | wc -l 27370 real 0m43.715s user 0m43.193s sys 0m0.523s In the case insensitive search, ripgrep isn't actually doing any literal optimizations, but it is in the first case. Namely, it sees that ` ` is required in every alternate. Since ` ` is so common, this ends up slowing down the search. (This shows how literal optimizations aren't necessarily so simple, because it's easy to make a mistake like I've done and cause search to be slower.) If we change ` ` to `\s+`, we can see ripgrep regain its performance precisely because it can't do any literal optimizations: $ time rg '\w+\s+Holmes|\w+\s+Watson|\w+\s+Adler|\w+\s+Moriarty|\w+\s+Lestrade' OpenSubtitles2016.raw.en | wc -l 26464 real 0m17.607s user 0m17.117s sys 0m0.490s $ time icgrep '\w+\s+Holmes|\w+\s+Watson|\w+\s+Adler|\w+\s+Moriarty|\w+\s+Lestrade' OpenSubtitles2016.raw.en | wc -l 26464 real 0m46.368s user 0m45.883s sys 0m0.483s $ time rg -i '\w+\s+Holmes|\w+\s+Watson|\w+\s+Adler|\w+\s+Moriarty|\w+\s+Lestrade' OpenSubtitles2016.raw.en | wc -l 27370 real 0m17.583s user 0m17.080s sys 0m0.493s $ time icgrep -i '\w+\s+Holmes|\w+\s+Watson|\w+\s+Adler|\w+\s+Moriarty|\w+\s+Lestrade' OpenSubtitles2016.raw.en | wc -l 27370 real 0m48.662s user 0m48.127s sys 0m0.503s Nevertheless, ripgrep outperforms icgrep in every case. Now, with all that said, I bet this is my bias showing. I'm confident you can find other cases (we don't already know about) where icgrep beats ripgrep. :-) BTW, the corpus I used can be got here: http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitl... (The one I used in my benchmark is a sample of this. For these benchmarks here, I used the full file.) The Cyrllic corpus is here: http://opus.lingfil.uu.se/OpenSubtitles2016/mono/OpenSubtitl...
In Ripgrep – A new command line search tool

Showing the 15 most recent of 25 sources. Enable JavaScript to search and browse every indexed mention.

MAKE YOURSELF AT HOME

A few shortcuts

/
Search the collection
?
Open this guide
Esc
Close dialogs and navigation

Your saved repositories and interests stay in this browser.