Boltdocs 3.3.0 — Faster Builds, CSS-Agnostic Core, and Experimental Routing
Boltdocs 3.3.0 is here
Boltdocs 3.3.0 continues the Nitro work started in 3.1.0 and 3.2.0: less work during startup, better concurrency, and fewer assumptions in core — plus opt-in APIs for SEO, transitions, and custom pages.
On the 100-page benchmark site, the cold build dropped from 17.85s to 14.50s compared with the previous published run (~19% faster), dev startup improved to 5.3s, and warm builds finish in 3.1s. These are benchmark results, not a guarantee for every project — methodology on the benchmark page.
Faster startup and builds
- Early Sätteri precompilation starts at
configResolved(), so MDX workers prepare files while Vite initializes its graph. - Dynamic worker sizing scales the pool with CPU count and file count instead of a fixed size.
- Non-blocking dev startup lets the server listen before background route generation finishes.
- Lazy Shiki grammars: only ~10 common languages load eagerly; the rest register on demand. The highlighter is ready in ~250ms instead of ~2.5s.
- Full-site dev prewarming: after startup, every route compiles in the background in small priority batches, so navigation hits already-built modules.
- Compact route payload: route data serializes without indentation, cutting what the browser parses before hydration.
A CSS-agnostic core
Core no longer assumes Tailwind CSS: vanilla CSS, CSS Modules, custom properties, and built-in theme tokens work out of the box. CSS integrations are explicit plugins:
| Package | Purpose |
|---|---|
@bdocs/plugin-tailwindcss | Tailwind CSS v4 through the Vite integration |
@bdocs/plugin-sass | SASS and SCSS preprocessing |
@bdocs/plugin-unocss | UnoCSS atomic utilities |
Cleaner project aliases
Boltdocs 3.3.0 adds a first-class aliases option for project-specific imports. The core now keeps its own runtime aliases configured automatically, so you no longer need to copy aliases such as boltdocs/client, boltdocs/entry, or use-sync-external-store into your project configuration:
import { defineConfig } from 'boltdocs'
export default defineConfig({
aliases: {
'@components': './src/components',
'@data': './src/data',
},
})
Relative replacements resolve from the project root. The object and array formats supported by Vite are both accepted. Existing advanced vite.resolve.alias settings remain compatible and are merged with aliases; framework aliases stay authoritative so a custom resolve block cannot accidentally disable the Boltdocs runtime.
Typed plugin hooks
definePlugin() gives plugin authors typed lifecycle hooks across client UI, providers, frontmatter, search indexing, and build assets:
import { definePlugin } from 'boltdocs'
export default definePlugin(() => ({
name: 'my-plugin',
hooks: {
'frontmatter:transform'(_ctx, { frontmatter, rawContent }) {
return {
...frontmatter,
readingTime: Math.ceil(rawContent.split(/\s+/).length / 200),
}
},
'build:generate'(ctx, { routes, outDir }) {
ctx.logger.info(`Generated assets for ${routes.length} routes in ${outDir}.`)
},
},
}))
Complete hook list in the Plugin API reference.
Opt-in SEO and page APIs
JSON-LD structured data
Configure a global graph with helpers from the Node entrypoint; per-page data goes through seo.structuredData in frontmatter:
import {
createWebSiteStructuredData,
defineConfig,
defineStructuredData,
} from 'boltdocs'
export default defineConfig({
siteUrl: 'https://example.com',
seo: {
structuredData: defineStructuredData(
createWebSiteStructuredData({ name: 'Example Docs', url: 'https://example.com' }),
),
},
})
Article and breadcrumb helpers in the SEO guide.
View Transitions
Opt-in, and degrade to normal updates when the browser lacks document.startViewTransition:
export default defineConfig({
experimental: {
viewTransitions: { enabled: true, types: ['page'] },
},
})
Custom layouts can call useViewTransition() from boltdocs/client. See Experimental Features.
Static pages-external routing
Literal file routes without building a pages object:
docs/pages-external/
├── home.tsx → /home
├── about.tsx → /about
└── pricing.mdx → /pricing
Enabled with experimental.fileRouting. Dynamic segments, route groups, and reserved helper files are ignored in this first version; the existing pages-external/index.tsx API remains available. Both APIs are covered in the External Pages guide.
Collections show recent posts first
Collection posts sort by descending publication date across usePosts(), useRecentPosts(), virtual collection data, and default blog pagination. Missing or invalid dates are placed last.
A sharper plugin audit
boltdocs audit statically scans installed plugins for risky calls without executing them. This release fixes correctness and speed:
- Accurate resolution — scoped packages pair via import specifiers even when the plugin name differs (
boltdocs-plugin-mermaidnow audits@bdocs/plugin-mermaid). - Bounded scans — each plugin gets an 8 MB byte budget; crossing it reports
scan-truncatedinstead of a false clean pass. - Fail-closed summaries — unresolvable or unscannable plugins count as untrusted.
- ~30% faster CLI — audits skip full config validation, and
--help/--versionno longer load the UI toolkit.
boltdocs audit
Reported signals and the CI exit-code contract live in the CLI reference.
Upgrade
pnpm add boltdocs@latest @bdocs/ssg@latest
CSS framework users should install their integration plugin. Existing projects can upgrade without enabling any experimental flag.