Monorepo Management
Why a Monorepo?
Managing presentations as separate projects creates friction:
- Duplicated effort: Installing dependencies, configuring tools, and updating versions happens per-project
- Version inconsistency: Different presentations end up on different Slidev versions, leading to subtle bugs and incompatibilities
- Scattered tooling: No central place to run commands across all presentations
A monorepo consolidates everything into a single repository while keeping presentations independent. You get shared infrastructure without coupling your content.
Architecture Overview
The following diagram shows how a Supaslidev workspace is structured:
Benefits of This Approach
Shared Dependencies
All presentations share a single node_modules at the workspace root. pnpm's content-addressable storage ensures packages are only stored once on disk, even across hundreds of presentations.
Consistent Tooling
Linting, formatting, and build configurations live in one place. When you update a tool, all presentations benefit immediately.
Atomic Updates
Upgrading Slidev happens once in the catalog. Every presentation gets the new version on the next pnpm install, reducing the risk of forgotten or partially-updated projects.
Simplified CI/CD
One repository means one pipeline. Build and deploy any combination of presentations from a single workflow.
pnpm Workspace Configuration
The workspace is defined in pnpm-workspace.yaml at the repository root:
packages:
- 'presentations/*'
catalog:
'@slidev/cli': ^52.11.3
'@slidev/theme-default': latest
'@slidev/theme-seriph': latest
'vue': ^3.5.26
The packages Array
The packages array tells pnpm which directories contain workspace packages. The glob presentations/* includes every folder under presentations/ as a separate package.
When you create a new presentation with pnpm new my-talk, it becomes part of the workspace automatically.
Understanding Catalog Dependencies
The catalog section is the key to consistent versioning. It defines named versions that presentations reference using the special catalog: specifier.
In a presentation's package.json:
{
"dependencies": {
"@slidev/cli": "catalog:",
"@slidev/theme-default": "catalog:",
"vue": "catalog:"
}
}
When pnpm resolves "@slidev/cli": "catalog:", it looks up @slidev/cli in the workspace catalog and uses that version (^52.11.3). This creates a single source of truth for dependency versions.
Updating Catalog Versions
To upgrade Slidev across all presentations:
- Edit
pnpm-workspace.yaml:
catalog:
'@slidev/cli': ^53.0.0 # Updated version
- Run
pnpm installto apply the change:
pnpm install
Every presentation now uses the new version. The lockfile updates to reflect the change, and you can verify everything works before committing.
Turborepo Integration
While pnpm handles dependency management, Turborepo orchestrates task execution across the workspace. It provides intelligent caching and parallel execution that dramatically speeds up builds, tests, and other operations.
How Turborepo Helps
Parallel Execution: Turborepo analyzes task dependencies and runs independent tasks concurrently. Building ten presentations happens in parallel rather than sequentially.
Intelligent Caching: When you run a task, Turborepo hashes the inputs (source files, dependencies, environment). If nothing changed since the last run, it replays the cached output instantly.
Dependency Awareness: Tasks can declare dependencies on other tasks. Building a presentation automatically ensures its dependencies are built first.
Configuration
Turborepo configuration lives in turbo.json at the workspace root:
{
"$schema": "https://turbo.build/schema.json",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["src/**", "**/*.ts", "**/*.vue", "package.json"],
"outputs": ["dist/**"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
Key configuration options:
- dependsOn:
["^build"]means this task waits for dependencies' build tasks to complete first - inputs: Files that affect the task output (used for cache invalidation)
- outputs: Directories/files produced by the task (cached between runs)
- cache: Set to
falsefor tasks that shouldn't be cached (like dev servers) - persistent: Marks long-running tasks that don't exit
Running Tasks with Turborepo
The root package.json provides scripts that use Turborepo:
# Build all packages in parallel
pnpm build:all
# Run linting across all packages
pnpm lint
# Type-check all packages
pnpm typecheck
# Run all tests
pnpm test:ci
These commands leverage Turborepo's parallelization and caching. After the first run, subsequent runs skip unchanged packages entirely.
Cache Behavior
Turborepo stores task outputs locally in node_modules/.cache/turbo. When a task runs:
- Turborepo computes a hash from the task's inputs
- If a cached result exists for that hash, it restores the outputs and replays the logs
- If no cache exists, the task runs normally and the result is cached
You can see cache hits in the output:
@supaslidev/quarterly-review:build: cache hit, replaying logs
@supaslidev/product-launch:build: cache miss, executing task
To clear the cache and force a full rebuild:
pnpm build:all --force
Adding Presentations
Create a new presentation using the dashboard CLI:
pnpm new my-new-talk
This command:
- Creates
presentations/my-new-talk/with the standard structure - Generates a
package.jsonusing catalog dependencies - Creates a starter
slides.mdfile - Runs
pnpm installto link the new package
You can also create presentations manually. Create the folder structure and ensure the package.json uses catalog: specifiers:
mkdir -p presentations/manual-talk
{
"name": "@supaslidev/manual-talk",
"private": true,
"type": "module",
"scripts": {
"build": "slidev build",
"dev": "slidev --open",
"export": "slidev export"
},
"dependencies": {
"@slidev/cli": "catalog:",
"@slidev/theme-default": "catalog:",
"vue": "catalog:"
}
}
Then run pnpm install to add it to the workspace.
Removing Presentations
To remove a presentation from the workspace:
- Delete the presentation folder:
rm -rf presentations/old-talk
- Clean up the lockfile:
pnpm install
pnpm automatically removes the package from the workspace and updates pnpm-lock.yaml.
If you want to archive a presentation without deleting it, move it outside the presentations/ directory. Since it no longer matches the workspace glob, pnpm treats it as a regular folder.
Running Commands Across Presentations
pnpm provides filtering to run commands on specific packages or all packages matching a pattern.
All Presentations
Build every presentation:
pnpm --filter '@supaslidev/*' run build
Specific Presentation
Start the dev server for one presentation:
pnpm --filter @supaslidev/my-talk run dev
Or use the dashboard CLI:
pnpm present my-talk
Multiple Presentations
Run commands on a subset:
pnpm --filter '@supaslidev/quarterly-*' run build
Workspace Structure Recap
A typical Supaslidev workspace looks like this:
my-workspace/
├── presentations/
│ ├── quarterly-review/
│ │ ├── slides.md
│ │ └── package.json # Uses catalog: dependencies
│ ├── product-launch/
│ │ ├── slides.md
│ │ └── package.json
│ └── team-onboarding/
│ ├── slides.md
│ └── package.json
├── .supaslidev/
│ └── state.json # Workspace metadata
├── pnpm-workspace.yaml # Workspace config and catalog
├── package.json # Root package
└── pnpm-lock.yaml # Single lockfile for all packages
Key points:
- Each presentation is a separate pnpm package with its own
package.json - All presentations share dependencies through the catalog
- A single
pnpm-lock.yamllocks versions for the entire workspace - The
.supaslidev/folder tracks workspace state for migrations
Next Steps
Learn more about the CLI commands for managing presentations, or explore the dashboard features for an interactive workflow.
