| name | setup-docs-theme |
| description | Sets up the docs-theme Astro + Starlight documentation theme in a consuming repository. Use this skill whenever a user wants to add, configure, or troubleshoot the docs-theme package in their project.
|
docs-theme Setup Skill
Overview
docs-theme is a GitHub-installable Astro + Starlight documentation theme.
It is configured entirely through a single docs.json file — the consuming
repo never touches Astro config directly.
Theme repo: github:YOUR_ORG/docs-theme
Entry point: index.js exports createDocsConfig(docsJson) and getEcosystemConfig(packageName, ecosystem)
Step 1 — Understand the consuming project
Before writing a single line, gather these facts about the project:
- Package name — exact string used in npm or pub.dev (e.g.
smart_refresher, my-npm-lib)
- Ecosystem — is this a Dart/Flutter package (
pub) or a JavaScript/Node package (npm)?
- GitHub URL — full repo URL, e.g.
https://github.com/ORG/REPO
- Deployed site URL — where will the docs be hosted? (e.g.
https://pkg.docs.example.com)
- Logo — does the project have a logo file? If so, what's the path relative to
docs/?
- Sidebar structure — what sections does the docs have? (Getting Started, Guides, API, etc.)
- Features — what are 4–6 key features of the package? Each needs a title, short description, and an emoji icon.
- CTA — what should the call-to-action say? (label, heading, description, button text + link)
Ask the user for any missing facts. Do not guess the package name, ecosystem, or GitHub URL.
Step 2 — Install the theme
The consuming repo must have a docs/ directory. Run inside the docs/ folder:
npm install github:YOUR_ORG/docs-theme
If docs/package.json doesn't exist yet, create it first:
{
"name": "docs",
"type": "module",
"private": true,
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview"
}
}
Step 3 — Write docs/docs.json
This is the single source of truth. Every field is optional except none are
required — a completely empty {} still produces a working site, but you should
populate as many fields as possible for a quality result.
Full schema
{
"title": "package-name",
"description": "One sentence about what the package does.",
"logo": "./src/assets/logo.svg",
"ecosystem": "npm",
"github": "https://github.com/ORG/REPO",
"site": "https://pkg.docs.example.com",
"packageName": "package-name",
"sidebar": [
{
"label": "Getting Started",
"items": [
{ "label": "Installation", "link": "/getting-started/installation/" },
{ "label": "Quick Start", "link": "/getting-started/quick-start/" }
]
},
{ "label": "Guides", "autogenerate": { "directory": "guides" } },
{ "label": "API Reference", "autogenerate": { "directory": "api" } },
{
"label": "Resources",
"items": [{ "label": "Changelog", "link": "/changelog/" }]
}
],
"features": {
"label": "Capabilities",
"title": "Everything you need.",
"items": [
{
"title": "Feature Name",
"description": "One or two sentences describing this feature.",
"icon": "🚀"
}
]
},
"cta": {
"label": "Ready to dive in?",
"title": "Start building today.",
"description": "Join developers building with package-name.",
"button": {
"text": "Quick Start Guide",
"link": "/getting-started/quick-start/"
}
}
}
Field reference
| Field | Type | Default | Notes |
|---|
title | string | "Docs" | Shown in the browser tab and nav header |
description | string | "Documentation" | Meta description tag |
logo | string | — | Path relative to docs/astro.config.mjs |
ecosystem | "npm" or "pub" | "npm" | Controls badge types and install commands |
github | string | — | Adds GitHub social link and Edit this page link |
site | string | — | Canonical site URL, required for SEO |
packageName | string | — | Used by PackageBadges component |
sidebar | array | 4-section default | Full Starlight sidebar config |
features.label | string | "Features" | Small eyebrow label above features heading |
features.title | string | "Everything you need." | Use \n for line breaks |
features.items | array | [] | Each item: { title, description, icon } — icon is emoji |
cta.label | string | "Ready to dive in?" | Small eyebrow label |
cta.title | string | "Start building today." | Main CTA heading |
cta.description | string | — | Supporting sentence |
cta.button.text | string | "Get Started" | Button label |
cta.button.link | string | "/getting-started/quick-start/" | Button href |
Ecosystem rules
"ecosystem": "pub" → badges show pub version, pub points, pub likes, license
"ecosystem": "npm" → badges show npm version, weekly downloads, bundle size, license
- The
installCommands generated by getEcosystemConfig() follow the same rule
Step 4 — Write docs/astro.config.mjs
This file should be exactly 6 lines. Never put Starlight config here.
import { defineConfig } from 'astro/config';
import { createDocsConfig } from 'docs-theme';
import docsJson from './docs.json';
export default defineConfig(createDocsConfig(docsJson));
Note: Vite (used by Astro) handles JSON imports natively — no assert { type: 'json' } needed.
Step 5 — Minimum docs/src/ content structure
docs/
└── src/
├── assets/
│ └── logo.svg ← optional, matches docs.json "logo" path
└── content/
└── docs/
├── index.mdx ← homepage (frontmatter: template: splash)
├── getting-started/
│ ├── installation.md
│ └── quick-start.md
├── guides/ ← autogenerated sidebar section
└── api/ ← autogenerated sidebar section
Minimal index.mdx frontmatter:
---
title: Home
template: splash
hero:
tagline: One sentence about the package.
actions:
- text: Get Started
link: /getting-started/quick-start/
icon: right-arrow
variant: primary
- text: GitHub
link: https://github.com/ORG/REPO
icon: external
variant: secondary
---
Step 6 — Copy the GitHub Actions workflow
mkdir -p .github/workflows
cp docs/node_modules/docs-theme/workflow/deploy.yml .github/workflows/docs.yml
Then open .github/workflows/docs.yml and replace:
projectName: YOUR_CLOUDFLARE_PAGES_PROJECT_NAME
with the actual Cloudflare Pages project name.
Add two repository secrets in GitHub → Settings → Secrets → Actions:
CLOUDFLARE_API_TOKEN
CLOUDFLARE_ACCOUNT_ID
Step 7 — Run locally to verify
cd docs
npm run dev
Visit http://localhost:4321. Confirm:
Common mistakes to avoid
- Hardcoding anything in
astro.config.mjs — all config belongs in docs.json.
- Wrong
ecosystem value — must be exactly "npm" or "pub", not "dart", "flutter", etc.
- Relative logo path —
logo is relative to docs/astro.config.mjs, not docs/src/.
- Correct:
"./src/assets/logo.svg"
- Wrong:
"../src/assets/logo.svg" or "src/assets/logo.svg"
- Sidebar items without trailing slash — Starlight prefers
"/getting-started/installation/" (trailing slash).
autogenerate directories that don't exist — if you set { "autogenerate": { "directory": "api" } }, the docs/src/content/docs/api/ directory must exist (even if empty).
- Missing
packageName — PackageBadges won't render if packageName is not set.
features.title multi-line — use a literal \n in the JSON string to get a line break in the heading.
Updating the theme
To pick up a new version of the theme:
cd docs
npm install github:YOUR_ORG/docs-theme
Pin to a specific git tag for stability:
npm install github:YOUR_ORG/docs-theme#v1.2.0
Using theme components in MDX pages
PackageBadges
import PackageBadges from 'docs-theme/components/PackageBadges.astro'
<PackageBadges packageName="my-pkg" ecosystem="npm" />
Callout
import Callout from 'docs-theme/components/Callout.astro'
<Callout type="tip" title="Pro Tip">
Content goes here.
</Callout>
Types: note | tip | warning | danger
getEcosystemConfig (JS)
import { getEcosystemConfig } from 'docs-theme/ecosystem'
const eco = getEcosystemConfig('my-pkg', 'npm')