Docusaurus Build & CI/CD Optimization Plan
Created: 2026-03-22 Status: VERIFIED Approved: Yes Iterations: 0 Worktree: No Type: Feature
Summary
Goal: Optimize Docusaurus build/dev performance using experimental Rspack+SWC bundling, standardize on Yarn, add Cloudflare Pages deployment config, and create a GitHub Actions CI workflow for PR validation.
Architecture: Enable the full experimental_faster feature set in Docusaurus 3.9.2 (Rspack bundler, SWC transpilation/minification, Lightning CSS, persistent cache, SSG worker threads, MDX cross-compiler cache). Add Cloudflare Pages _headers for aggressive static asset caching. Create a GitHub Actions workflow for typecheck + build validation on PRs.
Tech Stack: Docusaurus 3.9.2, @docusaurus/faster, Rspack, SWC, Yarn 1.22.22, Cloudflare Pages, GitHub Actions
Scope
In Scope
- Enable all
experimental_fasterflags indocusaurus.config.ts - Install
@docusaurus/fasterpackage - Remove stale
package-lock.json(standardize on Yarn) - Add Cloudflare Pages
_headersfile for CDN caching - Add Cloudflare Pages
_redirectsfile - Create GitHub Actions CI workflow (typecheck + build)
- Add
wrangler.tomlfor local Cloudflare Pages dev preview
Out of Scope
- Image optimization/compression (separate concern, can be addressed later)
- Mermaid lazy-loading or removal (functional change, not build optimization)
- Blog author warning fix (content issue, not build perf)
- Cloudflare Pages dashboard configuration (already set up)
- Production deployment pipeline changes (already working)
Context for Implementer
Write for an implementer who has never seen the codebase.
- Patterns to follow:
docusaurus.config.ts:5-12— thefutureblock already hasv4: true. Theexperimental_fasterblock goes alongside it insidefuture. - Conventions: TypeScript config files, Yarn for package management, static assets go in
static/ - Key files:
docusaurus.config.ts— main Docusaurus configuration (build, plugins, themes)package.json— dependencies, scripts,packageManagerfield set toyarn@1.22.22static/— files copied as-is to build output (where_headers,_redirectsgo).gitignore— currently ignores/node_modules,/build,.docusaurus,.cache-loader
- Gotchas:
- Both
yarn.lockandpackage-lock.jsoncurrently exist — onlyyarn.lockshould remain - The
future: { v4: true }shorthand enables v4 breaking changes but NOTexperimental_faster— those are separate flags requiring the@docusaurus/fasterpackage - The
@docusaurus/theme-mermaidtheme triggers avscode-languageserver-typeswebpack warning — this is cosmetic and unrelated to our changes - Cloudflare Pages serves files from the
build/directory and reads_headers/_redirectsfrom the build output root (which means they go instatic/pre-build) - Rspack persistent cache stores in
./node_modules/.cache— Cloudflare Pages CI cachesnode_modulesbetween builds automatically
- Both
- Domain context: This is a documentation site for Vidra (a Go video platform). Build speed matters for developer iteration and CI pipeline cost. The site is small (12 docs, 1 blog post) but the mermaid theme and webpack bundling make builds slower than necessary.
Assumptions
@docusaurus/fasteris compatible with Docusaurus 3.9.2 — supported by [Docusaurus 3.6+ release notes, context7 docs] — Tasks 1, 2 depend on this- Cloudflare Pages CI may cache
node_modulesbetween builds (includingnode_modules/.cachewhere Rspack persistent cache lives) — unverified assumption, Cloudflare Pages cache behavior is environment-dependent. If cache doesn't persist, warm builds in CI will equal cold builds. Local dev still benefits regardless. — Task 2 depends on this for CI persistent cache benefit - The GitHub repo is hosted at
github.com/yosefgamble/vidra-docs— supported by [docusaurus.config.ts:18] — Task 4 depends on this - Cloudflare Pages project is already connected to this GitHub repo for deployments — supported by [user confirmation: "already deployed"] — Task 3 depends on this
Risks and Mitigations
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
experimental_faster Rspack bundler has edge cases with mermaid theme | Medium | Build fails | Each experimental_faster flag is independently toggleable — disable individual flags if one causes issues |
| Persistent cache corruption causes stale builds | Low | Wrong output served | yarn clear script already clears all caches; add cache-bust step to CI workflow |
Removing package-lock.json causes CI confusion | Low | CI install fails | Verify Cloudflare Pages CI is configured for Yarn, not npm |
Goal Verification
Truths
yarn buildcompletes successfully with allexperimental_fasterflags enabled- Cold build time is measurably faster than the 21s baseline
- Warm (cached) build time is significantly faster than cold build
yarn typecheckpasses- GitHub Actions workflow file exists and is syntactically valid
_headersfile is present in build output with correct caching rules- Only
yarn.lockexists (nopackage-lock.json)
Artifacts
docusaurus.config.ts— containsexperimental_fasterconfiguration blockpackage.json— includes@docusaurus/fasterdependency, nopackage-lock.jsonstatic/_headers— Cloudflare Pages caching and security headersstatic/_redirects— Cloudflare Pages redirect rules.github/workflows/ci.yml— GitHub Actions PR validation workflowwrangler.toml— Cloudflare Pages local dev configuration
Progress Tracking
- Task 1: Clean up package manager and install @docusaurus/faster
- Task 2: Enable experimental_faster in docusaurus.config.ts
- Task 3: Add Cloudflare Pages configuration files
- Task 4: Create GitHub Actions CI workflow
Total Tasks: 4 | Completed: 4 | Remaining: 0
Implementation Tasks
Task 1: Clean up package manager and install @docusaurus/faster
Objective: Remove the stale package-lock.json, ensure Yarn is the sole package manager, and install the @docusaurus/faster package required for build optimizations.
Dependencies: None
Files:
- Delete:
package-lock.json - Modify:
package.json(new dependency:@docusaurus/faster) - Modify:
.gitignore(addpackage-lock.jsonto prevent accidental recreation)
Key Decisions / Notes:
@docusaurus/fasteris a peer package that provides SWC and Rspack integrations for Docusaurus 3.6+- The
packageManagerfield inpackage.jsonalready specifiesyarn@1.22.22— keep it - Run
yarn add @docusaurus/fasterto install and updateyarn.lock - Add
package-lock.jsonas a new line in.gitignoreto prevent accidental recreation by npm
Definition of Done:
-
package-lock.jsonis deleted -
package-lock.jsonis in.gitignore -
@docusaurus/fasteris inpackage.jsondependencies -
yarn installsucceeds without errors - No dual lockfile situation
Verify:
ls package-lock.jsonshould fail (file doesn't exist)yarn install --frozen-lockfileshould succeedgrep "docusaurus/faster" package.jsonshould match
Task 2: Enable experimental_faster in docusaurus.config.ts
Objective: Configure all experimental_faster flags to replace webpack with Rspack and Babel with SWC, enabling dramatically faster builds.
Dependencies: Task 1 (needs @docusaurus/faster installed)
Files:
- Modify:
docusaurus.config.ts(addexperimental_fasterblock insidefuture)
Key Decisions / Notes:
- The existing
futureblock atdocusaurus.config.ts:10-12currently hasv4: true— this shorthand expands to individual v4 flags. We need to expand it to an object to addexperimental_fasteralongside. - All flags to enable:
swcJsLoader,swcJsMinimizer,swcHtmlMinimizer,lightningCssMinimizer,rspackBundler,rspackPersistentCache,mdxCrossCompilerCache,ssgWorkerThreads - Pattern from context7 docs shows the exact structure
Definition of Done:
-
docusaurus.config.tshas all 8experimental_fasterflags set totrue -
yarn buildcompletes successfully - Build output is functionally identical (same pages generated)
- Cold build time measured and compared to 21s baseline
- Mermaid diagram assets are present in build output (confirms theme compatibility with Rspack)
Verify:
yarn clear && time yarn build— should succeed and be faster than 21sls build/index.html build/docs/getting-started/overview/index.html— key pages existgrep -rl 'mermaid' build/assets/js/ | head -3— mermaid JS assets present in build
Task 3: Add Cloudflare Pages configuration files
Objective: Create _headers and _redirects files for Cloudflare Pages CDN optimization, plus a wrangler.toml for local dev preview.
Dependencies: None (can run in parallel with Task 2)
Files:
- Create:
static/_headers(Cloudflare Pages caching/security headers) - Create:
static/_redirects(redirect rules) - Create:
wrangler.toml(Cloudflare Pages local dev config)
Key Decisions / Notes:
_headersand_redirectsgo instatic/so Docusaurus copies them tobuild/root where Cloudflare Pages reads them- Fingerprinted assets (
/assets/*) getCache-Control: public, max-age=31536000, immutable(1 year, safe because filenames contain content hashes) - Non-fingerprinted paths get shorter cache (
max-age=3600) with revalidation - Security headers:
X-Content-Type-Options: nosniff,X-Frame-Options: DENY,Referrer-Policy: strict-origin-when-cross-origin wrangler.tomlpointspages_build_output_dirto./buildforwrangler pages devlocal preview- Prevent
*.pages.devURLs from being indexed by search engines
Definition of Done:
-
static/_headersexists with fingerprinted asset caching and security headers -
static/_redirectsexists (even if minimal) -
wrangler.tomlexists withpages_build_output_dir = "./build" - After
yarn build,_headersappears inbuild/root
Verify:
yarn build && cat build/_headers— should show headers contentcat build/_redirects— should show redirect rules
Task 4: Create GitHub Actions CI workflow
Objective: Add a GitHub Actions workflow that runs typecheck and build validation on every PR, catching errors before Cloudflare Pages deploys.
Dependencies: Task 1 (needs clean Yarn setup), Task 2 (build should use new config)
Files:
- Create:
.github/workflows/ci.yml
Key Decisions / Notes:
- Trigger on
pull_requesttomainandpushtomain - Use
actions/setup-node@v4withcache: 'yarn'for dependency caching - Node 22 (matches project's
engines.node >= 20and current local version) - Steps: checkout → setup-node →
yarn install --frozen-lockfile→yarn typecheck→yarn build - The build step validates that all links resolve (
onBrokenLinks: 'throw') - Keep it simple — one job, sequential steps. Separate typecheck and build for clear failure messages.
- Verify
tsconfig.jsonhasnoEmitconfigured (via@docusaurus/tsconfigextends). If not, update thetypecheckscript totsc --noEmitto prevent emitting compiled files in CI.
Definition of Done:
-
.github/workflows/ci.ymlexists with correct syntax - Workflow triggers on PR to main and push to main
- Workflow runs typecheck and build steps
- Yarn dependency caching is configured
-
actionlintor manual YAML validation passes (if available)
Verify:
cat .github/workflows/ci.yml— valid YAML with expected structurenode -e "require('js-yaml').load(require('fs').readFileSync('.github/workflows/ci.yml'))"or manual review
Open Questions
None — all decisions resolved.
Deferred Ideas
- Image optimization: Compress wizard PNGs (230-280KB each) to WebP or use
docusaurus-plugin-ideal-imagefor responsive images - Mermaid lazy loading: The mermaid theme adds ~500KB to JS bundles; could explore code-splitting or conditional loading
- Blog author cleanup: Fix the inline author warning in
2026-03-22-welcome.mdby creatingblog/authors.yml - Broken link monitoring: Add a scheduled CI job to check for broken external links