---
title: Migrate to Blume
description: Move a Mintlify, Fumadocs, Docusaurus, Starlight, or Nextra site to Blume with one command that hands the migration to Claude Code or Codex.
sidebar:
  label: Migrate to Blume
  order: 2.4
---

Moving a docs site to idiomatic Blume takes judgment a codemod can't make: which declared navigation becomes folders, which components become directives, and what has no Blume equivalent. So `blume migrate` hands the job to a coding agent, working from Blume's migration playbook, while you review each edit.

## Migrate with one command

Run it from the root of the docs project you're migrating:

```package-install
npx blume migrate fumadocs --claude
```

Swap `fumadocs` for your framework, and `--claude` for `--codex` to use Codex. With pnpm 12, add `--allow-build=esbuild` after `pnpm dlx`, since pnpm 12 won't run esbuild's install script unapproved. The agent opens interactively in your terminal, so every edit goes through its own permission flow. It works in place, so start from a clean working tree and review the whole migration as one diff.

## Sources

Name the framework you're migrating from, or leave it out and Blume detects it from the project's own files. When you name one and the project looks like another, Blume warns and continues with the one you named:

| Source | Detected from |
| --- | --- |
| `mintlify` | `docs.json` or `mint.json` |
| `fumadocs` | `source.config.ts`, or `fumadocs-core`, `fumadocs-ui`, or `fumadocs-mdx` in `package.json` |
| `docusaurus` | `docusaurus.config.*` |
| `starlight` | `@astrojs/starlight` in `package.json` |
| `nextra` | `nextra` in `package.json` |

Each source has its own mapping reference in the playbook. A site built with anything else still migrates: run the command without a source, and the agent inventories the repo first, then works from the playbook's general rules.

## What the agent does

The agent follows the playbook's workflow from the source's config to a passing build:

1. Writes `blume.config.ts`, mapping only what your source declares and leaving Blume's defaults to cover the rest.
2. Restructures content into [filesystem navigation](/docs/content/navigation), converting per-folder ordering files (Fumadocs `meta.json`, Nextra `_meta`) to `meta.ts`.
3. Rewrites pages: frontmatter to Blume's schema, callout components to [directives](/docs/content/syntax), icons to Lucide, and snippets inlined.
4. Adds a [redirect](/docs/deployment#redirects) for every URL that moves, so no link breaks.
5. Points your `package.json` scripts at `blume dev` and `blume build`, and swaps the old framework's dependencies for `blume`.
6. Runs `blume build` and `blume validate` until both pass.

It finishes with a summary of what it migrated, dropped, or approximated, such as footer links or dynamic redirects with no Blume equivalent, so you can decide what to do with each.

## Other agents

Without `--claude` or `--codex`, the command reports the source it detected, prints the path to the playbook — the `blume-migrate` [skill](/docs/advanced/skills) bundled in the package — and exits without changing anything. Point any other agent at that `SKILL.md`, or install the skill where your agent looks for skills, with the command it prints:

```bash
npx skills add haydenbleasel/blume --skill blume-migrate
```

## Compare first

The [comparison pages](/compare) set Blume beside each framework and list what the migration carries over and rewrites for it.
