Jesse A. Green / notebook

Docusaurus Administrator & Developer Guide

Generated May 2026 from facebook/docusaurus at 9929ac0

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

1. Architecture Overview

Docusaurus is a modular, plugin-driven static site generator that transforms Markdown/MDX content into a React-based single-page application. Built as a Yarn workspaces monorepo, it separates concerns across ~40 packages: a core engine, content plugins, themes, utilities, and a bundler abstraction layer.

The architecture follows a three-tier model:

┌─────────────────────────────────────────────────────┐
│                    docusaurus.config.js              │
│                  (User Configuration)                │
└──────────────┬───────────────────────┬──────────────┘
               │                       │
    ┌──────────▼──────────┐  ┌────────▼────────────┐
    │    Preset Classic   │  │   Standalone Plugins │
    │  ┌────────────────┐ │  │  (PWA, Redirects,   │
    │  │ plugin-docs    │ │  │   Ideal Image, etc.) │
    │  │ plugin-blog    │ │  └──────────────────────┘
    │  │ plugin-pages   │ │
    │  │ plugin-sitemap │ │
    │  │ theme-classic  │ │
    │  │ gtag / GTM     │ │
    │  └────────────────┘ │
    └──────────┬──────────┘
               │
    ┌──────────▼──────────────────────────────────────┐
    │              @docusaurus/core                     │
    │  CLI → LoadContext → Plugin Init → Lifecycle      │
    │  → Content Load → Route Gen → Bundler → SSG      │
    └──────────┬──────────────────────────────────────┘
               │
    ┌──────────▼──────────────────────────────────────┐
    │         @docusaurus/bundler                       │
    │   Webpack (default) ──or── Rspack (future flag)  │
    │   SWC / Terser / Lightning CSS minifiers          │
    └─────────────────────────────────────────────────┘

Component Inventory

Component Package Role
Core Engine @docusaurus/core CLI, plugin orchestration, SSG, dev server
Bundler @docusaurus/bundler Webpack/Rspack abstraction, minification
Docs Plugin @docusaurus/plugin-content-docs Documentation with versioning, sidebars
Blog Plugin @docusaurus/plugin-content-blog Blog posts, authors, feeds
Pages Plugin @docusaurus/plugin-content-pages Static/MDX pages
Classic Theme @docusaurus/theme-classic UI components, navbar, footer, sidebar
Theme Common @docusaurus/theme-common Shared React hooks, utilities, contexts
Preset Classic @docusaurus/preset-classic Bundle of docs + blog + pages + theme
MDX Loader @docusaurus/mdx-loader Webpack loader for MDX/Markdown
Utils @docusaurus/utils Path normalization, constants, data files
Utils Validation @docusaurus/utils-validation Joi-based schema validation
Types @docusaurus/types TypeScript type definitions
Logger @docusaurus/logger Structured logging with performance tracking
Faster @docusaurus/faster SWC/Rspack/Lightning CSS optimizations
Create Docusaurus create-docusaurus Project scaffolding CLI
Client Redirects @docusaurus/plugin-client-redirects HTML-based URL redirects
PWA @docusaurus/plugin-pwa Service worker, offline access
Sitemap @docusaurus/plugin-sitemap XML sitemap generation
Google Analytics @docusaurus/plugin-google-analytics Legacy GA integration
Google Gtag @docusaurus/plugin-google-gtag GA4 via gtag.js
Google Tag Manager @docusaurus/plugin-google-tag-manager GTM container injection
Vercel Analytics @docusaurus/plugin-vercel-analytics Vercel analytics integration
Rsdoctor @docusaurus/plugin-rsdoctor Build analysis and diagnostics
Search Algolia @docusaurus/theme-search-algolia DocSearch integration
Live Codeblock @docusaurus/theme-live-codeblock Interactive React code editor
Mermaid @docusaurus/theme-mermaid Mermaid diagram rendering
Translations @docusaurus/theme-translations Locale translation files
Ideal Image @docusaurus/plugin-ideal-image Responsive image optimization
SVGR @docusaurus/plugin-svgr Import SVGs as React components
CSS Cascade Layers @docusaurus/plugin-css-cascade-layers CSS @layer wrapping
Babel @docusaurus/babel Babel presets and configuration
CSSNano Preset @docusaurus/cssnano-preset CSS minification configuration
ESLint Plugin @docusaurus/eslint-plugin Coding convention enforcement
Stylelint Copyright @docusaurus/stylelint-copyright Copyright header check for CSS
LQIP Loader @docusaurus/lqip-loader Low-quality image placeholder
Remark npm2yarn @docusaurus/remark-plugin-npm2yarn Package manager tab generation
Module Aliases @docusaurus/module-type-aliases TypeScript path aliases
TSConfig @docusaurus/tsconfig Shared TypeScript configuration

Technology Stack

Layer Technology
Language TypeScript (strict), compiled to ES modules
Runtime Node.js >= 24.14
UI Framework React >= 19.2.0
Content Format MDX 3.x (via @mdx-js/react)
Bundler (default) Webpack 5 with persistent caching
Bundler (opt-in) Rspack via @docusaurus/faster
CSS Processing PostCSS, CSSNano, Lightning CSS (opt-in)
JS Compilation Babel (default) or SWC (opt-in via Faster)
Monorepo Yarn workspaces + Lerna
Testing Jest 30 with SWC transform
Linting ESLint, Stylelint, CSpell, Syncpack
Visual Testing Argos (Playwright screenshots)

Plugin Lifecycle

Plugins follow a standardized async lifecycle:

validateOptions() → constructor(context, options) → loadContent()
  → contentLoaded({content, actions}) → configureWebpack()
  → injectHtmlTags() → postBuild() → extendCli()

Key lifecycle methods:

Method Purpose
validateOptions Joi schema validation of plugin config
loadContent Read and process source files
contentLoaded Generate routes and data files via actions
configureWebpack Merge custom webpack/rspack config
configurePostCss Modify PostCSS options
injectHtmlTags Add tags to <head> or <body>
postBuild Post-build hooks (sitemap, feed generation)
extendCli Register custom CLI commands
getThemePath Return path to theme components
getClientModules Return client-side module paths

Note

A plugin constructor can return null to self-disable, allowing conditional activation based on environment or config. This is used by analytics plugins that only activate in production.

Data Flow

1. CLI invoked (start/build)
2. LoadContext: read docusaurus.config, resolve presets → plugins
3. Plugin init: validateOptions → construct → ensure unique IDs
4. Content loading: each plugin reads its source files
5. Route generation: plugins emit routes + data files to @generated/
6. Bundler: Webpack/Rspack compiles client + server bundles
7. SSG: AppRenderer executes React server-side for each route
8. Output: static HTML + JS/CSS bundles in build/ directory

Plugins output data to @generated/{pluginName}/{pluginId}/, which is aliased for import in React components. The AppRenderer must call shutdown() after SSG to clear Node.js require caches and prevent memory leaks.

2. System Requirements

Requirement Minimum Recommended
Node.js >= 24.14 Latest LTS
npm/Yarn/pnpm/Bun Any supported version Yarn 1.22+
Git Required for deploy, VCS metadata Latest
OS Windows, macOS, Linux Linux for CI
Memory 2 GB 4+ GB for large sites
Disk Depends on site size SSD recommended

Build-Time Dependencies (devDependencies from monorepo root)

Package Version Purpose
react / react-dom ^19.2.0 UI framework
@mdx-js/react ^3.0.0 MDX integration
typescript ~6.0.2 Type checking
jest ^30.2.0 Testing
@swc/core ^1.7.39 SWC compilation
lerna ^7.4.2 Monorepo management
eslint ^8.45.0 Code linting
prettier ^2.8.8 Code formatting
husky ^8.0.3 Git hooks

User Site Dependencies (classic template)

Package Version Purpose
@docusaurus/core 3.9.2 Core engine
@docusaurus/preset-classic 3.9.2 Standard plugin bundle
@docusaurus/faster 3.9.2 Build optimization (optional)
@mdx-js/react ^3.0.0 MDX support
clsx ^2.0.0 Conditional CSS classes
prism-react-renderer ^2.3.0 Code syntax highlighting
react / react-dom ^19.2.0 UI framework

3. Configuration Reference

Site Configuration (docusaurus.config.js)

The configuration file exports a Config object (or async factory function).

Core Settings

Key Type Default Required Description
title string — Yes Site title
tagline string '' No Site tagline
url string — Yes Production URL
baseUrl string '/' Yes Base URL path
favicon string — No Favicon path
trailingSlash boolean | undefined undefined No Trailing slash policy
organizationName string — No GitHub org/user (for deploy)
projectName string — No GitHub repo name (for deploy)
deploymentBranch string 'gh-pages' No Branch for GitHub Pages deploy
onBrokenLinks 'ignore' | 'log' | 'warn' | 'throw' 'throw' No Broken link behavior
onBrokenAnchors 'ignore' | 'log' | 'warn' | 'throw' 'warn' No Broken anchor behavior
onBrokenMarkdownLinks 'ignore' | 'log' | 'warn' | 'throw' 'warn' No Broken Markdown link behavior
onDuplicateRoutes 'ignore' | 'log' | 'warn' | 'throw' 'warn' No Duplicate route behavior
staticDirectories string[] ['static'] No Static asset directories
noIndex boolean false No Add noindex meta to all pages
headTags HtmlTagObject[] [] No Additional <head> tags
scripts (string | HtmlTagObject)[] [] No Additional <script> tags
stylesheets (string | HtmlTagObject)[] [] No Additional <link> stylesheets
clientModules string[] [] No Client-side modules to load

i18n Configuration

Key Type Default Description
i18n.defaultLocale string 'en' Default locale
i18n.locales string[] ['en'] All supported locales
i18n.path string 'i18n' Root i18n directory
i18n.localeConfigs Record<string, LocaleConfig> {} Per-locale overrides

future Flags

Key Type Default Description
future.faster.swcJsLoader boolean false Use SWC instead of Babel for JS/TS
future.faster.swcJsMinimizer boolean false Use SWC for JS minification
future.faster.swcHtmlMinimizer boolean false Use SWC for HTML minification
future.faster.lightningCssMinimizer boolean false Use Lightning CSS for CSS minification
future.faster.rspackBundler boolean false Use Rspack instead of Webpack
future.faster.mdxCrossCompilerCache boolean false Cache MDX across client/server builds
future.v4.removeLegacyPostBuildHeadAttribute boolean false Remove legacy post-build API
future.v4.useCssCascadeLayers boolean false Wrap styles in CSS @layer

Important

The future flags are opt-in previews of breaking changes planned for Docusaurus v4. Enable them incrementally to prepare for the next major version.

Markdown Configuration

Key Type Default Description
markdown.format 'mdx' | 'md' | 'detect' 'mdx' Default Markdown processor
markdown.mermaid boolean false Enable Mermaid code blocks
markdown.remarkPlugins RemarkPlugin[] [] Remark plugins
markdown.rehypePlugins RehypePlugin[] [] Rehype plugins
markdown.parseFrontMatter function — Custom frontmatter parser

Environment Variables (Complete Reference)

User-Facing

Variable Default Description
PORT 3000 Dev server / serve port
DOCUSAURUS_CLI_SITE_DIR . Override site directory
DOCUSAURUS_CLI_CONFIG undefined Override config file path
BASE_URL — Override baseUrl at build time

Deployment

Variable Default Description
GIT_USER — GitHub username for HTTPS deploy
GIT_PASS — GitHub token (obfuscated in logs)
USE_SSH — Use SSH for deploy (true/false)
ORGANIZATION_NAME — Override organizationName config
PROJECT_NAME — Override projectName config
DEPLOYMENT_BRANCH 'gh-pages' Target branch for deploy
CURRENT_BRANCH — Override source branch detection
GITHUB_HOST — Custom GitHub host
GITHUB_PORT — Custom GitHub port
GIT_USER_NAME — Git commit author name
GIT_USER_EMAIL — Git commit author email
CUSTOM_COMMIT_MESSAGE — Custom deploy commit message
CI_PULL_REQUEST / CIRCLE_PULL_REQUEST — Skip deploy on PR builds
CIRCLE_PROJECT_USERNAME — Fallback for organizationName
CIRCLE_PROJECT_REPONAME — Fallback for projectName

Build Optimization

Variable Default Description
DOCUSAURUS_PERF_LOGGER — Enable performance logging
DOCUSAURUS_RSPACK_TRACE — Enable Rspack trace output
TERSER_PARALLEL — Override Terser parallelism
USE_SIMPLE_CSS_MINIFIER — Use simpler CSS minification
SKIP_HTML_MINIFICATION — Skip HTML minification entirely
WEBPACK_URL_LOADER_LIMIT — URL loader inline size limit
DOCUSAURUS_SERVER_NODE_TARGET — Override Node target for server bundle

Development / Testing

Variable Default Description
NODE_ENV — Environment (production/development)
SIMULATE_PRODUCTION_VISIBILITY — Show draft/unlisted state in dev
DOCUSAURUS_BABEL_CONFIG_FILE_NAME — Override Babel config filename
DOCUSAURUS_GENERATED_FILES_DIR_NAME — Override .docusaurus directory name
DOCUSAURUS_DEPLOY_DEBUG — Enable verbose deploy logging
DOCUSAURUS_CRASH_TEST — Force crash (testing only)
DOCUSAURUS_SLOWER — Add artificial delays (testing)
DOCUSAURUS_SITE_VCS — Override VCS provider

PWA

Variable Default Description
PWA_SERVICE_WORKER_URL — Custom service worker URL
PWA_DEBUG — Enable PWA debug logging
PWA_SW_CUSTOM — Custom service worker code path

Warning

GIT_PASS is obfuscated in deploy command logs, but always use environment secrets (CI variables) rather than hardcoding credentials.

Plugin Option Schemas

Docs Plugin (@docusaurus/plugin-content-docs)

Option Type Default Description
path string 'docs' Docs source directory
id string 'default' Plugin instance ID
sidebarPath string | false 'sidebars.js' Sidebar config file
include string[] ['**/*.{md,mdx}'] File inclusion globs
exclude string[] Various test patterns File exclusion globs
editUrl string | function — Edit link base URL or function
editLocalizedFiles boolean false Route edits to localized files
editCurrentVersion boolean true Edit links point to current version
showLastUpdateAuthor boolean false Show last Git author
showLastUpdateTime boolean false Show last Git update time
routeBasePath string 'docs' URL base path
versions object — Per-version configuration
onlyIncludeVersions string[] — Limit which versions to build
breadcrumbs boolean true Show breadcrumbs

Blog Plugin (@docusaurus/plugin-content-blog)

Option Type Default Description
path string 'blog' Blog source directory
include string[] ['**/*.{md,mdx}'] File inclusion globs
exclude string[] Various patterns File exclusion globs
editUrl string | function — Edit link base
showReadingTime boolean true Display reading time
authorsMapPath string 'authors.yml' Authors definition file
authorsBaseRoutePath string '/authors' Author pages URL base
onInlineAuthors string — Inline author handling strategy
feedOptions object — RSS/Atom feed configuration
blogTitle string 'Blog' Blog page title
blogSidebarCount number | 'ALL' 5 Sidebar recent posts count

Sitemap Plugin (@docusaurus/plugin-sitemap)

Option Type Default Description
ignorePatterns string[] [] Route patterns to exclude
lastmod 'date' | 'datetime' | null null Lastmod format
priority number 0.5 Default page priority
changefreq string — Default change frequency
createSitemapItems function — Custom sitemap item generator

Client Redirects Plugin (@docusaurus/plugin-client-redirects)

Option Type Default Description
redirects {from, to}[] [] Static redirect definitions
fromExtensions string[] [] Auto-redirect from extensions
toExtensions string[] [] Auto-redirect to extensions
createRedirects function — Dynamic redirect generator

PWA Plugin (@docusaurus/plugin-pwa)

Option Type Default Description
debug boolean false Enable debug logging
offlineModeActivationStrategies string[] [] Offline activation strategies
injectManifestConfig object — Workbox manifest config
pwaHead {tagName, ...}[] [] Head tag injection
swCustom string — Custom service worker module
swRegister string | false — SW registration module

Module Resolution (Plugin Shorthand)

Docusaurus resolves plugin names using these patterns:

Input Resolved
'content-docs' @docusaurus/plugin-content-docs
'my-plugin' docusaurus-plugin-my-plugin
'@scope/my-plugin' @scope/docusaurus-plugin-my-plugin
'./local-plugin' ./local-plugin (relative path)

Same pattern applies to themes (docusaurus-theme-*) and presets (docusaurus-preset-*).

4. Deployment & Scaling

GitHub Pages Deployment

The built-in deploy command handles the full workflow:

  1. Builds the site (unless --skip-build)
  2. Creates a temporary directory
  3. Clones the deployment branch
  4. Copies build output
  5. Commits and pushes

Required configuration:

// docusaurus.config.js
module.exports = {
  url: 'https://my-org.github.io',
  baseUrl: '/my-repo/',
  organizationName: 'my-org',
  projectName: 'my-repo',
  trailingSlash: false,
};

CI deployment example:

GIT_USER=git CURRENT_BRANCH=main \
  GIT_PASS=$GITHUB_TOKEN \
  npx docusaurus deploy

For organization pages (<org>.github.io without a subpath), set deploymentBranch: 'main' and baseUrl: '/'.

Static Hosting (Netlify, Vercel, Cloudflare)

The build output is a self-contained static site in build/:

npx docusaurus build
# Deploy build/ to any static host

For Netlify detection, Docusaurus checks NETLIFY and CONTEXT environment variables to adjust build behavior (e.g., deploy preview settings).

Scaling Considerations

Concern Solution
Large sites (1000+ pages) Enable @docusaurus/faster for Rspack + SWC
Many versions Use onlyIncludeVersions to build a subset
i18n with many locales Build locales in parallel CI jobs with --locale
Memory pressure NODE_OPTIONS=--max-old-space-size=4096
Build speed Enable mdxCrossCompilerCache for large MDX sites
CI caching Cache node_modules/.cache and .yarn/.cache between builds

Tip

The clear command removes node_modules/.cache and .yarn/.cache bundler caches. In CI, preserve these directories between runs for faster incremental builds.

5. Operations

Build Monitoring

Enable performance logging to track build phases:

DOCUSAURUS_PERF_LOGGER=true npx docusaurus build

The logger tracks start/end marks for each build phase. If a mark is missing, it throws: No performance start mark for label=${label}.

For deep build analysis, use Rsdoctor:

plugins: ['@docusaurus/plugin-rsdoctor'],
RSDOCTOR=true npx docusaurus build

Health Checks

Use the debug plugin (included in classic preset) during development:

  • http://localhost:3000/__docusaurus/debug — site config, routes, plugin data
  • http://localhost:3000/__docusaurus/debug/config — resolved configuration
  • http://localhost:3000/__docusaurus/debug/routes — all registered routes

Cache Management

Cache Location Purpose Clear With
Generated files .docusaurus/ Plugin data, aliases npx docusaurus clear
Build output build/ Production bundle npx docusaurus clear
Webpack cache node_modules/.cache Persistent build cache npx docusaurus clear
Yarn PnP cache .yarn/.cache PnP build cache npx docusaurus clear

Note

The clear command removes all four cache locations. In development, a full clear forces regeneration of all data files and full rebundle on next start.

Version Management

Docusaurus versions are snapshots of the docs/ directory:

docs/                    → "current" (unreleased next version)
versioned_docs/
  version-3.10.0/        → v3.10.0 snapshot
  version-3.9.2/         → v3.9.2 snapshot
  ...
versioned_sidebars/
  version-3.10.0-sidebars.json
  version-3.9.2-sidebars.json

Version creation copies docs + sidebars + i18n translations. The Docusaurus website itself maintains 10+ versioned snapshots (v2.x through v3.10.0).

Translation Workflow

  1. Extract messages: npx docusaurus write-translations --locale fr
  2. Translate JSON files in i18n/fr/
  3. Translate content by placing localized Markdown in i18n/fr/docusaurus-plugin-content-docs/current/
  4. Build: npx docusaurus build --locale fr

Crowdin integration is available via the @crowdin/cli package (used by the Docusaurus website itself).

Tip

Use --messagePrefix with write-translations to mark untranslated strings (e.g., --messagePrefix "🚧 ") so they stand out in the UI during development.

6. Performance

Bundler Selection

Bundler Flag Characteristics
Webpack (default) — Mature ecosystem, persistent caching, widest plugin compatibility
Rspack (opt-in) future.faster.rspackBundler Significantly faster builds, Rust-based, Webpack API compatible

Minification Options

Minifier Type Flag Notes
Terser JS default Configurable parallelism via TERSER_PARALLEL
SWC JS swcJsMinimizer ES2020 target, tree-shaking, faster
CSSNano CSS default Custom preset in @docusaurus/cssnano-preset
Lightning CSS CSS lightningCssMinimizer Browserslist-aware, Rust-based
Terser (HTML) HTML default Can fail; errors logged as HTML minification failed (Terser)
SWC (HTML) HTML swcHtmlMinimizer Fallback errors: HTML minification failed (SWC)

Skip HTML minification entirely with SKIP_HTML_MINIFICATION=true.

MDX Cross-Compiler Cache

When mdxCrossCompilerCache is enabled, MDX files compiled for the client bundle are cached and reused for the server bundle (and vice versa). This is production-only and avoids double-compiling large MDX sites.

Browserslist Targets

The @docusaurus/faster package computes targets from browserslist:

  • Client: From browserslist config in package.json (production/development contexts)
  • Server: From the current Node.js version, overridable with DOCUSAURUS_SERVER_NODE_TARGET

7. Security

Content Security

Concern Mitigation
XSS in user content MDX sanitizes by default; React escapes JSX
Script injection scripts and headTags config only; no runtime injection
Deploy credentials GIT_PASS obfuscated in logs; use CI secrets
API keys in config Algolia search key is public (search-only); no server-side secrets

Dependency Security

The monorepo uses:

  • lockfile-lint — validates lockfile integrity
  • syncpack — ensures dependency version consistency across packages
  • patch-package — applies security patches without waiting for upstream
  • Yarn deduplication via yarn-deduplicate in postinstall

PWA Security

The PWA service worker is compiled separately by Webpack with its own Babel configuration. Custom service worker code (swCustom) is inlined — audit any custom SW modules for fetch interception or cache poisoning.

Caution

The PWA plugin's service worker has full control over network requests and cached responses. Only enable it in trusted deployment environments and audit any custom service worker code.

CSP Considerations

Docusaurus injects inline scripts for:

  • Color mode initialization
  • Service worker registration (PWA)
  • Analytics scripts (gtag, GTM)

If deploying with strict Content-Security-Policy headers, add appropriate nonce or sha256 hashes for these inline scripts.

8. Developer Internals

Repository Structure

facebook/docusaurus/
├── packages/
│   ├── docusaurus/               Core engine
│   │   └── src/
│   │       ├── commands/         CLI commands (start, build, deploy, etc.)
│   │       ├── server/           Server-side: config loading, plugins, codegen
│   │       ├── webpack/          Webpack configuration and utilities
│   │       └── client/           Client-side exports and theme fallbacks
│   ├── docusaurus-bundler/       Webpack/Rspack abstraction
│   ├── docusaurus-faster/        SWC/Rspack/Lightning CSS optimizations
│   ├── docusaurus-logger/        Structured logging with perf tracking
│   ├── docusaurus-types/         TypeScript type definitions
│   ├── docusaurus-utils/         Path, URL, data file utilities
│   ├── docusaurus-utils-common/  Shared utilities (client + server)
│   ├── docusaurus-utils-validation/ Joi schema helpers
│   ├── docusaurus-babel/         Babel presets and configuration
│   ├── docusaurus-mdx-loader/    Webpack MDX loader + remark plugins
│   ├── docusaurus-preset-classic/ Plugin bundle (docs+blog+pages+theme)
│   ├── docusaurus-plugin-content-docs/   Versioned documentation
│   ├── docusaurus-plugin-content-blog/   Blog with authors + feeds
│   ├── docusaurus-plugin-content-pages/  Static/MDX pages
│   ├── docusaurus-plugin-sitemap/        XML sitemap
│   ├── docusaurus-plugin-client-redirects/ Client-side redirects
│   ├── docusaurus-plugin-pwa/            Progressive Web App
│   ├── docusaurus-plugin-google-analytics/ Legacy GA
│   ├── docusaurus-plugin-google-gtag/     GA4
│   ├── docusaurus-plugin-google-tag-manager/ GTM
│   ├── docusaurus-plugin-vercel-analytics/ Vercel analytics
│   ├── docusaurus-plugin-rsdoctor/        Build diagnostics
│   ├── docusaurus-plugin-ideal-image/     Responsive images
│   ├── docusaurus-plugin-svgr/            SVG as React components
│   ├── docusaurus-plugin-css-cascade-layers/ CSS @layer support
│   ├── docusaurus-theme-classic/          Standard UI components
│   ├── docusaurus-theme-common/           Shared React hooks + utils
│   ├── docusaurus-theme-search-algolia/   DocSearch integration
│   ├── docusaurus-theme-live-codeblock/   Interactive code editor
│   ├── docusaurus-theme-mermaid/          Diagram rendering
│   ├── docusaurus-theme-translations/     Locale message files
│   ├── docusaurus-module-type-aliases/    TS path aliases
│   ├── docusaurus-tsconfig/               Shared tsconfig base
│   ├── docusaurus-remark-plugin-npm2yarn/ Package manager tabs
│   ├── docusaurus-cssnano-preset/         CSS minifier config
│   ├── create-docusaurus/                 Project scaffolding CLI
│   ├── eslint-plugin/                     ESLint rules
│   ├── stylelint-copyright/               CSS copyright checker
│   └── lqip-loader/                       Low-quality image placeholders
├── website/                      Docusaurus.io website (dogfood)
│   ├── docs/                     Current documentation
│   ├── versioned_docs/           Version snapshots (2.x through 3.10.0)
│   ├── versioned_sidebars/       Version sidebar configs
│   ├── blog/                     Blog posts
│   ├── src/                      Custom pages and components
│   ├── _dogfooding/              Internal test content
│   └── docusaurus.config.ts      Website config
├── examples/                     Template examples (classic, classic-ts)
├── admin/                        Admin scripts and new.docusaurus.io
├── argos/                        Visual regression testing
├── jest/                         Jest configuration
└── package.json                  Root workspace config

Module Deep Dive: Core Engine (@docusaurus/core)

CLI (src/commands/cli.ts): Commander-based CLI registration. 8 built-in commands plus external command passthrough via externalCommand() which loads plugins to check for custom commands.

Build (src/commands/build/): Orchestrates the full build pipeline — loads context, initializes plugins, generates routes, runs bundler, performs SSG. The --bundle-analyzer flag activates webpack-bundle-analyzer for treemap visualization.

Start (src/commands/start/): Dev server with HMR. Polls filesystem when --poll is set (useful for network drives or Docker volumes). Auto-opens browser unless --no-open.

Deploy (src/commands/deploy.ts): GitHub Pages deployment via Git operations. Builds SSH or HTTPS URLs based on USE_SSH, clones the deploy branch into a temp directory, copies build output, commits, and pushes. All execa.commandSync calls are logged (obfuscating GIT_PASS).

Server (src/server/): Config loading, plugin initialization, site metadata, route generation, i18n setup, code generation. The LoadContext object provides site config, paths, and environment to all plugins.

Plugins (src/server/plugins/): Plugin lifecycle management — config normalization, module resolution (shorthand names), option validation, unique ID enforcement, initialization.

Module Deep Dive: Docs Plugin

The docs plugin is the most complex content plugin (~93K chars of source):

  1. Version management: Reads versioned_docs/, versioned_sidebars/, and versions.json to construct a multi-version content tree
  2. Document processing: Parses frontmatter, generates slugs/permalinks, resolves edit URLs, fetches VCS metadata (last author/time)
  3. Sidebar pipeline: Load → Normalize shorthands → Validate → Generate (unwrap autogenerated) → Post-process (defaults, category links, flatten empty)
  4. Navigation: Links docs with previous/next based on sidebar order
  5. CLI extension: Adds docs:version <version> command for creating version snapshots

Module Deep Dive: Blog Plugin

The blog plugin (~104K chars) manages:

  1. Author system: Global authors.yml with schema validation (unique permalinks, normalized images, social links). Supports both key-based references and inline author definitions.
  2. Feed generation: RSS, Atom, JSON feeds with post content. Feed generation errors are caught per-post with descriptive messages.
  3. Post processing: Date parsing, reading time calculation, truncation marker detection, tag normalization.

Module Deep Dive: MDX Loader

The MDX loader (@docusaurus/mdx-loader) provides:

  1. Format detection: .md → CommonMark mode, .mdx → MDX mode, configurable default
  2. Remark plugins: Admonitions (NOTE/TIP/WARNING/etc.), heading IDs, TOC extraction, image transforms, link transforms, npm2yarn, unused directive warnings
  3. Cross-compiler caching: Production-only cache sharing between client and server MDX compilation
  4. Frontmatter handling: Custom Joi extension (JoiFrontMatter) that converts YAML-auto-typed numbers/dates back to strings

Module Deep Dive: Bundler Abstraction

The bundler package (@docusaurus/bundler) abstracts Webpack and Rspack:

  1. CurrentBundler type: Runtime selection between Webpack and Rspack
  2. Persistent caching: Both bundlers support filesystem caching for incremental builds
  3. CSS extraction: MiniCssExtractPlugin (Webpack) or CssExtractRspackPlugin (Rspack)
  4. Custom Rspack progress plugin: CustomRspackProgressPlugin extends Rspack's progress plugin

Module Deep Dive: Logger

The logger (@docusaurus/logger) provides:

  1. Structured logging: Template literal tag API — logger.info\text path=${val}``
  2. Performance tracking: Start/end marks with duration measurement. Enabled via DOCUSAURUS_PERF_LOGGER
  3. Error formatting: Interpolated error messages with code, path, name formatters

Code Patterns and Conventions

Pattern Convention
Module system ES Modules (.ts compiled, .mjs for config)
Error handling Typed errors with {cause: err} chaining
Plugin self-disable Return null from constructor
Unique IDs DEFAULT_PLUGIN_ID = 'default'; uniqueness enforced at init
Path handling Forward slashes everywhere; @docusaurus/utils normalizers
Config validation Joi schemas via @docusaurus/utils-validation
Trailing slash Centralized normalization in utils; configurable per-site
VCS integration Optional Git-based last-update metadata (author, time)
Content visibility isDraft() / isUnlisted() — production-only filtering
Data file loading YAML/JSON support; localized paths take priority
Async-first Plugin lifecycle is fully async; build commands await all phases

Constants (@docusaurus/utils/src/constants.ts)

Constant Value Description
DEFAULT_BUILD_DIR_NAME 'build' Output directory name
GENERATED_FILES_DIR_NAME '.docusaurus' Generated files directory
SRC_DIR_NAME 'src' Source directory name
DEFAULT_STATIC_DIR_NAME 'static' Static assets directory
DEFAULT_PORT 3000 Default server port
DEFAULT_PLUGIN_ID 'default' Default plugin instance ID

Testing Strategy

Layer Tool Configuration
Unit tests Jest 30 @swc/jest transform, jest.config.ts at root
DOM tests @testing-library/react jsdom environment
Snapshot tests Jest + custom serializers jest-serializer-ansi-escapes, jest-serializer-react-helmet-async
Visual regression Argos + Playwright Screenshots compared against baselines
Type checking TypeScript 6.0 tsc (not run during build)

Test fixtures live alongside source: src/__tests__/__fixtures__/. The monorepo uses @swc/jest for fast test compilation.

ESLint Rules (@docusaurus/eslint-plugin)

The custom ESLint plugin enforces:

  1. No synchronous filesystem operations — prevents blocking the event loop in plugin code
  2. No direct lodash imports — enforces specific sub-module imports for tree-shaking
  3. Coupling restrictions — prevents improper cross-references between content plugins

Enforces copyright header comments at the top of CSS files.

Potential Improvements

Based on source analysis:

  1. TypeScript 6.0 migration: The @docusaurus/tsconfig base needs updates for the baseUrl deprecation (issue #11893)
  2. CommonMark mode expansion: Feature request #9092 tracks making more features work without MDX (head tags, live code blocks, tabs)
  3. Rspack stability: The Rspack bundler path is opt-in; some edge cases with i18n on Cloudflare Pages remain (issue #11961)
  4. execa migration: Deploy command uses execa.commandSync with manual argument escaping; a TODO in source notes migration to execa(file, [...args]) with async/await
  5. PWA hash router incompatibility: The PWA plugin explicitly detects and warns about hashRouter usage
  6. text{ pattern in LaTeX: MDX/Acorn error triggered by certain LaTeX syntax (issue #11235)

Contributing

The monorepo uses:

  • Yarn workspaces for package management
  • Lerna for versioning and publishing
  • Husky for pre-commit hooks
  • lint-staged for staged-file linting
  • Prettier for code formatting
  • CSpell for spell checking with a project-words.txt dictionary
  • Syncpack for dependency version consistency

Development workflow:

yarn install          # Install all dependencies + build packages (postinstall)
yarn start            # Build packages then start website
yarn test             # Run Jest tests
yarn lint             # ESLint + Stylelint + CSpell + Syncpack
yarn format           # Prettier formatting

Package build: lerna run build --no-private compiles all public packages. The postinstall hook runs patch-package, yarn-deduplicate, and package builds.

Canary releases: Automated via yarn canary which bumps to a canary version tag (<version>-canary-<count>+<sha>) and publishes to the canary dist-tag.

9. Integration Points

Algolia DocSearch

The search theme detects DocSearch version (v3 vs v4) and configures webpack aliases for backward compatibility. It generates:

  • OpenSearch XML (opensearch.xml) for browser search integration
  • A search page route at the configured searchPagePath
  • Translation messages for localized search UI

Analytics Providers

Provider Plugin Injection
Google Analytics 4 plugin-google-gtag gtag.js script in <head>
Google Tag Manager plugin-google-tag-manager GTM script + noscript iframe
Google Analytics (legacy) plugin-google-analytics analytics.js script
Vercel Analytics plugin-vercel-analytics Vercel script injection

All analytics plugins check NODE_ENV === 'production' before injecting scripts.

Crowdin (Translation Management)

The Docusaurus website uses Crowdin for translation management:

yarn crowdin:upload:website     # Upload source strings
yarn crowdin:download:website   # Download translations (fr, ko, pt-BR, zh-CN, ja)

Configuration lives in crowdin-v2.yaml at the repo root.

CI/CD Integration

Netlify detection: Checks NETLIFY and CONTEXT env vars. Deploy previews may adjust build behavior.

CircleCI integration: Deploy command falls back to CIRCLE_PROJECT_USERNAME / CIRCLE_PROJECT_REPONAME for organization/project names, and checks CI_PULL_REQUEST / CIRCLE_PULL_REQUEST to skip deploy on PR builds.

Generic CI: CI env var is checked by serve command to default --no-open (don't try to open a browser in CI).