Migrating from Docusaurus to Fumadocs
Folder mapping, steps, and an honest look at the payoff — with Fumadocs as the destination.
This page leaves Docusaurus behind. The destination is Fumadocs: the right-hand column of the table
below is docs-overlay-fumadocs API, and step 3 is a Fumadocs install. It was never a way to keep
Docusaurus, and the title did not say so.
You can keep Docusaurus. A guide for that — Staying on Docusaurus — was added after this version was published, so it is not in this one; switch to a newer version in the sidebar to read it. The content model is identical either way, and only the last mile differs.
Docusaurus stores each version as a full snapshot: versioned_docs/version-11.14.0/ next to
versioned_docs/version-11.13.0/, plus versions.json and one versioned_sidebars/*.json per
version. Cutting a release copies the whole tree.
The shape of the move
| Docusaurus | docs-overlay |
|---|---|
docs/ (current) | content/docs/next/ |
versioned_docs/version-11.14.0/ | content/docs/11.14.0/ |
versions.json | nothing — the folders are the list |
versioned_sidebars/version-X-sidebars.json | content/docs/X/**/meta.json, inherited |
lastVersion: "11.14.0" | latestAtRoot: true |
versions: { current: { path: "next" } } | channels: ["next"] |
docsVersionDropdown | versionTabs() plus a component of your own |
URLs come out identical, which is the point: /atomic/intro for the last release, /next/... for the
current one, /11.13.0/... for an older one. Nothing that was linked externally breaks.
Steps
-
Rename the folders.
version-11.13.0→11.13.0, anddocs/→next/. Keep themeta.jsonfiles; dropversions.jsonandversioned_sidebars/. -
Widen the schema. Without this nothing works and nothing says so:
// source.config.ts import { withOverlay } from "docs-overlay-fumadocs/schema"; export const docs = defineDocs({ dir: "content/docs", docs: { schema: withOverlay(pageSchema) } }); -
Wire the loader — see Install.
-
Prune what is identical. Any file in an older version byte-identical to the one it would inherit can be deleted; the overlay serves the inherited copy. On the tree this was built for, 43 of 188 files were identical between two adjacent versions.
-
Convert the deletions. A page present in an old snapshot but absent from the newer one already behaves correctly — it simply is not in the newer folder. A page you want removed from a newer version while the file still exists needs a tombstone in that version.
-
Convert the renames. Add
renamedFromto the new file in the version that renamed it. Docusaurus had no equivalent, so this is new capability rather than a translation.
Be honest about the payoff
On the corpus this was measured against, 115 of ~170 shared files genuinely differ between 11.13.0 and 11.14.0. Deduplication is therefore a modest win. What actually changes:
- Cutting a version costs nothing.
git mv next 11.15.0 && mkdir nextis a zero-byte content diff against ~190 copied files and a ~1.2 MB commit. - Navigation stops being duplicated. The two
versioned_sidebarsfiles measured differed by a single line across 4 kB. - Deletions and renames become declarative and reviewable, instead of manual surgery inside frozen folders — and a renamed page keeps its old URL working, which it did not before.
What is not supported
Versioned i18n. Fumadocs' i18n.parser: "dir" consumes the first path segment, which is the one the
version occupies. 0.x does not combine the two.