# macro_railroad: syntax diagrams for Rust macro_rules macros

> macro_railroad is a Rust library that turns a macro_rules! definition into a railway diagram, the kind of syntax chart that explains a macro's matching rules more clearly than the source does. It emits SVG, lays out the diagram through the railroad crate, and there is a browser add-on and a WebAssembly demo that let you paste a macro and see the result without writing any Rust.

**lukaslueg/macro_railroad** — A library to generate syntax diagrams for Rust macros.

- Repository: https://github.com/lukaslueg/macro_railroad
- Stars: 568 · Forks: 13
- Language: Rust
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/lukaslueg-macro-railroad

## A diagram for a matcher nobody can read

macro_railroad is described in the README as a library to generate syntax, railroad, diagrams for Rust's macro_rules!(). The problem it addresses is specific and familiar. A macro_rules matcher is a pattern written in a macro syntax, and once a macro has more than a few arms the source becomes a wall of almost identical lines that a reader has to compare pair by pair. A railway diagram shows the alternatives as a chain of paths, which is the same trick a railroad map plays on a timetable.

The output is Scalable Vector Graphics, and the README notes that layout details are controlled by customizable CSS, which is the important architectural fact about the design. The diagram is not a bitmap or a fixed drawing; it is structured markup that a stylesheet arranges. That is what makes the browser add-on and the WebAssembly demo possible, and it is why the same library can serve a documentation build and an interactive page.

The licence is MIT, the author is Lukas Lueg, the crate version is 0.2.0 on edition 2024, and the last push to the repository was on 2026-10-10. The repository has no GitHub releases, and the crate is published on crates.io.

## The nom method macro, and what the diagram has to represent

The README's worked example is the method macro from nom, and it is a good test case because the macro has many arms that differ in small ways. The definition it puts in front of you starts like this.

```rust
macro_rules! method {
    ($name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => { ... };
    ($name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => { ... };
    ($name:ident<$a:ty,$i:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => { ... };
    ($name:ident<$a:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => { ... };
    ($name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => { ... };
```

The point of the example is that the arms differ along two axes at once. The type parameter list varies in length and position, there is an optional return type, there is an optional pub, and the self parameter is sometimes mutable. A diagram has to show those as choices on a path, and that is exactly what the library is for. The README shows the resulting SVG rendering the nom method diagram, and the generated file lives at examples/nom4_method.svg.

The library does not parse Rust source in general. It works on the macro definition, which it reads with syn, and the Cargo.toml lists syn with the full, parsing and extra-traits features, plus proc-macro2 for the token stream and railroad 0.3.7 for the diagram engine, both with default features turned off.

## Running the examples, and where the HTML comes from

The examples are generated by a cargo example rather than by a separate tool, and the README gives the command.

```bash
cargo run --example various
```

That writes some HTML files to /examples, and the README invites you to hack on the demos in /examples/various.rs. The output format is worth noticing: the deliverable is HTML, not SVG files, because the CSS control the README describes only exists in a document.

The examples directory in the repository shows the range of inputs that are handled. There is src_to_svg.rs for the direct SVG path, extract_from_docs.py for pulling macros out of documentation, and a set of pre-rendered results: nom_examples.html, stdlib_examples.html, syn_examples.html and various_examples.html, alongside individual artefacts such as nom4_method.svg, convert_args.jpeg, handlebars_helper.jpg and stdlib_vec.jpeg.

The macros used as test cases are varied on purpose. The README links the macros from nom-4.1.1 as diagrams, some of the macros from the standard library, the macros from syn-0.14, and some macros from various crates including bitflags, quickcheck and cfg-if. The standard library and syn cases are the interesting ones for a reader, because those are matchers people actually get stuck on.

## A browser add-on and a WebAssembly demo

Two things sit outside the library itself, and both are aimed at the person who wants a diagram without setting up a Rust project.

The first is a browser add-on for Firefox, Chrome and Edge, with its source in a separate macro_railroad_ext repository. The second is a live demo, whose code is in the macro_railroad_wasm repository. The demo is a good indicator of what the library can be used for, because a WebAssembly build means the diagram generation runs in the browser, and the CSS control the README mentions becomes the mechanism for adjusting the layout at runtime rather than at build time.

That combination is what makes the project more than a documentation script. The same core produces the SVG in a crate's README, the diagram in a browser page, and the interactive version in a demo. The trade is that the library is only about macro_rules. Procedural macros, the other kind of Rust metaprogramming, work on a token stream rather than a matcher pattern, and there is nothing in this repository that suggests they are covered.

## Features, benchmarks and a fuzzing directory

The Cargo.toml is short and tells you what the project is and is not. The runtime dependencies are syn, railroad and proc-macro2. The development dependencies include quote for producing Rust code in the tests, railroad_verification, which appears to be a separate crate used to check the generated diagrams, and criterion for benchmarking, with the two bench targets named to_diagram and quick_error and both marked harness = false, which is the criterion convention.

The feature list has two entries, visual-debug which pulls in railroad/visual-debug, and resvg which pulls in railroad/resvg. Both are switches on the diagram engine rather than on this library, which is a useful signal about where the complexity sits. The resvg feature in particular is the one that decides whether you can turn the SVG into a raster without a browser, since the resvg crate is a pure Rust SVG renderer.

The repository layout adds benches/, fuzz/, src/, tests/ and examples/, and the presence of a fuzz/ directory says that the parser is being fuzzed, which matters more for a library that reads untrusted macro text than the README says outright.

## Where macro_railroad is the wrong tool

Three cases point elsewhere. The first is a procedural macro. A proc macro is a function that receives a token stream and returns one, and there is no matcher pattern to draw. A tool that diagrams that would need to show the function body, which is a different kind of diagram and a different kind of problem, and nothing in this repository addresses it.

The second is a team that has already settled on a documentation tool. The output is HTML with CSS, so if your documentation pipeline renders Markdown to a static site with its own asset pipeline, the CSS control the README describes has to survive that pipeline rather than be dropped into it.

The third is a reader who wants to understand the macro by expansion rather than by picture. macro-expansion tools show what a macro produces for a given input, which answers a different question from the one a syntax diagram answers. The diagram tells you which inputs are accepted, and the expansion tells you what comes out, and neither substitutes for the other.

The alternative worth comparing against is hand-drawn or hand-maintained diagrams for the important macros. A small crate with three arms does not need a generator, and a hand-drawn diagram ages better than a generated one because a human updates it when the macro changes. The generator earns its place for the macros where the number of arms makes hand maintenance impractical, which is the nom and syn case in the examples.

## Conclusion

macro_railroad fits a Rust developer documenting a macro whose matcher is hard to read, or a crate author who wants a diagram in the documentation instead of a wall of macro_rules! arms. It does not fit a project that needs diagrams for procedural macros rather than macro_rules ones, and it does not fit a toolchain where you would rather read the expanded expansion. Before you adopt it, read the dependencies in Cargo.toml, because the output shape is decided by the railroad crate and its CSS rather than by this library alone, and check the features list, since the resvg and visual-debug feature flags decide whether you can render the SVG to a raster without a browser.

## FAQ

### What does macro_railroad do?

It is a Rust library that generates syntax, railroad, diagrams for Rust's macro_rules!(). Diagrams are generated as Scalable Vector Graphics, with layout details controlled by customizable CSS, so the same diagram can be restyled after generation. The crate is MIT licensed, at version 0.2.0 on edition 2024.

### Can I try macro_railroad without writing Rust?

Yes. The README links a live demo whose code is in the macro_railroad_wasm repository, and a browser add-on for Firefox, Chrome and Edge with its source in the macro_railroad_ext repository. The examples in the repository itself are generated with cargo run --example various, which writes HTML files to /examples.

### Which Rust macro syntax does macro_railroad handle?

macro_rules! matchers, as the README's example of nom's method macro shows, with the generated SVG saved as examples/nom4_method.svg. The dependency list shows syn with the full, parsing and extra-traits features, proc-macro2 and the railroad crate, so the parsing is done on the macro definition rather than on general Rust source.

### What are the Cargo features of macro_railroad?

There are two, visual-debug which enables railroad/visual-debug and resvg which enables railroad/resvg, both switching on the diagram engine rather than on new parsing behaviour. The crate also has dev-dependencies on quote, railroad_verification and criterion, with two benchmark targets named to_diagram and quick_error.

### Does macro_railroad work with procedural macros?

The README describes the library as generating diagrams for Rust's macro_rules!(), and the examples cover macros from nom, the standard library, syn, and crates including bitflags, quickcheck and cfg-if. A procedural macro is a function over a token stream rather than a matcher pattern, so it does not fall within what the library documents.

## Sources

- [Issues](https://github.com/lukaslueg/macro_railroad/issues)
- [License: MIT](https://github.com/lukaslueg/macro_railroad/blob/master/LICENSE)
- [lukaslueg/macro_railroad on GitHub](https://github.com/lukaslueg/macro_railroad)
- [README](https://github.com/lukaslueg/macro_railroad/blob/master/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lukaslueg-macro-railroad
