Modern monorepo template for documentation and course platforms
A production-ready template based on Astro v6, MDX, Tailwind CSS v4, and pnpm Workspaces - optimized for creating technical documentation and interactive learning platforms.
- Docs App: kc-docs.casoon.dev
- Courses App: kc-courses.casoon.dev
- Astro v6 — Vite Environment API, Content Collections Loader API, ClientRouter
- MDX — Markdown with interactive components
- Tailwind CSS v4 — CSS-first config, Vite plugin, design tokens
- Biome — Single tool for linting + formatting (replaces ESLint + Prettier)
- pnpm Workspaces — Monorepo with catalog for centralized dependency management
- Zod v4 — Runtime validation for content schemas
- Shared Components — Reusable UI components across apps
- Interactive Courses — Quiz, exercises, progress tracking
- Dark Mode — With theme persistence via ClientRouter
- Cloud Sync — Sync learning progress across devices
- Type-Safe — TypeScript strict mode throughout
- Technical Documentation — API references, guides, tutorials
- Course Platforms — Interactive learning paths with quizzes and exercises
- Knowledge Bases — Internal documentation for teams
- Developer Portals — Developer resources and guides
- Node.js >= 22.12.0
- pnpm >= 9.0.0
- Volta (recommended)
Option 1: Use GitHub Template (recommended)
- Click "Use this template" at the top of the GitHub page
- Give your project a name
- Clone your new repository:
git clone https://github.com/yourusername/your-project.git cd your-project
Option 2: Direct Clone
git clone https://github.com/casoon/knowledge-core.git
cd knowledge-core# 1. Install dependencies
pnpm install
# 2. (Optional) Customize package names
# Change @knowledge-core/* to your own scope in:
# - package.json files (all packages)
# - Import statements in apps
# 3. Start the project
pnpm dev# Start both apps
pnpm dev
# Documentation only
pnpm dev:docs
# -> http://localhost:4321
# Courses only
pnpm dev:courses
# -> http://localhost:4322# Build all apps
pnpm build
# Build individual app
pnpm build:docs
pnpm build:coursesknowledge-core/
├── apps/
│ ├── docs/ # Documentation app
│ │ ├── src/
│ │ │ ├── content/ # MDX files
│ │ │ ├── layouts/ # Astro layouts
│ │ │ └── pages/ # Pages & routing
│ │ └── package.json
│ │
│ └── courses/ # Course platform app
│ ├── src/
│ │ ├── content/
│ │ │ ├── courses/ # Course definitions
│ │ │ └── lessons/ # Lessons (MDX)
│ │ ├── layouts/
│ │ └── pages/
│ └── package.json
│
├── packages/
│ ├── ui/ # Shared UI components
│ ├── styles/ # Tailwind v4 + design tokens
│ ├── content-model/ # Zod v4 content schemas
│ └── config/ # Shared configs
│
├── shared/ # Shared layouts, SEO, utilities
├── package.json # Root package
└── pnpm-workspace.yaml
Create an MDX file in apps/docs/src/content/docs/:
---
title: My Page
description: Description
category: guides
order: 1
tags: [tutorial]
status: stable
---
import { Callout } from '@knowledge-core/ui';
# My Page
<Callout type="info">Important information!</Callout>- Course definition in
apps/courses/src/content/courses/my-course.json:
{
"title": "My Course",
"slug": "my-course",
"description": "Course description",
"level": "beginner",
"estimatedTotalMinutes": 120,
"tags": ["programming"],
"published": true
}- Lesson in
apps/courses/src/content/lessons/:
---
courseSlug: my-course
title: Lesson 1
module: Basics
orderInModule: 1
estimatedMinutes: 15
goals:
- Goal 1
- Goal 2
---
import { Quiz, Exercise } from '@knowledge-core/ui';
# Lesson 1
<Exercise title="Exercise" difficulty="easy">
Task here...
</Exercise>
<Quiz
questions={[
{
question: "What is 2 + 2?",
options: ["3", "4", "5"],
correctAnswer: 1
}
]}
/>- Callout - Info, Warning, Error, Success
- CodeBlock - Syntax highlighting with copy button
- Card - Content cards
- Tabs / TabPanel - Tab navigation
- Quiz - Interactive quizzes with feedback
- Exercise - Exercise blocks with difficulty levels
- Hint - Collapsible hints
- ProgressBar - Progress indicator
- CourseCard - Course overview cards
- LessonNav - Lesson navigation sidebar
- LessonComplete - Mark lessons as complete
- TotalProgress - Overall progress display
- SyncProgress - Cloud sync for progress
- NavBar - Main navigation with mobile support & ClientRouter
- SearchBar - Full-text search (Pagefind)
- FontSizeControl - Accessibility font size control
- QuizToggle - Show/hide quizzes
Edit packages/styles/src/tokens.css:
:root {
--color-primary: #6366f1;
--color-secondary: #f8fafc;
/* ... */
}
.dark {
--color-primary: #818cf8;
/* ... */
}Tailwind v4 uses CSS-first configuration in packages/styles/src/global.css:
@import "tailwindcss";
@import "./tokens.css";
@theme {
--color-primary: var(--color-primary);
--color-surface: var(--color-surface);
/* ... */
}
@custom-variant dark (&:where(.dark, .dark *));# Development
pnpm dev # All apps
pnpm dev:docs # Docs only
pnpm dev:courses # Courses only
# Build
pnpm build # All apps
pnpm build:docs # Docs only
pnpm build:courses # Courses only
# Preview
pnpm preview # All apps
pnpm preview:docs # Docs only
pnpm preview:courses # Courses only
# Code Quality
pnpm check # Biome lint + format check
pnpm check:fix # Biome auto-fix
pnpm format # Format all files
pnpm type-check # TypeScript check
# Clean
pnpm clean # Remove all build artifacts- Build Command:
pnpm build:docs - Build output directory:
apps/docs/dist
- Push to GitHub
- Import on Vercel
- Select root directory
- Build Command:
pnpm build:docsorpnpm build:courses - Output Directory:
apps/docs/distorapps/courses/dist
# netlify.toml
[build]
command = "pnpm build:docs"
publish = "apps/docs/dist"- SETUP.md - Detailed setup guide and customization
- CONTRIBUTING.md - Contribution guidelines
Contributions are welcome! See CONTRIBUTING.md for details.
MIT License - see LICENSE
Built with:
Made with care for developers and educators