Astro 6.4 shipped May 28 with a Rust-native Markdown processor called Sätteri that cuts build times on large documentation sites by more than half. That is the good news. The not-so-good news is that Sätteri cannot run a single remark or rehype plugin — by design, not by accident. And even if you never touch Sätteri, this release deprecates the top-level markdown config syntax that every Astro project currently uses. There is work to do either way.
The Config Change That Affects Every Astro Developer
Start with the change that hits everyone, regardless of processor choice. In Astro 6.4, the following top-level markdown options are deprecated:
// astro.config.mjs — DEPRECATED in 6.4, removed in Astro 8.0
markdown: {
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeSlug],
smartypants: true,
gfm: true,
}
These options still work for now, but they are on the clock. Astro 8.0 removes them entirely. The fix is a one-time migration: wrap your existing configuration inside a processor: unified({...}) call.
// astro.config.mjs — New syntax (migrate now)
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';
export default defineConfig({
markdown: {
processor: unified({
remarkPlugins: [remarkToc],
rehypePlugins: [rehypeSlug],
smartypants: true,
gfm: true,
}),
},
});
Your plugins keep working. Your build output does not change. All you are doing is future-proofing before the Astro 8.0 cut. Do it now while the diff is small and the context is fresh.
What Sätteri Actually Is
Sätteri is a ground-up Rust rewrite of Astro’s Markdown pipeline — its own AST specification, its own parser, its own serializer. It replaces the unified/remark/rehype chain entirely when you opt in. The single-pass design is what makes it fast: GFM tables, task lists, autolinks, strikethrough, Smartypants, and directives are all compile-time features rather than JavaScript plugin traversals stacked one on top of another.
The performance numbers from testing on real production documentation sites:
| Site | Unified | Sätteri | Speedup |
|---|---|---|---|
| Astro docs | 142s | 63s | 2.25x |
| Cloudflare docs | 120s | 55s | 2.18x |
| Mid-size marketing site | 38s | 22s | 1.73x |
On a team running 50 builds per day, cutting 79 seconds per build translates to roughly 230 fewer CI hours per year. For small sites, the gain is real but modest. For any content operation sitting on hundreds or thousands of Markdown pages, this is the build time improvement worth prioritizing.
The Plugin Problem
Sätteri does not run remark or rehype plugins. This is not an oversight — a native Rust pipeline cannot execute JavaScript plugins. If your site relies on remark-toc, rehype-slug, rehype-autolink-headings, custom slug logic, math rendering, or any other plugin in the remark ecosystem, switching to Sätteri means losing that functionality with no immediate replacement.
The workaround is porting plugins to Sätteri’s own MDAST or HAST plugin system. That ecosystem is young. For most teams, that port is not a realistic near-term option. An experimental per-directory processor configuration is in progress, but it is not stable enough for production use yet.
The compatibility picture as it stands today:
| Feature | Unified | Sätteri |
|---|---|---|
| GFM (tables, task lists) | via plugin | native |
| Smartypants | via plugin | native |
| Directives | plugin needed | native |
| Custom remark plugins | Yes | No |
| Custom rehype plugins | Yes | No |
| MDX | Yes | Yes |
Who Should Switch to Sätteri Now
The clearest use case for adopting Sätteri immediately is a large documentation site that uses standard Markdown with little to no custom plugin logic. If your build regularly exceeds 80 seconds and your Markdown pipeline is close to vanilla, the switch is straightforward:
// astro.config.mjs — Sätteri opt-in
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';
export default defineConfig({
markdown: {
processor: satteri({
features: { directive: true },
}),
},
});
If you have any doubt about plugin dependencies, diff your rendered output against what unified produced before committing. Sätteri’s GFM parsing is spec-compatible but edge cases can produce minor differences in output. For plugin-heavy sites — anything with custom table-of-contents generation, heading anchors, or syntax highlighting customization — stay on unified for now and focus solely on the config migration. Sätteri will catch up, but it is not there yet.
Cloudflare Deployment: A Bonus Improvement
One other addition in 6.4 worth noting for teams deploying to Cloudflare Workers: the @astrojs/cloudflare adapter gained a cf() routing helper. Enable it in your adapter config with advancedRouting: { cf: true } and replace the manual KV binding setup with a single app.use(cf()) call. It eliminates the boilerplate around SESSION KV bindings, ASSETS binding, and client address detection — and it improves dev/production parity, reducing the class of wrangler-vs-Edge bugs that only appear once you deploy.
The Deprecation Timeline
Astro 8.0 will remove the old top-level markdown options. At the current Astro release cadence, that gives most teams 12 to 18 months before the removal hits. That sounds comfortable, but the migration is trivial to do today and will only grow harder as config files accumulate more customization. Run npx @astrojs/upgrade now, wrap your plugins in processor: unified({...}), and close the ticket. Sätteri is the interesting long-term question you can revisit once its plugin ecosystem matures and your current plugins have equivalents. The config migration cannot wait that long.













