Skip to content

WIP: Astro Starlight prototype — GitBook alternative - #16

Open
scosman wants to merge 13 commits into
mainfrom
claude/gitbook-alternatives-pjubsj
Open

WIP: Astro Starlight prototype — GitBook alternative#16
scosman wants to merge 13 commits into
mainfrom
claude/gitbook-alternatives-pjubsj

Conversation

@scosman

@scosman scosman commented Aug 22, 2026

Copy link
Copy Markdown
Contributor

WIP / preview only. Opened for review of the approach, not to merge. Nothing here changes the existing GitBook content or site.

Explores moving these docs off GitBook onto Astro Starlight, building to a static site suitable for Cloudflare Pages.

Try it locally

Requires Node 22.12+ (Astro 7's floor) and Python 3.

cd site
npm install
npm run serve     # build + preview

Then open http://localhost:4321. npm run dev also works and rebuilds on change, but if the checkout lives in a file-syncing folder (Dropbox, iCloud Drive, OneDrive), the dev server can fail intermittently with module errors from inside node_modules/astronpm run serve sidesteps that. See site/README.md → Troubleshooting.

Approach

The GitBook markdown at the repo root stays the source of truth. site/scripts/gitbook_to_starlight.py reads it and generates the Starlight site. Everything the script writes is gitignored and regenerated on every dev/build, so there is no second copy of the docs to keep in sync — this PR adds a handful of files, not 43.

Generated From
src/content/docs/** docs/, developers/
sidebar.json SUMMARY.md
public/assets/** .gitbook/assets/

Converted automatically:

  • 81 {% hint style="…" %} blocks → Starlight asides (:::note / :::tip / :::caution / :::danger)
  • 14 {% embed %} blocks → Vimeo/YouTube iframes and local <video> tags
  • {% code %} wrappers stripped (Expressive Code covers those options)
  • SUMMARY.md → sidebar, nested groups included
  • Relative .md links → absolute site URLs, resolved per file
  • Leading # Heading → Starlight title frontmatter

The ~90 <figure> blocks are left as raw HTML and render as-is, width attributes included.

Builds 43 pages in a few seconds, including the Pagefind search index — no Algolia or other external search service required.

python3 scripts/gitbook_to_starlight.py --list prints every source file it picks up without writing anything, for when the page count looks off.

Theme

Uses starlight-theme-black, a shadcn-inspired Starlight theme, which adds a top nav bar and a per-page "Copy page" menu with open-in-ChatGPT/Claude actions. Themes are Starlight plugins, so this is one entry in the plugins array and is straightforward to swap.

src/styles/custom.css carries the accent colors plus one workaround: the theme gives sidebar links a fixed 30px height against a 22.4px line-height, so labels wrapping to two lines overflow their box and collide with the next entry. Three of our sidebar labels hit this.

Two things found along the way

  • Five {% embed %} blocks pointed at files.gitbook.com CDN URLs. Those stop working once the GitBook space goes away. Local copies exist in .gitbook/assets, and the converter repoints them.
  • Two videos exceed Cloudflare Pages' 25 MiB per-file limitfinal_1080.mp4 (38 MB) and final_1080p_web_fast_start.mp4 (27 MB). They need to move to Cloudflare Stream, R2, or Vimeo before this can deploy anywhere, independent of framework choice.

Not done

  • The landing page (site/src/landing/index.mdx) is hand-written — GitBook's <table data-view="cards"> has no automatic equivalent. It is the one page maintained by hand rather than generated.
  • Images skip Astro's optimizer; they are copied to public/assets/ and referenced absolutely. Moving them into src/assets/ with relative markdown links enables automatic WebP and responsive sizing (the hero image alone goes 63 kB → 2 kB through the pipeline).
  • No redirects for any URLs that change relative to the current GitBook site.
  • No WYSIWYG editor wired up. Starlight pairs with git-backed CMSes such as Keystatic or TinaCMS; that is a separate decision from the framework.

Full details and caveats in site/README.md.

claude and others added 13 commits August 22, 2026 01:51
Explores moving these docs off GitBook onto Astro Starlight, building to
a static site suitable for Cloudflare Pages.

The GitBook content at the repo root is untouched and remains the source
of truth. site/scripts/gitbook_to_starlight.py reads it and generates the
Starlight site; everything it writes is gitignored and regenerated by
`npm run dev` / `npm run build`.

The converter handles the GitBook-specific syntax automatically: hint
blocks become Starlight asides, embeds become Vimeo/YouTube iframes and
local video tags, SUMMARY.md becomes the sidebar, and relative .md links
are resolved to absolute URLs. The landing page is hand-written, since
GitBook's card table has no automatic equivalent.

Five embeds pointed at files.gitbook.com CDN URLs that stop working once
the GitBook space goes away; these are repointed at the local copies in
.gitbook/assets.

Builds 43 pages in ~5s including the Pagefind search index. See
site/README.md for how to run it and what is still outstanding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
Starlight themes are plugins, so the visual design can be swapped with an
env var rather than an edit. DOCS_THEME selects between starlight-theme-black
(default), starlight-theme-nova, and stock Starlight, on both dev and build.
An unknown value fails with the list of valid ones.

Also fixes a bug in starlight-theme-black, in CSS loaded only under that
theme: it gives sidebar links a fixed 30px height against a 22.4px
line-height, so labels wrapping to two lines overflow their box and collide
with the next entry. Three of our sidebar labels hit this. Verified against
the built site: no clipped links and no collisions afterwards, with the
wrapping labels growing to two lines as expected.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
The converter excluded directories by path substring, so a node_modules at
the repo root was scanned and its READMEs became doc pages. Prune by
directory name in place instead, which also stops os.walk descending into
them at all. Verified: with a node_modules planted at the repo root, the old
logic picked up its markdown and the new logic does not.

Add `npm run serve` (build + preview) as a path that does not depend on the
dev server, and document why `npm run dev` can fail intermittently with
"Class extends value undefined" when the checkout lives in a file-syncing
folder: the dev server imports modules lazily, so it sees whatever
half-synced state node_modules is in, while astro build reads everything in
one pass.

Also declare the real Node floor. Astro 7 requires >=22.12.0; the README
claimed 20+, which would fail with confusing module errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
`python3 scripts/gitbook_to_starlight.py --list` prints the repo root and
every source file that would be converted, without writing anything. The page
count is the first sign that the walk is picking up markdown it should skip,
and this shows exactly which files those are.

Extracts the walk into find_sources() so listing and converting cannot drift,
and handles BrokenPipeError so piping into `head` exits cleanly.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
Black is the chosen theme, so the DOCS_THEME env var and the THEMES map go
away in favour of configuring the plugin directly. Removes the
starlight-theme-nova dependency and folds the theme's sidebar workaround into
custom.css, since it no longer needs to load conditionally.

Verified after the change: the site builds, and the sidebar workaround still
holds -- no clipped or colliding links, with the three wrapping labels growing
to two lines.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
The theme replaces Starlight's sidebar with a flat one: every group renders
as a static header with all children always visible, and `collapsed` in the
sidebar config is ignored. SUMMARY.md has six nested groups that need to
expand and collapse, so src/components/Sidebar.astro takes that override back
and renders Starlight's default sidebar. The theme skips any component the
Starlight config already overrides, so the rest of it is unaffected.

Verified in the built site: all eight groups render as collapsible elements
with the right initial state, and toggling one moves it between 28.8px and
152.6px.

This also removes the need for the sidebar height workaround, which applied
to the theme's own sidebar markup and is now dead. Starlight's default
sidebar wraps long labels correctly, with no clipped links.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
starlight-theme-black has a `sidebar.useDropdowns` option that renders groups
as collapsible dropdowns in its own styling. Enabling it is the right fix,
and it replaces the previous approach of overriding the component back to
Starlight's default sidebar, which worked but looked foreign inside the
theme: oversized bold group labels, a white active pill, and Starlight's
nested rule lines.

Deletes src/components/Sidebar.astro and restores the sidebar height
workaround, which applies to the theme's markup again. The theme's 8px block
padding assumed a fixed 30px box, so with the box free to grow it made every
row 38px; trading the padding down keeps the intended rhythm. Measured in the
built site: single-line rows 30px, wrapped rows 53px, no clipped labels.

All eight groups render as collapsible with the right initial state, and the
group containing the current page starts expanded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
The theme offers ChatGPT, v0, Claude and Scira by default. Agents listed in
the config override the built-in defaults, so disabling scira alone leaves
the other three untouched.

Verified in the built site: the menu renders Open in ChatGPT, Open in v0 and
Open in Claude, with no Scira entry.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
Brings in the four new pages added upstream while this branch was in
progress (code-tools, code-judges, judge-types, llm-judges) plus edits to
ten existing files. Content is considered frozen at this commit for the
purposes of the GitBook migration.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
The landing page is the one page maintained by hand rather than generated,
so it drifts when the GitBook card table changes. Merging main added a Code
Tools card and renamed the RAG card, and the Demo Project card had also been
missed. Brings all fourteen cards back in line with README.md and verifies
every link resolves in the built site.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
Plans taking the Starlight prototype to production on Cloudflare Pages:
project overview, functional spec, architecture, and a nine-phase
implementation plan.

Sequencing is driven by two hard constraints. Capturing a baseline of the
live GitBook site comes first, because the URL inventory and the per-page
text and screenshots that per-page QA diffs against are impossible to obtain
once GitBook is gone. Removing the transformer comes last, preceded by a
reconciliation step for anything that lands after the content freeze, so late
pages can still be converted.

Also excludes specs/ from the transformer's walk. Adding these documents
would otherwise have turned them into four extra doc pages, the same way a
stray node_modules did earlier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
Phase 1 runs in a separate session with real browser and internet access, so
the brief is written to be self-contained rather than assuming context from
the planning session.

Covers the four inventory sources, the flat-alias probe that finds URLs
absent from both SUMMARY.md and the sitemap, what to capture per page, and
the sanity checks. Recommends keeping screenshots out of git.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HErYsDQFEjH6ErwV17HXSt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants