A lean, production-ready Astro v6 monorepo template with Tailwind v4, Svelte 5 and Biome.
Status: Astro v6 is stable. This template tracks the latest Astro v6 releases.
This template uses pnpm workspaces with a shared library, making it an ideal foundation for running multiple projects from a single repository. Typical use cases:
starter and blog)All projects share the same design tokens, UI components and utilities — ensuring a consistent look and feel while keeping each app independently deployable. Adding a new project is as simple as creating a new folder under apps/ and importing from shared/.
This template succeeds astro-v5-template. It was rebuilt from scratch with a focus on simplicity and the Astro v6 feature set.
| Area | v5 | v6 |
|---|---|---|
| Apps | 3 (blank, base, demo) | 2 (starter, blog) |
| Linting | Biome + ESLint + Prettier | Biome only |
| Fonts | 16 packages | 3 (Inter, Lora, Fira Code) |
| Styling | @casoon/atlas + Tailwind | Custom tokens + Tailwind v4 |
| Node | >= 20 | >= 22.12.0 |
| Zod | v3 | v4 |
| Content | Legacy Collections | Loader API |
| Dev server | Standard Vite | Vite Environment API |
@casoon/astro-speed-measure for build performance tracking@casoon/astro-post-audit for SEO, link and WCAG checks after every build@casoon/nosecrets in pre-commit plus manual workspace scans@casoon/astro-sitemap generates /sitemap.xml at build time with i18n hreflang, RSS feed, and pattern-based priority/changefreq rules@casoon/astro-crawler-policy generates robots.txt and llms.txt from a curated bot registry with presets for SEO, AI training control and citation-friendlinessTip: For additional ready-made Tailwind v4 components (buttons, cards, modals, navigation and more), check out webspire.de — a component library built on Tailwind v4 that pairs well with this template.
astro-v6-template/
├── apps/
│ ├── starter/ # Landing page + contact form + i18n
│ └── blog/ # Blog with MDX + RSS + i18n
├── shared/ # Design tokens, components, layouts, SEO, utilities
├── e2e/
│ ├── starter/ # Playwright E2E tests for starter
│ └── blog/ # Playwright E2E tests for blog
├── .github/workflows/ # CI pipeline
├── biome.json # Linting & formatting
├── playwright.config.ts # E2E test configuration
└── pnpm-workspace.yaml # Workspace + catalog
# Clone the repository
git clone https://github.com/casoon/astro-v6-template.git
cd astro-v6-template
# Install dependencies
pnpm install
# Start the starter app
pnpm dev
# Start the blog app
pnpm dev:blog
| Script | Description |
|---|---|
pnpm dev |
Start the starter app (port 4321) |
pnpm dev:blog |
Start the blog app (port 4322) |
pnpm build |
Build all apps |
pnpm build:starter |
Build starter only |
pnpm build:blog |
Build blog only |
pnpm check |
Run Biome lint + format check |
pnpm check:fix |
Biome auto-fix |
pnpm format |
Format all files |
pnpm test:e2e |
Run all Playwright E2E tests |
pnpm test:e2e:starter |
E2E tests for starter only |
pnpm test:e2e:blog |
E2E tests for blog only |
pnpm type-check |
TypeScript check |
pnpm clean |
Remove build artifacts + node_modules |
Landing page featuring:
/api/contact)Blog template featuring:
/rss.xml) via astroSitemap integration/sitemap.xml) with i18n hreflang@astro-v6/shared)All shared code lives in shared/:
Navbar.astro, ThemeToggle.svelteBaseLayout.astro (HTML base with skip link)PageSEO.astro (meta tags, Open Graph, JSON-LD)env.ts, api.ts, cn.ts, i18n.ts, og.tsBoth apps support English (default) and German:
/, /contact, /blog/welcome/de/, /de/contactsrc/i18n/@astro-v6/shared/utils/i18nOpen Graph images are generated at build time:
# Generate manually
pnpm --filter starter generate:og
pnpm --filter blog generate:og
# Runs automatically before `astro build`
pnpm build
public/og/*.png (1200x630, gitignored)<PageSEO ogImage={...}># Run all tests (builds must exist)
pnpm test:e2e
# Run per app
pnpm test:e2e:starter
pnpm test:e2e:blog
Tests covering navigation, i18n, SEO/OG meta tags, contact form, theme toggle, RSS, accessibility (axe-core WCAG 2.1 AA), robots.txt and sitemap.
# Scan the whole workspace
pnpm secrets:scan
# Scan only staged files (used by pre-commit)
pnpm secrets:scan:staged
Both apps include @casoon/astro-speed-measure to track build performance. It measures integration hooks, Vite plugin timing, per-page rendering and asset processing — giving you visibility into what slows down your build.
// astro.config.mjs
import speedMeasure from '@casoon/astro-speed-measure';
export default defineConfig({
integrations: [
// ... other integrations
speedMeasure(), // always add as last integration
],
});
Each build prints a performance report to the console and writes a JSON baseline for trend comparisons. Supports budgets, HTML reports and GitHub Actions CI summaries.
Both apps include @casoon/astro-post-audit for automatic SEO, link and WCAG checks after every build. It runs a fast Rust binary against the build output via the astro:build:done hook.
The template ships with comprehensive rules enabled out of the box:
// astro.config.mjs
postAudit({
throwOnError: false,
rules: {
filters: { exclude: ['404.html'] },
canonical: { self_reference: true },
headings: { no_skip: true },
html_basics: { meta_description_required: true },
opengraph: {
require_og_title: true,
require_og_description: true,
require_og_image: true,
},
a11y: {
require_skip_link: true,
require_img_alt: true,
require_button_text: true,
require_label: true,
},
links: { check_fragments: true },
sitemap: {
require: true,
canonical_must_be_in_sitemap: true,
entries_must_exist_in_dist: true,
},
security: { check_target_blank: true },
hreflang: {
check_hreflang: true,
require_x_default: true,
require_self_reference: true,
require_reciprocal: true,
},
},
}),
Checks include canonical URLs, meta descriptions, Open Graph tags, heading hierarchy, broken links with fragment validation, sitemap cross-referencing, target="_blank" security, hreflang reciprocal validation and WCAG heuristics (skip link, alt text, button text, form labels). Set throwOnError: true for strict CI enforcement.
Both apps use @casoon/astro-sitemap to generate /sitemap.xml as part of astro:build:done — no extra page route needed.
// astro.config.mjs
import astroSitemap from '@casoon/astro-sitemap';
import { getBlogRssItems } from './src/utils/blog-rss.js';
astroSitemap({
i18n: {
defaultLocale: 'en',
locales: { en: 'en', de: 'de' }, // adds xhtml:link hreflang entries
},
priority: [
{ pattern: '/blog/', priority: 0.7 },
],
changefreq: [
{ pattern: '/blog/', changefreq: 'monthly' },
],
rss: {
title: 'Astro v6 Blog',
description: 'A blog template built with Astro v6, MDX and Content Collections.',
language: 'en',
getItems: getBlogRssItems, // reads MDX frontmatter via gray-matter
},
}),
The getItems helper (src/utils/blog-rss.js) reads MDX frontmatter directly with gray-matter rather than getCollection(), because Astro's content API is unavailable inside the build hook.
Features: static page discovery from Astro's build output, i18n hreflang links, RSS feed generation, pattern-based priority/changefreq, sitemap-index chunking for large sites (>50k URLs).
Both apps use @casoon/astro-crawler-policy to generate robots.txt (and optionally llms.txt) from a curated bot registry.
// astro.config.mjs
import crawlerPolicy from '@casoon/astro-crawler-policy';
crawlerPolicy({
sitemaps: ['https://astrov6blog.casoon.dev/sitemap.xml'],
// preset: 'seoOnly' | 'citationFriendly' | 'openToAi' | 'blockTraining' | 'lockdown'
}),
The default preset (seoOnly) allows all verified search engine bots and blocks AI training crawlers. Override per environment via the env option.
This template enforces WCAG 2.1 Level AA compliance through two complementary layers:
@casoon/astro-post-audit runs automatically after every build and checks the raw HTML output for:
alt attributes on images<a> without text or aria-label)<h1> elements per pageaxe-core via @axe-core/playwright validates the fully rendered pages in a real browser:
# Run accessibility tests
pnpm test:e2e # all tests including a11y
Tests are located in e2e/starter/a11y.spec.ts and e2e/blog/a11y.spec.ts.
BaseLayout<nav>, <main>, <article>, <section> throughoutaria-label, aria-current, role where neededprefers-color-scheme, OKLCH colors maintain contrast in both modesThis template leverages the key features of Astro v6:
glob() loader instead of legacy type: 'content'z.email(), z.url() as top-level functionsThis template includes a Claude Code setup for AI-assisted development:
.claude/mcp.json) — Pre-configured MCP servers for context7 documentation lookup, Cloudflare tooling, and Webspire UI patternsCLAUDE.md) — Architecture rules, code conventions, and dependency constraintsFor the full set of reusable Claude Code skills (Astro, Tailwind, Svelte, SEO, Playwright, and more), see casoon/ai-agent-config.
MIT