Part of Ferramenta, a family of Rust tools.
Ferroni — Oniguruma's regex engine, modernized in Rust
Full Oniguruma syntax for Rust: look-behind, backreferences, conditionals,
Unicode properties, and the multi-pattern scanner that TextMate grammars run
on. One cargo add, no C compiler, memory-safe, and faster than the C
original.
Oniguruma is the regex engine TextMate grammars are written for, which puts it underneath VS Code, Shiki and most syntax highlighters. jq and PHP's mbregex use it too. Its C project ended in April 2025. Ferroni ports the engine to Rust line by line, checks it against the upstream test suite, and adds what C Oniguruma never shipped: Unicode 18.0 data, a vscode-oniguruma-compatible scanner, a compile-time check for catastrophic backtracking, and an idiomatic Rust API.
- Same engine, verified. All 2,974 upstream UTF-8 test cases pass. The port keeps Oniguruma's parser, compiler and optimizer, so a pattern behaves as it does in C (how compatibility is checked).
- Easy to add.
cargo add ferroniis the whole setup: no C toolchain, no bindgen, six common dependencies. An idiomatic API ofRegex,Capturesand match iterators sits on top, and a compiledRegexisSend + Sync(getting started). - Safe with untrusted input. Memory-safe Rust with
unsafeconfined to the links between parse-tree nodes, timeouts and backtracking limits per search, and fuzzing on every pull request (untrusted input). - Faster than the original. Ahead of C Oniguruma in every measured workload, from everyday text processing to syntax highlighting (performance).
Quick start
use *;
Syntax highlighters ask many patterns at once which one matches next.
Scanner answers that with the shape of vscode-oniguruma's scanner, UTF-16
offsets included:
use *;
let mut scanner = new.unwrap;
let line = r#"const x = "hello" // greeting"#;
let m = scanner.find_next_match.unwrap;
assert_eq!; // the keyword pattern matched first
assert_eq!;
The guide continues with
captures and iteration,
options and syntax modes,
the Scanner API,
error handling and
the low-level C API.
Runnable versions of both snippets are in examples/:
cargo run --example basic_match and cargo run --example scanner_tokenize.
When to use Ferroni
Ferroni is for code that needs Oniguruma's syntax or behavior:
- Syntax highlighting and editors. TextMate grammars rely on look-behind,
\Ganchors, backreferences and Oniguruma's own quantifier syntax. Ferriki, a Shiki-compatible highlighter, tokenizes them with Ferroni's scanner. - Patterns the
regexcrate cannot run. Look-around, backreferences, conditionals, subexpression calls and recursion, absent expressions, possessive quantifiers, and twelve syntax modes from Perl and Ruby to POSIX. - Dropping the C library. If you link C Oniguruma today, Ferroni runs the same UTF-8 patterns without a C toolchain in your build.
When your patterns fit the syntax of Rust's
regex crate, use that instead: it
guarantees linear-time matching and is usually faster on plain text search.
Features
- Full Oniguruma syntax: look-ahead and variable-length look-behind, atomic
groups, possessive quantifiers, named groups in three spellings,
backreferences by number, name and relative position, conditionals
(?(cond)T|F), absent expressions(?~...), subexpression calls\g<name>, and callouts. - Unicode 18.0: 914 property names such as
\p{Greek},\p{Lu}and\p{Emoji}, grapheme clusters\X, text segment boundaries\yand\Y, and full case folding, so(?i)straßefindsSTRASSE. C Oniguruma's last release ships Unicode 16.0 (ADR-015). - 12 syntax modes: Oniguruma, Ruby, Perl, Perl_NG, Python, Java, Emacs, Grep, GNU, POSIX Basic, POSIX Extended and ASIS.
- A scanner for highlighters: vscode-oniguruma's multi-pattern API with UTF-16 offsets, a result cache per string, and a pattern cache that scanners share (ADR-006).
- Limits: time, retry, stack and nesting limits, process-wide or per search.
- Two APIs: the idiomatic
RegexAPI, and every C entry point under its original name (onig_new,onig_search, ...).
Performance
How Ferroni compares with seven other engines on three kinds of work. Each figure is the geometric mean over every task in the workload, on two test machines.
| Ferroni compared with | Everyday patterns | Advanced patterns | Syntax highlighting |
|---|---|---|---|
| Oniguruma (C) | 2.2× faster | 1.4× faster | 12× faster |
| Shiki JS | – | – | 6.1× faster |
| Onigmo | 2.6× faster | 1.5× faster* | 34× faster |
| PCRE2 | 1.7× faster* | 1.4× faster* | 28× faster |
| PCRE2 JIT | 2.1× slower* | 3.5× slower* | 9.7× faster |
| fancy-regex | 1.0× slower* | 3.0× faster* | 1.5× faster |
| regex | 1.5× slower* | – | – |
- Everyday patterns (32 tasks): search and extraction in HTML, logs, chat with emoji, Markdown, JSON, CSV and source code, in syntax the regex crate also runs.
- Advanced patterns (17 tasks): look-around, backreferences, possessive groups, subexpression calls, absent expressions and grapheme clusters.
- Syntax highlighting (3 documents): the scanner calls Shiki makes for whole C, Java and PHP documents, in grammars every engine runs.
* Ran only some of the tasks: the engine rejects a pattern or finds different matches. The figure covers the tasks it ran.
– Not measured: the engine lacks the syntax, or the multi-pattern API the workload needs.
fancy-regex is quoted in its fastest configuration per column: seek mode for everyday patterns and advanced patterns; RegexSet for syntax highlighting.
Measured 2026-10-09 on Blacksmith's macOS arm64 (Apple M4 Pro) and Linux x86-64 (AMD EPYC) runners. Every engine first has to reproduce Oniguruma's results before it is timed. These are observations on the measured workloads, not a promise for every pattern or machine.
Where Ferroni is behind, the table says so: Rust's regex crate and PCRE2's
JIT are faster on most text tasks whose syntax they support, C Oniguruma wins
a few individual tasks, and grammar compilation is mixed. Per-host figures,
every task and the raw data:
- Text processing, task by task
- Highlighting replays and complete TextMate grammars
- Compilation and short searches
- Tasks an engine cannot run
- Memory use
Correctness and safety
- Test parity. Every upstream test file for UTF-8 is ported case by case:
2,974 C test cases and the vscode-oniguruma scanner tests, all passing
(parity table). With
Ferroni's own tests the tree holds at least 2,500
#[test]functions, counted byscripts/count-tests.sh. - Coverage gate. CI measures line coverage on every pull request and fails
below the threshold set in
scripts/coverage.sh. - Fuzzing. Pattern compilation, matching and the scanner are fuzzed on every pull request, and for longer every week.
- Memory safety. C Oniguruma has a history of memory-safety CVEs in its
buffer and string handling. Ferroni keeps that code in safe Rust; the
remaining
unsafe, 10 sites, covers only the links between parse-tree nodes during compilation (ADR-002). - Hostile patterns and input. Per-search timeouts and retry limits stop
runaway backtracking, and a compile-time check flags patterns such as
(a+)+(untrusted input).
Scope
Ferroni supports ASCII and UTF-8, two of Oniguruma's 29 encodings. That covers
TextMate grammars, since vscode-oniguruma compiles every pattern as UTF-8, and
jq; PHP's mbregex in a non-UTF-8 encoding is not covered. The POSIX and GNU
APIs (regcomp, regexec) are not ported either
(what is covered).
Documentation
| Where | What |
|---|---|
| Guide | Install, match, capture, scan, and handle errors |
| Untrusted input | Limits, backtracking checks, and memory safety |
| Compatibility | What is covered, test parity, and how the port maps to C |
| Migrating to 2.0 | The breaking changes of 2.0, with before and after code |
| Performance | Every benchmark, with hosts, versions and raw data |
| Architecture decisions | Why the port is built the way it is |
| API reference | Every type and function on docs.rs |
Project status
Ferroni is feature-complete for its scope and maintained, with no feature work planned. The scope is Oniguruma's syntax for ASCII and UTF-8, and the vscode-oniguruma scanner.
The project maintains:
- bug fixes and parity fixes against C Oniguruma,
- the annual Unicode update,
- Rust toolchain and dependency upkeep,
- security fixes for the latest release. SECURITY.md explains how to report a vulnerability and what to expect.
Not planned:
- the other 27 of Oniguruma's 29 encodings (ADR-003),
- the POSIX and GNU APIs (ADR-012),
- an opt-in Onigmo syntax (#159).
Issues are welcome and are triaged as time allows. Pull requests are reviewed
against the architecture decisions,
starting with structural parity with C Oniguruma. The help wanted label marks
the issues that are waiting for a contributor.
One integration is still open: Ferroni as a regex backend for syntect (#252).
Contributing
Contributions are welcome. CONTRIBUTING.md covers the build, the test suites, the benchmarks and the coverage gate. The architecture decisions describe the constraints a change has to keep, starting with structural parity with the C original.
Acknowledgments
Ferroni is built on the work of K. Kosako and the Oniguruma contributors. The C original powers regex in PHP, TextMate, jq and many other projects, and Ruby's engine, Onigmo, started as a fork of it. The Scanner API and its test suite are based on vscode-oniguruma by Microsoft and the VS Code team.
Oniguruma ended in April 2025. Ferroni is an independent continuation by Sebastian Software; it is not affiliated with or endorsed by the original author.
License
BSD-2-Clause (same as Oniguruma)
Ferroni is the one Ferramenta tool that is not published under MIT OR Apache-2.0: it is a line-by-line port of Oniguruma's C source, so it stays
under the BSD-2-Clause license of the code it is derived from.
More from Ferramenta
Ferramenta — A family of Rust tools.
Engines
| Tool | Job |
|---|---|
| ferriki | Shiki-compatible syntax highlighting |
| ferromark | Markdown to HTML, sanitized by default |
| ferrolex | Spell checking for text and code |
| ferrocat | Translation catalog engine |
| ferralk | Glob matching and parallel filesystem walking |
| ferrugo | PDF previews for untrusted files |
Applications
| Tool | Job |
|---|---|
| palamedes | Internationalization for TypeScript applications |
| dalo | Your team's agent setup, versioned like code |