Lightweight presentation helper with presenter view, speaker notes, and timer
npm install mini-presenter
mini-presenter is a tiny local server that injects a display helper into your
slides and provides a presenter view with timers, notes, and previews.
This should allow you to present almost any website as a slideshow for as long
as it has anchors per slide and build step. With a bit of extra support for
special marker hashes you can also have next slide previews.
- Injected display script keeps the presenter view in sync.
- Presenter dashboard with current slide preview, timer, and connection status.
- Optional next-slide preview when your deck exposes slide order.
- Speaker notes via deck API or Markdown files.
- Configurable keyboard shortcuts.
- Optional file watching with auto-reload.
- Optional Cloudflare tunnel via cloudflared for sharing previews.
``bashRun directly with npx (no install needed)
npx mini-presenter path/to/deck
Quick start
`bash
npx mini-presenter path/to/deck --port 8080 --watch --funnel
npx mini-presenter https://mitsuhiko.github.io/talks/i-was-questioning-life/
`- Slides:
http://localhost:8080/
- Presenter view: http://localhost:8080/_/presenterWhen you pass a URL, mini-presenter proxies the remote site through the local server. File watching is only available for local folders.
Use
--watch to enable file watching and auto-reload on HTML/CSS/JS changes.
Use --funnel to create an anonymous Cloudflare tunnel (requires cloudflared).Export slides (PDF/PNG)
The exporter will start a dedicated Chrome instance with remote debugging automatically.
`bash
npx mini-presenter export ./slides --output slides.pdf
npx mini-presenter export ./slides --output ./images --format png --delay 500
`Basic requirements for slide decks
Your presentation can be plain HTML/CSS/JS as long as it cooperates with navigation and state reporting:
- Served from a local folder or URL. mini-presenter serves the folder or proxies the URL you pass on the CLI and injects its script into any HTML file.
- Expose a current slide identifier. The injected script uses
window.miniPresenter.getCurrentSlide() if available. Otherwise it falls back to location.hash.
- React to navigation commands. The presenter sends next, prev, first, last, and goto actions. Implement the mini-presenter API (below) _or_ listen for keyboard events (ArrowRight, ArrowLeft, Home, End) and update the slide state yourself.
- Update the URL hash. This is the easiest way to keep the presenter preview and notes aligned. When the current slide changes, update location.hash (or implement getCurrentSlide()).If you already have a deck that uses hash-based navigation (Reveal, custom HTML, etc.), it usually “just works.”
Mini-presenter deck API (optional)
Add a global
window.miniPresenter object to make the presenter smarter:`js
window.miniPresenter = {
// Navigation hooks (used instead of keyboard events when present)
next() {},
prev() {},
first() {},
last() {},
goto(hash) {}, // State + metadata
getCurrentSlide() { return location.hash || "#"; },
getSlideList() { return ["#1", "#2", "#3"]; },
getNotes(slideId) { return "Speaker notes"; }
};
`-
getSlideList() enables the next-slide preview.
- getNotes(slideId) provides speaker notes directly from the deck.
- If you don’t expose these hooks, the presenter falls back to URL hash updates and keyboard events.Presenter preview context
The presenter view loads slide previews in iframes with ?_presenter_preview=1.
When that query param is present, the injected script:
- sets window.miniPresenter.isPresenterPreview = true
- sets document.documentElement.dataset.presenterPreview = "true"
- mutes all