Part of Ferramenta, a family of Rust tools.
Ferriki
Ferriki is Shiki-compatible syntax highlighting with a leaner Rust core and Node bindings.
It keeps the API shape people already know from Shiki, but removes the old JS/WASM multi-engine direction from the runtime. The goal is simple: keep the developer experience familiar, move the heavy lifting into Rust, and end up with a smaller, cleaner architecture that is easier to reason about and easier to ship.
Why Ferriki
- Shiki-compatible where it matters: existing highlighting-oriented Node APIs stay recognizable.
- Rust-first by design: grammar handling, theme application, state management, and rendering belong in the native core.
- Standard language and theme assets load lazily from a release-pinned CDN, so their payloads stay out of the packages.
- Leaner runtime shape: no product dependency on the historical JS/WASM engine stack.
- Verifiable compatibility: the Node layer is checked against a strict mirrored Shiki release-tag suite, while the tokenizer is checked against a pinned vscode-textmate oracle.
Ferriki is for teams that like the Shiki contract, but want a cleaner native foundation under it.
Product Scope
Ferriki is intentionally narrow right now.
| Area | Status | Notes |
|---|---|---|
| Core highlighting runtime | Integrated | Native Rust core, Node bindings, Shiki-compatible highlighting API |
| HTML output | Primary Node path | codeToHtml renders HTML; styleMode: "classes" adds nested scope classes; codeToHtmlWithCss also returns resolved theme CSS |
| HAST and token output | Supported | codeToHast and token APIs remain available for consumers that need structured output |
| Transformers | Integrated | User-supplied JavaScript hooks run in the facade (ADR 0008) |
| Optional Vite adapter | Available | @ferriki/vite highlights marked HTML and static JSX during Vite transforms, outside the core runtime |
colorized-brackets, markdown-it, rehype, and VitePress integrations |
Out of scope | These remain optional adapter projects, not Ferriki core exports |
Whether every public Node HAST and token export remains in the 1.0 contract is still open; see ADR 0017.
The mirrored Shiki workspace under node/compat/upstream/shiki exists to verify compatibility claims. It is not a statement that every mirrored package is a Ferriki feature.
Products
This repository has a Rust library and a Node package:
ferriki(repository root package): reusable Rust highlighter and renderernode/ferriki: the Node-facing package surface
The private ferriki-core crate hosts the N-API binding
over the same Rust runtime.
Repository Layout
src: theferrikicrate, native highlighter and asset catalogscrates/ferriki-core: N-API hostnode/ferriki: Node packagenode/compat/harness: Ferriki-specific compatibility gluenode/compat/upstream/shiki: strict upstream Shiki mirrornode/compat/upstream/vscode-textmate: strict tokenizer source and test oracleadr: architecture decision records (index)
Contributor workflow, test lanes, and the mirror rules are documented in
CONTRIBUTING.md.
User-facing documentation lives in the docs/ directory:
- Ferriki API reference
- Rust API and Ferromark integration
- Shiki migration guide
- Compatibility and support policy
- Troubleshooting
- Ferromark + Ardo example
The repository root is intentionally Rust-first. All Node, npm, and upstream
compatibility machinery lives under node.
Quick Start
Prerequisites: a stable Rust toolchain (cargo), Node.js >= 22.13.0, and pnpm
(the pinned version in node/package.json is picked up via corepack).
Rust:
Node (build:native compiles the Rust core and copies the addon into the
package):
The compatibility workspace contains upstream prepare scripts that rewrite
generated files. Installs intentionally skip package lifecycle scripts; the
explicit prepare:compat command runs those generators in a temporary
checkout and keeps the tracked mirror immutable.
The TextMate compatibility lane runs selected, unchanged Shiki tests with
honest aliases so every highlighted result passes through the native addon.
The broader test:ferriki-compat:core lane also runs the Ferriki-owned API,
error, catalog, registration, multi-theme, transformer, token-state, packaging,
and Ferromark/Ardo contract checks. Upstream cases outside that accepted
boundary remain explicitly classified in the compatibility manifest.
Class-based output (next release)
Inspired by GitHub's PrettyLights and wooorm's starry-night.
Use styleMode: "classes" for nested scope classes and custom CSS.
codeToHtmlWithCss returns { html, css } using unchanged TextMate themes,
including theme maps that switch via data-ferriki-theme without retokenizing.
See the class-based highlighting guide for examples and integration details.
Compatibility
Ferriki tracks one approved Shiki release tag at a time — currently
Shiki v4.4.3 (machine-readable source of truth:
node/compat/upstream/shiki/.source.json).
- Upstream-derived files under
node/compat/upstream/shikiare mirrored, not hand-edited. - vscode-textmate source and tests under
node/compat/upstream/vscode-textmateare likewise pinned and never hand-edited. - Ferriki-specific behavior lives outside that mirror, mainly in
node/compat/harnessand the Ferriki product paths. - “Shiki-compatible” in this repository means compatibility is intended to be checked, not just claimed.
- Compatibility coverage is broader than product scope. Ferriki may still test selected optional upstream adapters separately, but that does not make them first-class Ferriki features.
Status
The native TextMate runtime from issue #30 is implemented. It is a mechanical port of pinned vscode-textmate v9.3.2 onto the Scanner API of Ferroni, integrated with Ferriki's asset catalogs, native renderer, N-API host, and focused Node surface. Its inner vscode-textmate oracle and honest Shiki v4.4.3 structural gate are green.
The accepted API contract and its focused checks own token/state, lifecycle, transformer, and registration behavior. Upstream adapter fixtures that do not describe Ferriki's native boundary remain classified as explicit non-goals. The current core direction is:
- Rust owns runtime behavior
- Node is the thin facade and compatibility layer
- optional ecosystem adapters do not define the core product boundary or release gate
License
Licensed under either of MIT or Apache-2.0 at your option.
More from Ferramenta
Ferramenta — A family of Rust tools.
Engines
| Tool | Job |
|---|---|
| ferroni | Oniguruma-compatible regex engine |
| 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 |