Library / SDK
Hejsil/mecha avatar
Hejsil/mecha

Mecha: a parser combinator library for Zig

A parser combinator library for Zig

613 stars31 forksZigMIT

At a glance

What is it?
Mecha is an MIT licensed parser combinator library for Zig, where small parsers are composed into a grammar and each returns a structured result. The README is short, so most of what you learn comes from the RGB example and the three files under example/.
Who is it for?
Adopt Mecha if you are writing a parser in Zig and want composable pieces with typed results instead of a hand rolled index walking function, especially for formats with a clear grammar such as numbers, identifiers or colour literals.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 123 days ago.
What is it written in?
Mainly Zig, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Small parsers composed into a grammar

Mecha is a parser combinator library for the Zig programming language, and the repository description is a parser combinator library for Zig with a matching set of topic tags covering functional parsing, parser combinators and Zig packages. The idea of combinator parsing is that a parser is a value you can combine with other parsers, and the result of a successful parse is data rather than a position in a string. In Mecha the unit of composition is a value that can be mapped, and the README example is a colour parser that shows the whole vocabulary in one place. The tree gives a sense of the size of the project, with mecha.zig at the root, a src/ directory holding the implementation, build.zig and build.zig.zon for the package definition, and an example/ directory with json.zig, math.zig and rgb.zig. It is a small, focused library rather than a framework, and the MIT licence only asks that its copyright notice be kept.

The RGB example shows the combinator vocabulary

The example in the README parses hex colours such as #aabbcc and #abc, and every line of it is a different combinator. mecha.int parses an integer, and it takes a type plus an options struct, where the options set parse_sign to false, base to 16 and max_digits, so the two int parsers in the example differ only in how many hex digits they accept and what type they produce. The result is then mapped, in one case through a toByte callback that expands a single nibble into a byte and in the other case straight to the integer. mecha.manyN applies a parser a fixed number of times, here three, and mecha.toStruct turns the three resulting values into the fields of a struct. The final composition uses mecha.combine to run two parsers in sequence, with mecha.ascii.char('#').discard() consuming the hash and dropping it, and mecha.oneOf to try two alternatives, the two digit form and the one digit form. That is the whole surface of the example: a typed integer parser, a repetition combinator, a struct mapper, a sequence, a discard and an ordered choice.

Parse results are error unions, and the test allocator is the point

Looking at how the example is exercised tells you how the library reports failure. The test block calls rgb.parse with the allocator and the input string, and unwraps the result with try before taking .value.ok, so a parse returns an error union whose success value holds an ok field for the parsed data. The tests use std.testing.allocator, which means the library is expected to allocate while parsing and to be checked for leaks by the standard test allocator. The test cases are also a small specification of the intended behaviour: the same colour is written in the six digit form and the three digit form and must produce the same r, g and b values, and the black case is checked in both forms as well. The four assertions per case are written with expectEqual against explicitly typed u8 values, so a change in the numeric type produced by the parser would fail the test rather than pass silently.

Two zig fetch commands and two lines of build.zig

Installation follows Zig's package manager, and the choice depends on which Zig you build against. The README notes that developers tend to use either the latest tagged release of Zig or the latest build of Zig's master branch, and the two need different fetches. The version that tracks Zig master is pulled straight from the repository:

sh
zig fetch --save git+https://github.com/Hejsil/mecha

A version that works with a tagged Zig release is fetched from a release archive instead, with the version substituted in the URL. Once the dependency is fetched, the build file needs two lines, one to resolve the dependency and one to expose its module to the executable:

zig
const mecha = b.dependency("mecha", .{});
exe.root_module.addImport("mecha", mecha.module("mecha"));

That module import is what makes the import in the example work, since the parser code starts with a plain import of the mecha module alongside std. The build.zig.zon file in the repository is the package metadata that tells Zig where the dependency comes from, so a project pinning a specific mecha version records that in the manifest rather than in code.

Releases track the Zig release cycle

The version history lines up with Zig's own cadence rather than with a feature roadmap of its own. Releases are 0.10.0 on 2025-03-05, 0.11.0 on 2025-08-21 and 0.12.0 on 2026-06-09, and the last push was on 2026-06-22. The 0.x numbering is the important detail, since it signals that the API can still change between minor versions, and the two-track installation described above is the direct consequence. If your project sits on a tagged Zig release, pinning a tagged mecha version is the safe choice, and if you track Zig master you accept that the library tracks it too. Because there is no changelog in the repository root to check, the release page is where you would look before upgrading, and the practical advice is to upgrade the library and the language together rather than one at a time.

What the README does not tell you

There are gaps you should know about before committing. The README does not document error reporting in detail beyond the error union shown in the example, so what a failure looks like for a user who mistypes a colour is something you would have to learn from the source. It also says nothing about backtracking behaviour, about how the library handles ambiguous grammars, or about the cost of the combinators at compile time and at runtime, which for a library that runs in build scripts and in hot paths is a question you would usually want answered. There is no API reference beyond the example and no separate documentation site listed in the repository. The three files under example/ are the practical substitute, and they are the right place to start, since json.zig and math.zig cover two other kinds of grammar that the RGB parser does not.

Editorial conclusion

Adopt Mecha if you are writing a parser in Zig and want composable pieces with typed results instead of a hand rolled index walking function, especially for formats with a clear grammar such as numbers, identifiers or colour literals. Do not adopt it if you need documented error recovery, backtracking guarantees or a performance discussion, because the README does not cover any of those, and check the Zig version alignment first, since the library is published per Zig release and the tagged builds track tagged Zig releases while the git fetch tracks Zig master. Verify first that your project is on a Zig version matching the mecha release you pin, run the example files under example/ as your starting point, and confirm that the combinator vocabulary in the README, int, manyN, combine, oneOf, toStruct and map, covers the grammar you intend to write.

Frequently asked questions

What is Mecha and what does it do?

Mecha is a parser combinator library for Zig. Parsers are values that you map, repeat and combine, and the result of a successful parse is structured data rather than a string position.

How do I install Mecha in a Zig project?

Use zig fetch to add the dependency, either from the repository for a version tracking Zig master or from a release archive for a version matching a tagged Zig release. Then add the dependency to build.zig with b.dependency and expose it with exe.root_module.addImport.

Which combinators does Mecha provide?

The README example shows mecha.int with options such as parse_sign, base and max_digits, mecha.manyN for a fixed number of repetitions, mecha.combine for sequencing, mecha.oneOf for alternatives, mecha.ascii.char for single characters, mecha.toStruct for building a struct, and map to transform results.

How does Mecha report parse failures?

The example unwraps a result with try and then takes the ok field of the value, so a parse returns an error union whose success value holds the parsed data. The example tests use the standard testing allocator, so allocations during parsing are checked for leaks.

Which versions of Mecha and Zig work together?

The README describes two tracks, a version of Mecha that works with a tagged release of Zig and a version that works with the latest build of the Zig master branch, and they are fetched with different zig fetch commands. Releases are 0.12.0 on 2026-06-09, 0.11.0 on 2025-08-21 and 0.10.0 on 2025-03-05.

Official sources

  1. Hejsil/mecha on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hejsil-mecha.svg)](https://hysenlabs.com/projects/hejsil-mecha)

Was this useful?