HackerReposA FIELD GUIDE TO OPEN SOURCE
ProSponsor the shelf♧ 0
← Back to top all-time
rust-bakery
nom
Rust2015–2026
rust-bakery / nom

nom

Rust parser combinator framework

31Distinct people
33Mentions
1Explicit recommenders
10.5KGitHub stars
REPOSITORY AT A GLANCE

What to know before exploring

What it is

Rust parser combinator framework

GitHub

Where it is used

No documented product use was verified in the last source check.

What people are saying

I now use nom to write my parsers. Once you understand it, it’s simple and parsing complex data becomes a _fun_ puzzle. I recommend it. https://github.com/rust-bakery/nom

speedgoose used a recommendation phrase. One indexed comment matches. 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 7–Nov 14 UTC · Direct repository links and separately labeled related project stories. Indexed through 11/14/2026, 10:22:47 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 year33 dated mentions

Observed mentions: 2015-02-26 19:14:56 UTC to 2026-08-07 09:05:28 UTC.

02462015-01-01 00:00:00 UTC to 2016-01-01 00:00:00 UTC (exclusive): 7 mentions; 1 submissions, 6 comments20152016-01-01 00:00:00 UTC to 2017-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2017-01-01 00:00:00 UTC to 2018-01-01 00:00:00 UTC (exclusive): 3 mentions; 0 submissions, 3 comments2018-01-01 00:00:00 UTC to 2019-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments2019-01-01 00:00:00 UTC to 2020-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 comments2020-01-01 00:00:00 UTC to 2021-01-01 00:00:00 UTC (exclusive): 2 mentions; 0 submissions, 2 comments20202021-01-01 00:00:00 UTC to 2022-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2022-01-01 00:00:00 UTC to 2023-01-01 00:00:00 UTC (exclusive): 5 mentions; 0 submissions, 5 comments2023-01-01 00:00:00 UTC to 2024-01-01 00:00:00 UTC (exclusive): 2 mentions; 1 submissions, 1 comments2024-01-01 00:00:00 UTC to 2025-01-01 00:00:00 UTC (exclusive): 0 mentions; 0 submissions, 0 comments2025-01-01 00:00:00 UTC to 2026-01-01 00:00:00 UTC (exclusive): 3 mentions; 1 submissions, 2 comments2026-01-01 00:00:00 UTC to 2027-01-01 00:00:00 UTC (exclusive): 1 mentions; 0 submissions, 1 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
20152015-01-01 00:00:00 UTC2016-01-01 00:00:00 UTC716
20162016-01-01 00:00:00 UTC2017-01-01 00:00:00 UTC505
20172017-01-01 00:00:00 UTC2018-01-01 00:00:00 UTC303
20182018-01-01 00:00:00 UTC2019-01-01 00:00:00 UTC202
20192019-01-01 00:00:00 UTC2020-01-01 00:00:00 UTC101
20202020-01-01 00:00:00 UTC2021-01-01 00:00:00 UTC202
20212021-01-01 00:00:00 UTC2022-01-01 00:00:00 UTC211
20222022-01-01 00:00:00 UTC2023-01-01 00:00:00 UTC505
20232023-01-01 00:00:00 UTC2024-01-01 00:00:00 UTC211
20242024-01-01 00:00:00 UTC2025-01-01 00:00:00 UTC000
20252025-01-01 00:00:00 UTC2026-01-01 00:00:00 UTC312
2026 (partial)2026-01-01 00:00:00 UTC2027-01-01 00:00:00 UTC101

From the project README

An excerpt from the repository, fetched Nov 13, 2026.

Read the project’s introduction
nom, eating data byte by byte nom is a parser combinators library written in Rust. Its goal is to provide tools to build safe parsers without compromising the speed or memory consumption. To that end, it uses extensively Rust's strong typing and memory safety to produce fast and correct parsers, and provides functions, macros and traits to abstract most of the error prone plumbing. nom will happily take a byte out of your files :) Example Documentation Why use nom? Binary format parsers Text format parsers Programming language parsers Streaming formats Parser combinators Technical features Rust version requirements Installation Related projects Parsers written with nom Contributors Example Hexadecimal color parser: use nom::{ bytes::complete::{tag, take_while_m_n}, combinator::map_res, sequence::Tuple, IResult, Parser, }; #[derive(Debug, PartialEq)] pub struct Color { pub red: u8, pub green: u8, pub blue: u8, } fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> { u8::from_str_radix(input, 16) } fn is_hex_digit(c: char) -> bool { c.is_digit(16) } fn hex_primary(input: &str) -> IResult<&str, u8> { map_res( take_while_m_n(2, 2, is_hex_digit), from_hex ).parse(input) } fn hex_color(input: &str) -> IResult<&str, Color> { let (input, _) = tag("#")(input)?; let (input, (red, green, blue)) = (hex_primary, hex_primary, hex_primary).parse(input)?; Ok((input, Color { red, green, blue })) } fn main() { println!("{:?}", hex_color("#2F14DF")) } #[test] fn parse_color() { assert_eq!( hex_color("#2F14DF"), Ok(( "", Color { red: 47, green: 20, blue: 223, } )) ); } Documentation Reference documentation The Nominomicon: A Guide To Using Nom Various design documents and tutorials List of combinators and their behaviour If you need any help developing your parsers, please ping geal on IRC (Libera, Geeknode, OFTC), go to #nom-parsers on Libera IRC, or on the Gitter chat room. Why use nom If you want to write: Binary format parsers nom was designed to properly parse binary formats from the beginning. Compared to the usual handwritten C parsers, nom parsers are just as fast, free from buffer overflow vulnerabilities, and handle common patterns for you: TLV Bit level parsing Hexadecimal viewer in the debugging macros for easy data analysis Streaming parsers for network formats and huge files Example projects: FLV parser Matroska parser tar parser Text format parsers While nom was made for binary format at first, it soon grew to work just as well with text formats. From line based formats like CSV, to more complex, nested formats such as JSON, nom can manage it, and provides you with useful tools: Fast case insensitive comparison Recognizers for escaped strings Regular expressions can be embedded in nom parsers to represent complex character patterns succinctly Special care has been given to managing non ASCII characters properly Example projects: HTTP proxy TOML parser Programming language parsers While programming language parsers are usually written manually for more flexibility and performance, nom can be (and has been successfully) used as a prototyping parser for a language. nom will get you started quickly with powerful custom error types, that you can leverage with nom_locate to pinpoint the exact line and column of the error. No need for separate tokenizing, lexing and parsing phases: nom can automatically handle whitespace parsing, and construct an AST in place. Example projects: PHP VM xshade shading language Streaming formats While a lot of formats (and the code handling them) assume that they can fit the complete data in memory, there are formats for which we only get a part of the data at once, like network formats, or huge files. nom has been designed for a correct behaviour with partial data: If there is not enough data to decide, nom will tell you it needs more instead of silently returning a wrong result. Whether your data comes entirely or in chunks, the result should be the same. It allows you to build powerful, deterministic state machines for your protocols. Example projects: HTTP proxy Using nom with generators Parser combinators Parser combinators are an approach to parsers that is very different from software like lex and yacc. Instead of writing the grammar in a separate file and generating the corresponding code, you use very small functions with very specific purpose, like "take 5 bytes", or "recognize the word 'HTTP'", and assemble them in meaningful patterns like "recognize 'HTTP', then a space, then a version". The resulting code is small, and looks like the grammar you would have written with other parser approaches. This has a few advantages: The parsers are small and easy to write The parsers components are easy to reuse (if they're general enough, please add them to nom!) The parsers components are easy to test separately (unit tests and property-based tests) The parser combination code looks close to the grammar you would have written You can build partial parsers, specific to the data you need at the moment, and ignore the rest Technical features nom parsers are for: byte-oriented: The basic type is &[u8] and parsers will work as much as possible on byte array slices (but are not limited to them) bit-oriented: nom can address a byte slice as a bit stream string-oriented: The same kind of combinators can apply on UTF-8 strings as well zero-copy: If a parser returns a subset of its input data, it will return a slice of that input, without copying streaming: nom can work on partial data and detect when it needs more data to produce a correct result descriptive errors: The parsers can aggregate a list of error codes with pointers to the incriminated input slice. Those error lists can be pattern matched to provide useful messages. custom error types: You can provide a specific type to improve errors returned by parsers safe par
Read the full README on GitHub

What Hacker News says

3 sources
From what I can find[1] it looks like while Julia has compact values it doesn't have what I'd traditionally call value types. Specifically value types that live on the stack unless they are a member of a reference type(which is what C# does). Looking at the performance docs[2] this is pretty clear in that array types(which looks like how Julia does Matrices) get allocated on the heap. You can clearly see the performance impact in the docs(1.95s vs 0.08s) that this type of behavior has. While you can preallocate(which the docs suggest and is the only path for GC'd languages) it's not an ideal solution. If your type is smaller than a single cache line, like in the example above, you've just flushed a whole cache line just to bring in that one pre-allocated value. You also run into the issue if you don't know exactly how many values you need
Read the rest
upfront which leads to pooling. In that scenario your pool may be large enough that you're bouncing between cache lines on different pooled objects. This is the type of thing that you really need control over if you want performance "as good as C". Anything less will be a compromise. There's also the whole class of zero-cost abstractions that can get from C++/Rust which leverage all the above to great effect. That lets you get things like nom[3] which gives you high level semantics + productivity while maintaining parity with C. None of this is academic, these are all optimizations I've used on shipping products that went out to millions of users. In each case we had fixed hardware with a limited execution budget and the 5-20x improvements we made were critical to us shipping a product that people wanted to use. [1] https://discourse.julialang.org/t/how-to-know-if-object-memo... [2] https://docs.julialang.org/en/release-0.4/manual/performance... [3] https://github.com/Geal/nom_benchmarks/tree/master/http / https://github.com/Geal/nom
In Some Insights from a Julia Developer
Many suggest resources for compiler implementations, i personally would start prototyping the language itself, think about it's type system and its runtime properties. There are many possibilities in terms of type systems, from static to dynamic and everything in between, concepts like linear types, algebraic types, etc. Runtime properties are things like it's memory model (garbage collection, yes or no). All of this depends on the purpose of your language. The second part would be choosing a platform to run on (so you only have to write a compiler frontend). There are many great technologies to host a language, but i'd advocate two specific ones here: * https://github.com/zetavm/zetavm (shoutout to @love2code) * https://llvm.org/ ZetaVM is a great target for dynamicly typed and/or jit compiled languages like python or javascript. LLVM is
Read the rest
used in many low level / near metal languages like C, C++, rust and so on. None of both must be your final targets, your compiler frontend can be moved to target another platform like the JVM later. As a last part, implement your compiler frontend. This involves lexing/parsing source code, type checking if needed and generating your target's intermediate representation. I personally prefer hand-written recursive descent parsers using a parser combinator framework (like https://github.com/Geal/nom) over parser generators. For further processing like type checking, there is the common monolith aproach and the nanopass framework/approach https://www.youtube.com/watch?v=Os7FE3J-U5Q Also there's a great series on compiler frontends by Alex Aiken: https://www.youtube.com/watch?v=sm0QQO-WZlM&list=PLFB9EC7B8F... Hope this gives an overview. :)
In Ask HN: Resources for building a programming language?
Gotta love Parsec for Haskell and pyparsing for Python. Some other awesome parsing libs: PEGTL - C++ Parsing Expression Grammar Template Library https://github.com/taocpp/PEGTL Parboiled - Java & Scala PEG Library https://github.com/sirthias/parboiled Nom - Rust parser combinator framework https://github.com/Geal/nom Nearley - JavaScript parser toolkit https://github.com/Hardmath123/nearley Neotoma - Erlang library and packrat parser-generator for PEGs https://github.com/seancribbs/neotoma
In What the heck is a parser-combinator?

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.