My repository already has everything a presentation needs. Treating it as the source of truth changed how I work with slides entirely.
Contents
I Hated Presentations
The problem wasn't design — it was context switching. I'd leave the terminal to open PowerPoint and spend twenty minutes rebuilding mental context I already had. The information was in the repository — meeting notes, decisions, requirements, audit results — but getting it into slides meant pulling it out manually, from memory.
With Slidev and Claude Code, the presentation is generated from the repository. No context switch.
The Repository
Everything relevant lives in the repo — not just code:
project/
├── docs/
│ ├── architecture.md
│ ├── requirements.md
│ ├── decisions/
│ └── meetings/
├── audit/
│ ├── findings.md
│ └── recommendations.md
└── presentations/
└── q1-review/
When it's time to present, the content is already there.
Generating Slides on Demand
/pres Generate a Q1 review presentation for the engineering team.
Use the findings in docs/meetings/ and docs/decisions/.
Focus on what shipped, what changed from the plan, and what's next.
Keep it under 15 slides.
Claude reads the repo and produces a slides.md in Slidev format. Iteration is plain language — "reframe that as lessons learned" — no menus, no templates.
Where It Shines
- Project reviews — repo accumulates everything; the deck is just the filtered summary
- Audit summaries — at databy.io the audit pipeline outputs both a technical report and an exec deck from the same findings, no extra step
- Docs that don't rot — update the doc, regenerate the slide; no drift
- Remote presenting — run Slidev with a Cloudflare tunnel, paste the link; audience joins live in their browser, no account required (setup in the appendix)
The Actual Shift
Presentations used to be a separate deliverable. Now they're a byproduct of the work — selecting and shaping what's already in the repository. I just don't dread them anymore.
Appendix: Technical Reference
If you're setting this up, the details are below.
Slidev Setup
Slidev is a presentation framework built for developers. Slides are plain Markdown files. A minimal package.json:
{
"scripts": {
"dev": "slidev slides.md --open",
"export-pdf": "slidev export slides.md --format pdf --per-slide"
},
"dependencies": {
"@slidev/cli": "^0.49.0",
"@slidev/theme-default": "latest"
}
}
A minimal slide deck:
---
theme: default
title: Project Review
colorSchema: dark
---
# Project Review
Q1 2026
---
# What We Built
- Feature A — shipped January
- Feature B — shipped February
- Feature C — in progress
---
# Next Steps
<v-clicks>
- Complete Feature C
- Begin Q2 planning
- Schedule stakeholder review
</v-clicks>
Each --- separator is a new slide. <v-clicks> makes items appear one by one. Speaker notes go in HTML comments.
npm run dev # Live preview at localhost:3030
npm run export-pdf # Export to PDF via Playwright/Chromium
First export requires Playwright's Chromium:
npx playwright install chromium
Export: The --per-slide Flag
Use --per-slide when the deck has background images. Without it, backgrounds don't render correctly in the PDF output.
# Correct — background images render
npx slidev export --format pdf --per-slide
# Missing background images
npx slidev export --format pdf
CI/CD Integration
Slidev exports via headless Chromium, so it runs in a GitHub Actions workflow or any automation pipeline without a GUI.
A minimal step:
- name: Generate presentation PDF
run: |
cd presentations/sprint-review
npm install
npx playwright install --with-deps chromium
npm run export-pdf
Presentations become a pipeline artifact, produced alongside everything else.
Cloudflare Tunnel
To share a live interactive presentation:
# Terminal 1: Start Slidev with remote access enabled
npx slidev --remote=yourpassword
# Terminal 2: Create a public tunnel
cloudflared tunnel --url http://localhost:3030
This creates a public URL at random-words.trycloudflare.com — no account, no cost. Share it for viewing; add ?password=yourpassword to the URL for the presenter remote control interface.
Required: vite.config.ts
Slidev's Vite server blocks requests from unknown hosts by default, which breaks the tunnel. Add this to the presentation directory:
import { defineConfig } from 'vite'
export default defineConfig({
server: {
allowedHosts: ['.trycloudflare.com', 'localhost', '127.0.0.1']
}
})
Without it, the tunnel connects but the browser gets "Blocked request" errors and serves nothing.
Troubleshooting:
| Symptom | Cause | Fix |
|---|---|---|
| "Blocked request" in browser | Missing vite.config.ts | Add allowedHosts config |
| HTTP 530 error | VPN/firewall blocking QUIC | Use mobile hotspot |
| Tunnel command hangs | Bundled cloudflared outdated | Run cloudflared manually |
| HTTP 502 | Slidev not running | Start Slidev before tunneling |