Monorepo Architecture Overview
This template is a Bun workspace monorepo with three applications and two shared packages. Understanding the architecture will help you navigate and customize the project.
Repository Structure
astro_keystatic_template/ ├── apps/ │ ├── www/ # Public website (Astro 7 + Vue 3) │ ├── cms/ # Keystatic admin (Astro 6 + React) │ └── dashboard/ # Admin dashboard (Astro 7 + Vue 3) ├── packages/ │ ├── keystatic-config/ # Shared CMS schema │ └── site-config/ # Shared typed configuration ├── content/ # Git-tracked content directory └── .ai/ # AI development tooling
Three Applications, One Repository
Each app lives in apps/ and has its own package.json, astro.config.mjs, and wrangler.jsonc. They share the same root content/ directory.
Public Website (apps/www)
Astro 7 with Vue 3 components. Uses output: 'static' for production SSG and export const prerender = false for SSR on preview. Reads content from the shared content/ directory using Keystatic's reader API.
CMS Admin (apps/cms)
Astro 6 with React. Runs the Keystatic admin UI at cms.yourdomain.com. Protected by Cloudflare Zero Trust. Content editors create and edit content here — changes are saved to GitHub.
Admin Dashboard (apps/dashboard)
Astro 7 with Vue 3. Displays analytics (Looker Studio embed), manages form submissions from D1, and provides publish controls. Protected by Cloudflare Zero Trust.
Shared Packages
Two workspace packages provide shared functionality:
@template/keystatic-config— collection schemas, field definitions, and SEO fields shared between www and cms@template/site-config— typed configuration object with site name, SEO defaults, analytics IDs, and more
Content Flow
Content flows from the CMS to GitHub, then to both the production and preview websites:
- Editor writes content in CMS → saved to GitHub
previewbranch - Preview site auto-deploys from
previewbranch (SSR) - Editor reviews in preview, clicks "Publish"
- CMS merges
preview→mainvia GitHub API - Production site auto-deploys from
mainbranch (SSG)
Version Split
The CMS uses Astro 6 for Keystatic compatibility, while www and dashboard use Astro 7. Bun's isolated linker (bunfig.toml: linker = "isolated") keeps these versions separate while maintaining workspace benefits.
Next up: how to use this template for your own project.