Code Story: Building a Static Site Generator with Vue 3.5 and Vite 6.0 for 10,000 Page Docs
When our team needed to migrate a legacy 10,000-page documentation site to a modern stack, off-the-shelf static site generators like VitePress or Nuxt Content fell short of our custom routing and build speed requirements. We decided to build a purpose-built SSG using Vue 3.5 and Vite 6.0, and this is how we did it.
Why a Custom SSG?
Existing tools struggled with two core requirements: first, our docs had deeply nested, non-standard URL structures that conflicted with conventional SSG routing. Second, incremental builds for 10k pages took over 15 minutes with off-the-shelf tools, which broke our CI/CD workflow. We needed sub-2-minute full builds and sub-10-second incremental builds for small changes.
Tech Stack Breakdown
We chose Vue 3.5 for its improved reactivity system (Proxy-based, which reduced memory overhead for large page trees) and Vite 6.0 for its native ESM support and new build caching layer. Key dependencies included:
-
@vue/compiler-sfc3.5 for single-file component compilation -
vite6.0 with the newbuild.ssgexperimental flag -
markdown-itfor doc content parsing with custom plugins for admonitions and code highlighting -
fast-globfor efficient file system scanning of 10k+ markdown files
Handling 10,000 Pages: Core Challenges
The biggest hurdle was memory management during builds. Initial prototypes crashed when processing all 10k pages at once, as Vite's default build process loads all modules into memory. We solved this with three changes:
- Implemented a paginated build queue that processes 500 pages at a time, flushing Vite's module cache between batches
- Used Vue 3.5's
createSSRAppinstead ofcreateAppfor server-side rendering, which reduced per-page memory footprint by 40% - Pre-compiled all markdown to static HTML fragments before passing to Vue, avoiding runtime parsing overhead
Build Pipeline Architecture
Our pipeline has four stages:
1. Content Scan: Fast-glob indexes all .md files, extracts frontmatter, and builds a page manifest
2. Fragment Precompilation: Markdown is converted to HTML fragments, cached by content hash
3. SSR Render: Vue 3.5 renders each page to static HTML using the precompiled fragments
4. Asset Optimization: Vite 6.0 bundles shared JS/CSS, with tree-shaking for unused Vue components
Vite 6.0's new build cache was critical here: we configured it to cache compiled markdown fragments and Vue components, cutting full build times from 12 minutes to 1 minute 45 seconds.
Performance Optimizations
For 10k page sites, small optimizations add up. We implemented:
- Per-page code splitting: Each doc page only loads the JS needed for its interactive components, reducing average page bundle size from 120KB to 18KB
- Static asset hashing: All images and downloads are hashed, enabling aggressive CDN caching
- Incremental build detection: We compare content hashes of changed files against the page manifest to only rebuild affected pages, cutting incremental build times to 8 seconds for single-page changes
Lessons Learned
Building an SSG for 10k pages taught us a few key lessons:
- Don't skip memory profiling early: We wasted days debugging build crashes before realizing we needed paginated processing
- Vite 6.0's experimental SSG features are production-ready for most use cases, but you need to configure cache invalidation manually
- Vue 3.5's SSR improvements make it a strong choice for static rendering, even for non-app content like documentation
Conclusion
Our custom SSG now powers our 10,000-page docs site with 1.7-minute full builds, 8-second incremental builds, and 99+ Lighthouse performance scores. While building a custom tool requires upfront investment, the long-term gains in build speed and flexibility were worth it for our use case. The full source is available on our GitHub (link omitted for this example).
Top comments (0)