Boltdocs 2.8.0 — Faster, Smarter, and Actually Fun to Use

Jesús AlcaláJesús Alcalá
Boltdocs 2.8.0 — Faster, Smarter, and Actually Fun to Use

Boltdocs 2.8.0 ships real code splitting, a doctor with performance budgets, strict route typing, Algolia DocSearch, a powerful plugin API, a reorganized .boltdocs/ directory, and Mermaid that doesn't drag your whole site down.

This one's about scaleLink

2.8.0 is my biggest release yet. Not because I added a ton of flashy features — but because I finally fixed the stuff that starts hurting when your docs grow past 50 pages.

Info
Note

Code splitting at the route level, a --budget flag for doctor, auto-generated strict route types, Algolia DocSearch integration, a proper plugin API, cleaned up .boltdocs/ structure, and a Mermaid plugin that only loads when there's actually a diagram on the page.


Route-Level Code SplittingLink

Every MDX page used to be eagerly loaded into the main bundle. That meant touching one page recompiled everything. In a big project, that's painful.

Dev startup is now ~45% fasterLink

With 2.8.0, MDX modules load on demand via React.lazy. The numbers speak for themselves:

  • Dev server cold start: from 3.4s down to ~1.8s on a 68-page site
  • HMR: only recompiles the page you're actually editing
  • Production build: each page gets its own chunk
// Before: eager — everything in memory
const modules = import.meta.glob('/docs/**/*.mdx', { eager: true })

// After: lazy + smart prefetch
const modules = import.meta.glob('/docs/**/*.mdx')

Background prefetchLink

After the first render, requestIdleCallback preloads MDX chunks in batches of 6. By the time a user clicks a link, the chunk is already cached. Navigation feels instant.


boltdocs doctor --budgetLink

The doctor command now has a --budget flag. It checks your build against configurable thresholds and yells at you if something is off:

JS Bundle

Max JS bundle size. Helps you catch bloat before it ships.

CSS Bundle

Same for stylesheets — handy when you start stacking visual plugins.

HTML per page

Flags pages that generate too much HTML. Great for SEO audits.

Images

Total KB limit for image assets.

Build time

Fails the build if it takes longer than X seconds. Perfect for CI.

SetupLink

Drop a doctor.json in your project root:

{
  "checks": {
    "performance": {
      "maxJSBundleSize": 200,
      "maxCSSBundleSize": 50,
      "maxPageHTMLSize": 100,
      "maxImagesKB": 500,
      "maxBuildTime": 30,
      "maxFontCount": 3
    }
  },
  "failOnError": true,
  "maxWarnings": 5
}

Then run:

pnpm build && pnpm boltdocs doctor --budget

Every violation is a DoctorIssue with configurable severity. Set failOnError: true and use it as a CI gate.


.boltdocs/ CleanupLink

The output directory is no longer a dumping ground:

.boltdocs/
├── build/        ← SSG build cache
├── cache/        ← Processing caches (routes, etc.)
├── generated/    ← Generated type definitions
└── reports/      ← Diagnostic reports (doctor, etc.)

This isn't cosmetic — separate directories mean external tools (CI scripts, linters, deployment pipelines) can target exactly what they need without guessing internal paths.


Strict Route TypingLink

One of the most requested features. Navbar links, sidebar links, and the Link component now have full autocomplete:

// Before: any string — typos go to production
<Link href="/docs/guides/getting-started/installation">Install</Link>

// After: autocomplete with compile-time validation
<Link href="/docs/guides/getting-started/installation">Install</Link>
// ❌ Error if the route doesn't exist

The BoltdocsRoutePaths type is generated during build and exposed as a global namespace augmentation. Works out of the box with TypeScript and VS Code.


Smarter Mermaid PluginLink

Mermaid now loads only when there are diagrams on the page:

  • Dynamic import: await import('mermaid') inside useEffect — saves ~27KB on pages without diagrams
  • Theme serialization fixed: light/dark theme config now correctly serializes as a JSX attribute. Themes actually work now
  • Better loading state: while the library loads, the raw diagram source is shown instead of an empty animated placeholder
// Same API — just way more efficient
<Mermaid chart={`
graph TD
  A[Install] --> B[Use]
`} />

Cleaner Build OutputLink

The SSG build output went from this noisy mess:

✓ built in 3.2s
✓ built in 3.5s
📄 /docs/...
📄 /docs/guides/...
📄 /blog/hello-world
... (80+ lines)

To this:

✦ Client build complete
✦ Server build complete
✦ Rendering complete
✦ Loader data generated
══════════════════════════════════
  ✓ 71 static pages generated

Each phase gets a visual separator and a clear completion message. The 80+ lines of individual pages collapse into a single counter. Way easier to read, way more useful.


Algolia DocSearchLink

Search just got a whole lot more powerful. While Boltdocs has always shipped with zero-config FlexSearch, 2.8.0 adds first-class Algolia DocSearch support for sites that need cloud-hosted search with analytics, synonym matching, and typo tolerance at scale.

How it worksLink

Add three lines to your boltdocs.config.ts:

import { defineConfig } from 'boltdocs'

export default defineConfig({
  integrations: {
    algolia: {
      appId: 'YOUR_APP_ID',
      apiKey: 'YOUR_SEARCH_ONLY_API_KEY',
      indexName: 'YOUR_INDEX_NAME',
    },
  },
})

When Algolia is configured, the client automatically bypasses FlexSearch and queries your Algolia index directly via the REST API — no npm SDK required.

Smarter fallbackLink

The integration debounces queries at 250ms, supports facet filtering by locale and version out of the box, and maps Algolia's hierarchy results to the same SearchResult shape used internally. Comment out the config during local dev and FlexSearch takes over seamlessly.

Zero bundle costLink

Since it uses the REST API directly instead of the official @docsearch/react package, Algolia support adds zero bytes to your client bundle until you configure it.


Plugin System APILink

2.8.0 introduces a proper plugin API that lets you extend every layer of Boltdocs — from MDX compilation to the Vite build pipeline.

Lifecycle hooksLink

Plugins can hook into the build and dev lifecycle:

HookWhen it runs
beforeBuild / afterBuildBefore and after production build
beforeDev / afterDevDev server starts and finishes
buildEndBuild completes (even on error)
transformMdxTransform MDX source before compilation
transformHtmlTransform final HTML output

What a plugin looks likeLink

import { defineConfig, type BoltdocsPlugin } from 'boltdocs'

const myPlugin: BoltdocsPlugin = {
  name: 'my-plugin',
  enforce: 'pre',
  remarkPlugins: [myRemarkPlugin],
  vitePlugins: [myVitePlugin],
  components: { MyComponent: './components/my-component' },
  hooks: {
    beforeBuild: async (ctx) => {
      ctx.logger.info('Building...')
      ctx.store.set('my-plugin', 'start', Date.now())
    },
    afterBuild: async (ctx) => {
      const start = ctx.store.get('my-plugin', 'start')
      ctx.logger.success(`Done in ${Date.now() - start}ms`)
    },
  },
}

export default defineConfig({
  plugins: [myPlugin],
})

Plugin storeLink

Each plugin gets a namespaced key-value store for sharing data across hooks without collisions. Values are deep-cloned for immutability.

AST utilitiesLink

The plugin API ships with a full toolkit for traversing and manipulating MDX and rehype ASTs:

  • visitNodes, visitRehypeElements, visitMdxElements
  • visitRemarkHeadings, visitRemarkLinks
  • createMdxElement, createRehypeElement, createMdxAttribute
  • addNodeClass, removeNodeClass, hasNodeClass
  • setNodeProperty, getNodeProperty

Security validationLink

Every plugin is validated at startup — duplicate names, semver mismatches, and path traversal attempts are caught before they cause damage. The boltdocs audit command scans installed plugins for network calls and env variable access.


Other bitsLink

  • boltdocs audit: new CLI command that scans plugins for network calls, env access, and path traversal — run boltdocs audit before adding third-party plugins
  • Smart build caching: SSG now computes a SHA-256 hash of client source mtimes. Unchanged sources skip the client rebuild entirely. Individual pages are cached by MD5 hash with automatic garbage collection
  • Pipeline architecture: the build is now a 6-stage pipeline — ConfigResolve → RouteGenerate → SEOValidate → TypeGenerate → SSGBuild → SEOWrite — each with rollback support
  • Unicode in DUI: @bdocs/dui now uses string-width to properly measure Unicode characters. Table alignment finally works when titles contain ✨, 📄, or ✔
  • SSR with Vite 8: moved react-router-dom to ssr.noExternal to fix "module is not defined" errors in Vite 8's SSR module runner
  • Responsive tabs: added overflow-x-auto so tabs scroll horizontally on mobile instead of breaking the layout
  • Mobile padding: px-4 sm:px-6 on the docs layout for better readability on small screens

UpgradingLink

Migration from 2.7.x is straightforward — no breaking changes to the public API. But if you have scripts poking around .boltdocs/, update your paths:

BeforeAfter
.boltdocs/routes.json.boltdocs/cache/routes.json
.boltdocs/types.d.ts.boltdocs/generated/types.d.ts
.boltdocs/cache-*.boltdocs/cache/*

What's nextLink

2.8.0 sets the foundation for native collections (blog, changelog, API docs with their own layouts), deeper Vite 8 integration, and continued plugin API expansion. Collections already landed with pagination support, and I'm looking at more collection types, richer plugin hooks, and deeper SSG customization.

Install or update:

pnpm add boltdocs@latest

Check the full docs to explore everything new.

Last updated on July 27, 2026