npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mini-presenter

v0.3.0

Published

Lightweight presentation helper with presenter view, speaker notes, and timer

Readme

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.

Features

  • 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.

Installation

# Run directly with npx (no install needed)
npx mini-presenter path/to/deck

# Or install globally
npm install -g mini-presenter

Quick start

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/_/presenter

When 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.

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:

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 <audio>/<video> elements so previews stay silent

Use this flag to disable autoplay audio or heavyweight effects in the presenter view.

Configuration (presenter.json)

Place an optional presenter.json next to your index.html to customize the presenter experience.

{
  "title": "My Presentation",
  "keyboard": {
    "next": ["ArrowRight", "Space", "PageDown", "l", "j"],
    "prev": ["ArrowLeft", "PageUp", "h", "k"],
    "first": ["Home"],
    "last": ["End"]
  },
  "notes": {
    "source": "files"
  },
  "preview": {
    "relativeHash": true
  }
}
  • title: Optional presenter title (defaults to the slideshow <title>).
  • keyboard: Custom key bindings for presenter navigation.
  • notes.source: api, files, or none (default: api + file fallback).
  • preview.relativeHash: Enable #<hash>~next preview resolution.

The config is available at /_/api/config.

Speaker notes

Notes are shown in the presenter view and loaded in this order:

  1. Presentation API: define window.miniPresenter.getNotes(slideId) in your deck.
  2. Notes files: add Markdown files under notes/ next to your index.html.

File mapping rules:

  • #1notes/1.md
  • #1.2notes/1.2.md (falls back to notes/1.md if missing)
  • #2-1notes/2-1.md (falls back to notes/2.md if missing)
  • #/2/1notes/2--1.md (slashes become --)
  • #intronotes/intro.md

Numeric hashes with -, ., or -- suffixes fall back to the base number if the specific file is missing (for example #2/1notes/2.md).

Notes are fetched from /_/api/notes?hash=%23intro and rendered as pre-wrapped text.

Next slide preview

The presenter shows a next-slide preview when it can determine the slide order from window.miniPresenter.getSlideList() in your deck (returns an array of hashes).

If preview.relativeHash is enabled, the preview iframe loads #<hash>~next and expects slide logic in your deck to resolve it to the next state (including build steps).

AI Use Disclaimer

Note: this library was 100% AI generated with Claude Code. I will try to fix it up as good as possible as I ran into issues, but I cannot vouch for the quality of it.

License and Links