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

@exor404/mdslides

v0.1.3

Published

Markdown in, presentation out.

Readme

mdslides

Markdown in, presentation out.

The slides sibling of mdstack. Point it at a folder — mdslides scaffolds a starter slides.md, then presents it in a dev server or builds a self-contained dist/ you can host anywhere static.

Status: pre-1.0, provisional. CLI flags and markdown conventions may change before 0.x → 1.0.

Quick start

npx @exor404/mdslides@latest

No install step. It asks for a name, scaffolds <name>/<name>.md (three sample slides — a title page, a list, and a help slide) plus a mdslides.config.js, and opens the dev server. The name defaults to the current folder, so pressing Enter at Name your presentation (chemistry): gives you chemistry/chemistry.md. That file is your deck — edit it and the slides live-reload.

Point it at a folder for the other commands:

npx @exor404/mdslides ./chemistry          # present (dev server, live-reload)
npx @exor404/mdslides build ./chemistry    # static build → ./chemistry/dist/
npx @exor404/mdslides preview ./chemistry  # serve the built dist/
npx @exor404/mdslides export ./chemistry   # → chemistry.pdf (one page per slide)

Already have a deck? Point straight at the file: npx @exor404/mdslides ./chemistry.md.

Heads-up: npm install @exor404/mdslides only installs the package — running the CLI (via npx, as above) is what scaffolds and presents. Using npx also keeps the engine's dependencies in npx's cache instead of bloating a project's node_modules.

Prefer a global command? npm i -g @exor404/mdslides makes mdslides available directly (mdslides ./chemistry).

Try the bundled example from a clone:

npm install
npm run dev        # opens ./example

Install

The package is published on the public npm registry as @exor404/mdslides. Pick the option that suits you:

No install (recommended). npx fetches and caches the latest version, then runs it — nothing is added to your project:

npx @exor404/mdslides@latest          # prompts for a name, scaffolds + presents

Global install. Puts an mdslides command on your PATH:

npm install -g @exor404/mdslides
mdslides ./chemistry                  # then use it anywhere
mdslides --help                       # (or run with no folder to start fresh)

Update later with npm update -g @exor404/mdslides; remove with npm uninstall -g @exor404/mdslides.

As a project dependency. Add it to a repo so collaborators get the same version via npm install:

npm install -D @exor404/mdslides
npx mdslides ./chemistry              # resolves from local node_modules

Requires Node 18+. Installing the package pulls in its rendering engine (Astro, Shiki, KaTeX) — that's why npx is the lightest way to try it: those dependencies stay in npx's cache instead of your project's node_modules.

The deck model

One markdown file is the whole deck. Every # (H1) heading starts a new slide — write plain markdown in between. A standalone --- line is an explicit break (for a slide with no heading, or to split one section).

# Presentation title
## A subtitle
**Your Name** · {{date}}

# Second slide
- a point
- another (bullets reveal one at a time)

Title slide

The first slide is the title slide automatically: the # renders large, ## is the subtitle, and the last line becomes a byline pinned to the bottom — write your presenter name(s) in markdown there. The {{date}} token resolves to today's date. Opt a slide out with <!-- slide: plain -->, or mark another slide as a title with <!-- slide: title -->.

Supported markdown (the lean subset)

Only what slides actually need:

  • Headings, paragraphs, bold, italic, ~~strike~~, ==highlight==
  • Lists (reveal one item at a time — see Reveal & motion), tables, blockquotes
  • inline code and fenced code blocks (syntax-highlighted via Shiki)
  • Math — $inline$ and $$block$$ via KaTeX
  • Images (relative paths resolve from the deck folder)

Fence a block with a language for syntax highlighting:

```js
export default { theme: 'angular' };
```

Presenting

| Key | Action | | --- | --- | | space PageDn | next slide / reveal next fragment | | PageUp | previous | | Home / End | first / last slide | | O | overview grid (click a slide to jump) | | F | fullscreen | | . | black screen | | ? | help |

The URL hash tracks the current slide (#/3) so deep links work.

Reveal & motion

Slides build themselves as you talk:

  • Content fades in when a slide opens — headings, paragraphs, images, code, tables and quotes rise into place with a light stagger.
  • Lists reveal step by step. Every list item is hidden when the slide opens and appears one at a time on / space; steps back. Once all items are shown, the next press advances to the following slide. This is automatic — you don't need to mark anything.
  • Manual fragments. Append {.fragment} to any other line (a paragraph, a heading) to hold it back and reveal it on a later press, in document order alongside the list items.

In the overview grid and PDF export, everything is shown at once. Motion respects the OS "reduce motion" setting.

Per-slide directives

A leading comment configures one slide:

# A slide
<!-- slide: center bg=#1a0b2e -->
  • center — vertically + horizontally centered
  • bg=<color|url(...)> — slide background

Configuration

First run drops a mdslides.config.js next to your deck:

export default {
  brand: { text: 'mdslides' },   // bottom-left wordmark; '' to hide
  theme: 'angular',              // built-in: 'angular'
  transition: 'fade',            // 'fade' | 'slide' | 'none'
};

PDF export

mdslides export renders the /print route (one slide per page, all fragments shown). It uses Playwright if installed (npm i -D playwright && npx playwright install chromium); otherwise open /print in a browser and use Save as PDF.

Releasing

Releases go to the public npm registry (npmjs.com), so anyone can npx @exor404/mdslides. A tag-triggered GitHub Actions pipeline (.github/workflows/package-publish.yml) does the publishing for you: it runs only when you push a v* tag, verifies the tag matches package.json, and runs npm publish against npmjs.com using an automation token stored as the NPM_TOKEN repository secret.

How the pipeline works

push tag v0.1.3 ──► GitHub Actions ──► checkout ──► setup Node 22
                                          │
                                          ├─ guard: tag (v0.1.3) must equal
                                          │   package.json "version" (0.1.3),
                                          │   else the run fails
                                          │
                                          └─ npm publish  (auth: NPM_TOKEN)
                                                  └──► npmjs.com

The version guard means the git tag and the published version can never drift — if they disagree, the run stops before publishing.

One-time setup

You only do this once. It wires an npm token into the repo so Actions can publish on your behalf.

  1. Create an npm automation token. On npmjs.com: avatar → Access TokensGenerate New TokenAutomation (or a Granular token scoped to the @exor404/mdslides package with Read and write). Copy the value — npm shows it only once.
  2. Add it to GitHub as a secret. Repo → SettingsSecrets and variablesActionsNew repository secret. Name it exactly NPM_TOKEN, paste the token, Add secret. (It's a secret, not a variable — secrets are encrypted and hidden from logs.)

The very first version must exist on npm before automation can update it. If the package isn't published yet, do one manual publish first: npm login && npm publish --access public.

Cutting a release

Once the secret is in place, every release is three commands:

npm version patch          # bumps package.json (0.1.2 → 0.1.3) and commits + tags v0.1.3
git push origin main       # push the version-bump commit
git push origin v0.1.3     # push the tag → the pipeline publishes

npm version patch (or minor / major) bumps package.json, makes the commit, and creates the matching vX.Y.Z tag in one step. Pushing that tag is what triggers the workflow. Watch it run under the repo's Actions tab; when it goes green the new version is live on npm.

Prefer to bump by hand? Edit "version" in package.json, then:

git commit -am "🔖 Release 0.1.3"
git tag v0.1.3             # must match package.json exactly, or the guard fails
git push && git push --tags

Requirements

Node 18+.

License

MIT