blog.dopana

Back

The Deprecation Warning#

When starting your development server (astro dev) or creating a production build (astro build), you might encounter this warning:

[astro] `markdown.remarkPlugins`, `markdown.rehypePlugins`, and `markdown.remarkRehype` are deprecated. Pass them to `unified({...})` from `@astrojs/markdown-remark` directly instead.
text

If your project uses Remark or Rehype plugins (such as KaTeX for math, heading sluggers, or custom syntax transformers), Astro is letting you know that the top-level configuration format is being phased out in favor of a dedicated processor architecture.

Let’s break down why this change happened, how the new system works, and how to fix your configuration cleanly in less than two minutes.

Why Did Astro Change the Markdown API?#

The “Explain Like I’m 10” (ELI5) Analogy#

Think of Astro as a modular kitchen:

  • Previously: Astro had a single, heavy oven (the Unified/Remark/Rehype engine) hardwired into the wall. If you wanted temperature settings or custom baking trays (plugins), you attached them directly to the kitchen wall (markdown.remarkPlugins).
  • Now: Astro created an interchangeable oven slot (markdown.processor).
    • You can plug in the classic Unified oven (@astrojs/markdown-remark) if you love the massive Remark/Rehype plugin ecosystem.
    • Or you can plug in the ultra-fast, Rust-powered Sätteri oven (@astrojs/markdown-satteri) for maximum build performance.

Because Remark and Rehype plugins only work inside the Unified engine, attaching them to the root markdown config no longer makes architectural sense. Astro now requires passing them directly to the unified({...}) processor.

flowchart TD
    subgraph Legacy["Astro (Legacy Architecture)"]
        L_Config["astro.config.mjs (markdown.remarkPlugins / rehypePlugins)"] --> L_Engine["Astro Core (Hardcoded Unified Parser)"]
    end

    subgraph Modern["Astro Modern Architecture (v6.4+ / v7+)"]
        M_Config["astro.config.mjs (markdown.processor)"]
        M_Config --> M_Choice{"Choose Processor"}
        M_Choice -->|unified: remarkPlugins, rehypePlugins| M_Unified["@astrojs/markdown-remark (Unified / Remark / Rehype)"]
        M_Choice -->|satteri: mdastPlugins, hastPlugins| M_Satteri["@astrojs/markdown-satteri (Rust-based Sätteri)"]
    end

Key Architectural Benefits#

  1. Decoupled Markdown Engine: Astro core is no longer tightly coupled to Unified, reducing bundle size for sites that don’t need it.
  2. First-Class Rust Compiler Support: Astro v7+ introduces Sätteri as the default zero-config Markdown processor for blazing-fast builds.
  3. Clearer Plugin Scoping: Processor-specific options (remarkPlugins, rehypePlugins, smartypants, gfm) live neatly within their respective processor definition.

How to Fix: Step-by-Step Guide#

Step 1: Install @astrojs/markdown-remark#

Ensure the official @astrojs/markdown-remark package is installed in your project:

Terminal
bun add @astrojs/markdown-remark
# or
npm install @astrojs/markdown-remark
# or
pnpm add @astrojs/markdown-remark
bash

Step 2: Update astro.config.ts (or astro.config.mjs)#

Import unified from @astrojs/markdown-remark and wrap your plugins inside markdown.processor:

[!NOTE] Notice that shikiConfig (syntax highlighting) remains directly inside markdown: { ... }. Only Markdown parser options (remarkPlugins, rehypePlugins, remarkRehype, gfm, smartypants) move inside processor: unified({ ... }).

Common Options in unified({...})#

Here are the most common options you can pass directly to unified({...}):

OptionTypeDescription
remarkPluginsArrayPlugins operating on Markdown syntax tree (mdast).
rehypePluginsArrayPlugins operating on HTML syntax tree (hast).
remarkRehypeObjectOptions passed to remark-rehype (e.g., footnote customization).
gfmbooleanEnable or disable GitHub-Flavored Markdown (default: true).
smartypants`boolean \Object`

Example: Custom Footnotes Configuration#

If you previously configured footnote back-links via markdown.remarkRehype, move it into unified({...}):

astro.config.ts
import { defineConfig } from 'astro/config';
import { unified } from '@astrojs/markdown-remark';

export default defineConfig({
  markdown: {
    processor: unified({
      remarkRehype: {
        footnoteBackContent: '↩',
        footnoteLabel: 'Footnotes',
      },
    }),
  },
});
typescript

Alternative: Using the Rust-based Sätteri Processor#

If your project doesn’t rely on existing Remark or Rehype plugins and you want maximum build speed, you can switch to Sätteri:

Terminal
bun add @astrojs/markdown-satteri
bash

Then configure it in your astro.config.ts:

astro.config.ts
import { defineConfig } from 'astro/config';
import { satteri } from '@astrojs/markdown-satteri';

export default defineConfig({
  markdown: {
    processor: satteri({
      features: {
        gfm: true,
        smartPunctuation: true,
      },
    }),
  },
});
typescript

[!TIP] Sätteri uses mdastPlugins and hastPlugins written specifically for its AST format rather than npm Remark/Rehype packages. If you need rich ecosystem plugins like remark-math or rehype-katex, stick with processor: unified({...}).

Third-Party Integrations Compatibility#

Integrations like astro-mermaid, @astrojs/mdx, and community plugins check config.markdown.processor. When you configure processor: unified({...}), these integrations automatically append their required transformers into your existing processor pipeline without conflicts.

bun run check
bun run build
bash

After updating your configuration, your build logs will be clean without any deprecation warnings.

Summary#

  • The Warning: Astro deprecated root-level markdown.remarkPlugins, markdown.rehypePlugins, and markdown.remarkRehype.
  • The Fix: Wrap your plugins inside markdown.processor: unified({ remarkPlugins: [...], rehypePlugins: [...] }) from @astrojs/markdown-remark.
  • Keep in Mind: shikiConfig stays at the markdown level, while parser options live in unified({...}).

References#