Is Sätteri Worth Adopting? Astro 7's Rust Markdown Engine
Published: 2026-07-11
Astro 7 makes Sätteri the default markdown engine, and for a brand-new site that’s a non-decision — you take the faster Rust pipeline and never think about it again.
The decision only gets interesting when you already have a markdown setup that works. My blog does: a custom pipeline with KaTeX for math and a couple of small rehype plugins, which Astro still lets me keep through an escape hatch. Adopting Sätteri would cost me those plugins. It was a trade, and I had to decide whether it was worth making.
I worked through the evaluation properly anyway, even though I already knew which way I was leaning. This is the evaluation I wish I’d been able to read first: what Sätteri handles on its own, what it leaves you to write, and the one native feature that didn’t cover my setup.
If you’ve already decided and want the mechanics, I wrote up the actual port of my KaTeX pipeline separately. This post is about whether to make that decision at all.
The good case: adopting means deleting code
The honest starting point is that Sätteri is not a stripped-down parser. Its Rust core natively implements much of what people install plugins for. GFM and frontmatter are on by default, so you get tables, footnotes, strikethrough and task lists without asking. Behind opt-in flags there’s more: heading attributes, smart punctuation, and math parsing. On top of that, its Astro wrapper adds Shiki highlighting and image collection.
So if your pipeline is “standard markdown, plus GFM, plus syntax highlighting,” Sätteri likely covers all of it. For you, adopting it means deleting code — remark-footnotes and remark-gfm go, and you get a faster build for the trouble. That’s the good case, and it’s the common one. Stop reading and take the default.
This post is for the other case.
What you’d have to rewrite
My pipeline isn’t the good case, and the reason is one word: parsing.
Sätteri parses $$...$$ into a math node. It does not turn that node into visual output — no <span class="katex">, no MathML. Rendering the LaTeX is what rehype-katex does today, and Sätteri has no native equivalent. Whatever the engine only parses, you still have to render.
Nor can you bring your existing plugin along. Sätteri runs no remark or rehype plugins at all, and its docs are blunt about why:
“Sätteri’s plugin API isn’t compatible. Existing remark/rehype plugins won’t run unmodified… No direct adaptation path exists.”
The AST lives in Rust, so a plugin that mutates the tree directly can’t work. You describe changes through a context object instead. It’s a different shape, not a harder one — but it means any plugin you rely on that has no native equivalent becomes code you own. For me that was KaTeX rendering, plus a few lines to put target and rel on outbound links.
So the question isn’t “can I port my plugins” — the docs answer that, and the answer is no. The question is how much of your pipeline falls into that category, and how much work it is once it does.
The native feature that didn’t fit my setup
Counting plugins gets you an estimate. It missed something for me.
Image collection is native, which sounds like it replaces the logic I use to pick a post’s first image as its OG image. But the collector skips root-absolute URLs:
} else if (!url.startsWith('/')) {
astro?.localImagePaths.add(url);
}
Every image on my blog is written as /blog/<slug>/... — root-absolute, by convention. So the collector saw none of them, and in a test build with my own logic removed, a post’s OG image fell back to the site default. Skipping those URLs is a reasonable design choice. It just doesn’t fit a blog that writes every image path that way.
That’s the failure mode of this kind of evaluation. A feature list tells you a feature exists. It can’t tell you whether it covers your conventions. Expect one or two of these, and read the source of anything you’re counting as covered.
The verdict
Here’s the whole ledger — the reason this was a real decision and not an obvious one:
| Feature | Under Sätteri |
|---|---|
| GFM tables, footnotes, strikethrough, task lists | Native |
| Frontmatter parsing | Native |
Math parsing ($, $$) |
Native, opt-in |
| Shiki syntax highlighting | Built in |
| Image collection | Native, but skips root-absolute URLs |
| Math rendering (KaTeX) | Rewrite by hand |
| External-link attributes | Rewrite by hand |
| Any existing remark/rehype plugin | Does not run |
Add it up and the cost is medium — but the shape of it matters more than the size. It’s concentrated. Everything I had to write fit into one hast plugin plus a small mdast plugin, under eighty lines total, in one file I rarely touch. That’s the useful thing to know before you start: this isn’t a migration that spreads through your codebase. It’s one well-defined piece of work, done once.
What you give up is remark and rehype’s decade of ecosystem. Every plugin you’d otherwise install, you now write and maintain yourself. If your list of those plugins is short, that’s a fine trade. If it’s long, the escape hatch exists for a reason, and choosing it isn’t a failure of nerve.
So, worth adopting? For most sites, easily — you delete plugins and gain build speed. For a site like mine it’s a genuine judgment call. And the honest version of my answer isn’t an engineering one.
Staying on the escape hatch is the defensible call, and in a normal production setting it’s the one I’d argue for: the classic pipeline works, Sätteri is pre-1.0, and nothing forces the change. I understand that argument. I just wasn’t making it.
I’d been drawn to the Rust engine from the moment I read about it, and I adopted it in the end — not because the risk math changed, but because being early on a still-niche engine was the part I actually wanted. Interesting to write about beat safest to run. On a personal blog, that’s allowed to be the reason. Just be clear with yourself about which reason you’re using.
Further Reading
- Sätteri documentation — the
Featuresset, thectx-based plugin model, and why remark/rehype plugins don’t run. - Astro 6.4 release notes — where Sätteri first shipped as an opt-in processor, before Astro 7 made it the default.
- Markdown in Astro — the official guide to
markdown.processor, including how to switch back to the unified processor and keep your remark and rehype plugins.