Summary
We don't currently scaffold a docs site in this template: packs inherit a long README and three reference markdowns under docs/. As more packs ship and we want a consistent "Nebari pack" presentation, we need to pick a static site generator (SSG) and bake it into the template so that every new pack starts with the same shape.
The current state of the art across our repos is inconsistent:
This issue captures the comparison and trade-offs from a recent design discussion, so the team (and future template consumers) can see how the choice was reached and what's still open.
Constraints we're working under
The decision is mostly determined by how nebari-dev/nebari-design is distributed. After looking at it in depth:
- It's a shadcn/ui-style registry, not a published npm package (
"private": true in package.json).
- Components are TSX source under
registry/nebari/ui/, built on React 19 + Base UI primitives + Tailwind v4 + lucide-react + class-variance-authority + tailwind-merge.
- Consumers integrate via
bunx shadcn add <component> — which copies the React source into the consumer's repo. There's no CDN bundle, no compiled UMD, no web-component wrappers.
- The CSS tokens (
registry/nebari/globals.css) are Tailwind v4 @theme declarations: light + dark, semantic naming (background / foreground / primary / etc.), OKLCH colors. These are framework-agnostic as long as your build runs Tailwind v4.
- The repo's own
build:pages script ships Storybook + the registry to GitHub Pages, so the integration model is "consumers fetch from a hosted registry."
Two implications follow:
- Any docs site that wants to use nebari-design components needs React + Tailwind v4 + TypeScript in its build. There's no escape hatch — the components don't exist as a pre-compiled bundle that you can
<script src> into HTML.
- Any docs site that wants nebari-design's colors / typography / spacing needs Tailwind v4 in its build, because the tokens are Tailwind v4
@theme declarations.
So the practical question is "which SSG fits a Tailwind-v4-plus-shadcn-React design system most naturally?"
Hosting policy
The org runs two different deploy targets depending on the docs site's scope:
nebari.dev (the main docs, currently Docusaurus) lives on Netlify. Netlify earns its keep there: deploy previews on every PR, redirects, custom-domain wiring, larger build budget — the long-lived flagship docs need that.
- Pack docs sites should default to GitHub Pages. Reasons:
- One workflow file per repo; no separate Netlify project or dashboard to manage per pack.
- No subscription / build-minutes dependency. Public-repo gh-pages is free and scales horizontally to N packs.
- Each pack gets a predictable URL (
<org>.github.io/<repo> or a custom domain) without org-level coordination.
- Avoids the "who pays for the Netlify account when a pack maintainer is no longer on the team" footgun.
This is a default, not a constraint — an individual pack maintainer can migrate their pack's docs to Netlify if they have a genuine need (deploy previews on PRs, large traffic, redirect rules). But the template scaffolding should ship a gh-pages workflow as the out-of-the-box path.
All three SSGs we're comparing deploy to gh-pages cleanly via the standard actions/upload-pages-artifact + actions/deploy-pages chain, so this constraint doesn't break the tie between them — but it does shape the workflow shape we'll bake into the template, and it's worth surfacing here so reviewers don't assume Netlify everywhere.
Options
Hugo
- Pros: blazing-fast builds (Go binary), single tool, simple authoring (markdown + frontmatter + occasional shortcodes), team has prior experience (Chuck + others). Native gh-pages deploy via the official action. Themes like Doks / Geekdoc / Hextra are technical-docs-friendly.
- Cons against nebari-design: needs a Tailwind v4 build step bolted on via Hugo Pipes + PostCSS, so the "no Node in CI" advantage evaporates the moment we import
globals.css. Cannot consume shadcn components at all without us writing per-component web-component shims and re-publishing them — a maintenance liability that grows with nebari-design.
- Fit verdict: clean for pack docs that want visual identity without runtime components. Forces a parallel build pipeline if we ever want to ship an interactive widget.
Astro
- Pros: purpose-built for "mostly static markdown, with islands of interactive components." Native React + Tailwind v4 + MDX. Can consume the shadcn registry directly —
bunx shadcn add button inside an Astro pack's docs/ lands the same TSX the rest of Nebari uses. Static-by-default like Hugo; same gh-pages workflow shape. Components hydrate only on pages that use them, so markdown pages stay pure HTML.
- Cons: Node + a bundler in CI (but we're paying that anyway for Tailwind v4). Team has less institutional experience than Hugo. Versioning / search / i18n need to be assembled from parts (Pagefind for search, branch-based versioning, etc.) — not built-in like Docusaurus.
- Fit verdict: lowest-friction option for the nebari-design integration specifically. Marginal cost over Hugo is small once you accept Tailwind v4 in the toolchain.
Docusaurus
- Pros: already proven in
nebari-docs and nebari-nebi-pack. Native React + MDX. Versioning, search, i18n, blog, plugins all built-in. Maintainers across the org already know the authoring conventions.
- Cons: heavier runtime than Astro for similar React-native capability. Theming is more opinionated; aligning with nebari-design's Tailwind v4 tokens fights Docusaurus's own theming layer somewhat. Larger bundles = slower first paint than Hugo or Astro.
- Fit verdict: correct choice for the deep, long-lived
nebari-docs site. For a thin pack-docs scaffold that ships in every pack template, heavier than necessary.
Tradeoff at a glance
|
Hugo |
Astro |
Docusaurus |
| Tailwind v4 (tokens) |
Add via Hugo Pipes + PostCSS |
Native |
Native (but fights theme layer) |
| Shadcn component adoption |
Custom-element shim per component |
bunx shadcn add works directly |
bunx shadcn add works directly |
| First paint |
Lowest (no JS) |
Low (islands hydrate only where used) |
Medium (SSR + hydration of React shell on every page) |
| CI weight |
Hugo binary + Node + Tailwind |
Node + bundler |
Node + bundler |
| Versioning / search / i18n |
DIY |
DIY (lightweight) |
Built-in |
| Team familiarity |
High (Chuck + others) |
Medium (some experience) |
High (nebari-docs incumbent) |
| Authoring |
Markdown + Hugo shortcodes |
Markdown / MDX + Astro components |
MDX |
| Migration story for existing Docusaurus packs |
Re-author |
Re-author |
None (already there) |
| gh-pages workflow fit (org default for packs — see "Hosting policy" above) |
Native; standard upload-pages-artifact action |
Native; standard upload-pages-artifact action |
Native; docusaurus deploy or upload-pages-artifact. Main docs on Netlify is org-policy, not a tool limit. |
Recommendation
Astro for pack docs, deployed to gh-pages, consuming nebari-design via shadcn add.
Reasoning:
- The moment a pack imports
nebari-design/registry/nebari/globals.css to get the visual identity, we need Tailwind v4 in the build. Hugo's "no Node toolchain" advantage stops being an advantage at that point.
- The shadcn distribution model is fundamentally React-native. Astro consumes it with zero adapter code. Hugo would require a web-component shim layer that we'd maintain forever. That asymmetry is large enough to overrule team-familiarity arguments.
- Astro is also lighter than Docusaurus for the same React capability, leaving
nebari-docs (Docusaurus) as the heavy / long-lived docs site and packs as fast / lightweight satellites. Clean mental model: "deep docs = Docusaurus, pack docs = Astro."
Hugo stays defensible if the team decides pack docs explicitly don't need to consume nebari-design components — only its visual identity, hand-replicated in vanilla CSS. That's a valid simplification but it means the design library's value proposition stops at pack docs.
Docusaurus stays defensible as the choice for any individual pack that wants the nebari-docs feature set (versioning / search / i18n). New packs can opt in if they need it; the template default doesn't force them.
Proposed next step
Spike a minimal Astro docs site in provenance-collector to prove the integration end-to-end.
If it lands well, the skeleton graduates into this template as docs/site/ (or similar) and every future pack gets it for free via "Use this template."
References
Summary
We don't currently scaffold a docs site in this template: packs inherit a long README and three reference markdowns under
docs/. As more packs ship and we want a consistent "Nebari pack" presentation, we need to pick a static site generator (SSG) and bake it into the template so that every new pack starts with the same shape.The current state of the art across our repos is inconsistent:
nebari-dev/nebari-docsnebari-dev/nebari-nebi-packnebari-dev/skillsctlThis issue captures the comparison and trade-offs from a recent design discussion, so the team (and future template consumers) can see how the choice was reached and what's still open.
Constraints we're working under
The decision is mostly determined by how
nebari-dev/nebari-designis distributed. After looking at it in depth:"private": trueinpackage.json).registry/nebari/ui/, built on React 19 + Base UI primitives + Tailwind v4 + lucide-react + class-variance-authority + tailwind-merge.bunx shadcn add <component>— which copies the React source into the consumer's repo. There's no CDN bundle, no compiled UMD, no web-component wrappers.registry/nebari/globals.css) are Tailwind v4@themedeclarations: light + dark, semantic naming (background / foreground / primary / etc.), OKLCH colors. These are framework-agnostic as long as your build runs Tailwind v4.build:pagesscript ships Storybook + the registry to GitHub Pages, so the integration model is "consumers fetch from a hosted registry."Two implications follow:
<script src>into HTML.@themedeclarations.So the practical question is "which SSG fits a Tailwind-v4-plus-shadcn-React design system most naturally?"
Hosting policy
The org runs two different deploy targets depending on the docs site's scope:
nebari.dev(the main docs, currently Docusaurus) lives on Netlify. Netlify earns its keep there: deploy previews on every PR, redirects, custom-domain wiring, larger build budget — the long-lived flagship docs need that.<org>.github.io/<repo>or a custom domain) without org-level coordination.This is a default, not a constraint — an individual pack maintainer can migrate their pack's docs to Netlify if they have a genuine need (deploy previews on PRs, large traffic, redirect rules). But the template scaffolding should ship a gh-pages workflow as the out-of-the-box path.
All three SSGs we're comparing deploy to gh-pages cleanly via the standard
actions/upload-pages-artifact+actions/deploy-pageschain, so this constraint doesn't break the tie between them — but it does shape the workflow shape we'll bake into the template, and it's worth surfacing here so reviewers don't assume Netlify everywhere.Options
Hugo
globals.css. Cannot consume shadcn components at all without us writing per-component web-component shims and re-publishing them — a maintenance liability that grows with nebari-design.Astro
bunx shadcn add buttoninside an Astro pack'sdocs/lands the same TSX the rest of Nebari uses. Static-by-default like Hugo; same gh-pages workflow shape. Components hydrate only on pages that use them, so markdown pages stay pure HTML.Docusaurus
nebari-docsandnebari-nebi-pack. Native React + MDX. Versioning, search, i18n, blog, plugins all built-in. Maintainers across the org already know the authoring conventions.nebari-docssite. For a thin pack-docs scaffold that ships in every pack template, heavier than necessary.Tradeoff at a glance
bunx shadcn addworks directlybunx shadcn addworks directlyupload-pages-artifactactionupload-pages-artifactactiondocusaurus deployorupload-pages-artifact. Main docs on Netlify is org-policy, not a tool limit.Recommendation
Astro for pack docs, deployed to gh-pages, consuming nebari-design via shadcn
add.Reasoning:
nebari-design/registry/nebari/globals.cssto get the visual identity, we need Tailwind v4 in the build. Hugo's "no Node toolchain" advantage stops being an advantage at that point.nebari-docs(Docusaurus) as the heavy / long-lived docs site and packs as fast / lightweight satellites. Clean mental model: "deep docs = Docusaurus, pack docs = Astro."Hugo stays defensible if the team decides pack docs explicitly don't need to consume nebari-design components — only its visual identity, hand-replicated in vanilla CSS. That's a valid simplification but it means the design library's value proposition stops at pack docs.
Docusaurus stays defensible as the choice for any individual pack that wants the
nebari-docsfeature set (versioning / search / i18n). New packs can opt in if they need it; the template default doesn't force them.Proposed next step
Spike a minimal Astro docs site in provenance-collector to prove the integration end-to-end.
If it lands well, the skeleton graduates into this template as
docs/site/(or similar) and every future pack gets it for free via "Use this template."References
nebari-dev/nebari-design— shadcn registry, package.json, registry.json, registry/nebari/globals.cssnebari-dev/nebari-docs— current Docusaurus incumbent for org-wide docsnebari-dev/nebari-nebi-pack— existing pack on Docusaurusnebari-dev/skillsctl— existing pack on a custom stack (untheamed)