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

@atom63/slides

v0.4.5

Published

Write presentations as MDX — a template grammar + token theming designed for coding agents to author decks.

Readme

@atom63/slides

Write presentations as MDX — and let a coding agent draft them.

A deck is a .mdx file: ----separated slides built from ~20 templates. Describe your talk to your coding agent; it writes the MDX — content, layout, and template choice. You restyle the whole deck with a one-line theme:, then present. The MDX stays the source of truth the whole way.

The same host-agnostic engine powers the Slides app in OS63 and runs standalone anywhere React + Vite + Tailwind v4 do.

The workflow

  1. Scaffoldnpm create @atom63/deck my-talk lays down a standalone deck project.
  2. Author with your agent — point your coding agent at src/deck.mdx and the deck-authoring skill, describe the talk; it writes the MDX — content, layout, and template choice.
  3. Theme in one line — set theme: in frontmatter to restyle the whole deck.
  4. Presentnpm run dev, then keyboard nav, grid overview, presenter PiP.

Because a deck is just code, the parts machines are good at — layout, alignment, template choice — are an agent's job; the parts you care about — the argument, the words — stay yours. An optional browser editor lets you nudge a slide by hand, but it's not the main path.

  • Templates, not div soup — ~20 composable slide templates (CoverSlide, StatBento, HeroBento, SplitHalf, QuoteSlide, FullBleedSlide, …) plus low-level primitives.
  • Token theming — every surface reads --theme-slide-* (and base) custom properties; swap a token set to restyle a whole deck.
  • Batteries-included player — keyboard nav, grid overview, presenter PiP, mobile layout, optional source view and password gate.
  • Introspectable — a machine-readable templateRegistry describes every template's content slots, so coding agents, editors, and tooling know exactly what each slide accepts.

Status: 0.4.x, extracted from a monorepo. The API may shift before 1.0.

Author with a coding agent

Step 2 of the workflow is the point of the whole toolchain: you don't hand-write JSX, you describe the talk. A deck is plain MDX — ----separated slides importing templates from @atom63/slides — which is exactly the shape a coding agent (Claude Code, Cursor, …) writes well.

The deck-authoring skill (skill/SKILL.md) packages everything the agent needs: the deck-file anatomy, the full template catalog with every prop and slot, the Swiss-design voice, and the anti-patterns to avoid. Point your agent at it (copy SKILL.md + TEMPLATES.md into your skills folder, or reference it directly), describe your talk, and it drafts src/deck.mdx. Then open the dev server, set theme: to taste, and present — the MDX stays the source of truth. (An optional browser editor is there for hand-nudging a slide, but it's not the main path.)

Install

npm i @atom63/slides

Peer dependencies you must also install:

npm i react react-dom sonner

You also need Tailwind CSS v4 in the consuming app (the engine ships utility classes, not a pre-compiled stylesheet — see Styling).

Quick start

A single-deck app needs four things: compile an .mdx deck, build a SlideDeckItem, render <SlidesPlayer>, and wire up styles. (A complete reference app lives at apps/deck-starter in the repo.)

vite.config.ts — compile MDX with a frontmatter export:

import mdx from '@mdx-js/rollup'
import react from '@vitejs/plugin-react'
import tailwindcss from '@tailwindcss/vite'
import remarkFrontmatter from 'remark-frontmatter'
import remarkMdxFrontmatter from 'remark-mdx-frontmatter'
import remarkGfm from 'remark-gfm'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [
    { enforce: 'pre', ...mdx({
      remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm],
      providerImportSource: '@mdx-js/react',
    }) },
    react({ include: /\.(mdx|tsx|jsx)$/ }),
    tailwindcss(),
  ],
})

app.tsx — the player provides the slide components internally; just pass the compiled deck:

import { SlidesPlayer } from '@atom63/slides'
import type { SlideDeckItem, SlideDeckMeta } from '@atom63/slides'
import Deck, { frontmatter } from './deck.mdx'

const deck: SlideDeckItem = {
  slug: 'my-talk',
  meta: frontmatter as unknown as SlideDeckMeta,
  content: Deck,
}

export function App() {
  return (
    <div style={{ height: '100vh', width: '100vw' }}>
      <SlidesPlayer deck={deck} onBack={() => {}} />
    </div>
  )
}

deck.mdx — frontmatter, then ----separated slides:

---
title: "My Talk"
date: "2026-01-01"
description: "An example deck."
---

import { CoverSlide, StatementSlide } from "@atom63/slides";

<CoverSlide eyebrow="2026" title="My Talk" credit="You" />

---

<StatementSlide kicker="The point" title="One idea per slide." />

---

## Bare markdown works too

- it renders through the engine's prose components
- including inline `code`

Styling

The engine uses Tailwind v4 utility classes. In your Tailwind entry CSS, import its stylesheets and point @source at its built classes:

@import "tailwindcss";
@import "@atom63/slides/theme-defaults";   /* tokens + Tailwind @theme color mappings */
@import "@atom63/slides/styles";           /* slide reveal animations */

/* Generate the utility classes the engine uses. */
@source "../node_modules/@atom63/slides/dist/**/*.js";

Import the engine CSS with CSS @import (in the Tailwind entry), not a JS importtheme-defaults ships a Tailwind @theme block that maps the palette into utilities like text-foreground/bg-primary, and @theme is only processed when the file is part of the Tailwind build.

  • @atom63/slides/theme-defaults — self-contained default values for every token the player reads + the @theme color mappings, so it renders out-of-the-box. A host that ships its own design tokens (e.g. via a token package) can skip this import.
  • @atom63/slides/styles — the slide reveal animation keyframes.

Theming

Everything is driven by CSS custom properties, so you restyle a deck without touching components. The default is light (theme-defaults).

Swap to a built-in theme — one extra @import, after theme-defaults, in your Tailwind entry CSS:

@import "tailwindcss";
@import "@atom63/slides/theme-defaults";
@import "@atom63/slides/themes/dark";   /* flips the whole deck to dark */
@import "@atom63/slides/styles";

Five themes ship in the box — each is one line, swapped for the dark line above:

| Theme | Import | Look | |---|---|---| | dark | @import "@atom63/slides/themes/dark"; | Neutral dark, blue signal. | | terminal | @import "@atom63/slides/themes/terminal"; | Dark monospace; phosphor-green on GitHub-dark greys. | | editorial | @import "@atom63/slides/themes/editorial"; | Light paper & ink; Cormorant serif, editorial red. | | neon | @import "@atom63/slides/themes/neon"; | Dark cyber; cyan/magenta on navy. | | bold | @import "@atom63/slides/themes/bold"; | Dark, charcoal + bright orange, strong Archivo sans. |

Theme palettes adapted from zarazhangrui/frontend-slides (MIT).

Theme contract

A theme is only a :root override of documented CSS custom properties — a palette, the three font tokens (--font-sans for headings/body, --font-mono for labels/code, --font-serif for quotes), and a few --theme-slide-* polish tokens — plus an optional @import url(...) for a webfont. There is no per-theme component code. This is the controllable surface: to restyle a deck you set or override these tokens, you do not write freeform CSS or bespoke components. The complete token set lives in src/styles/theme-defaults.css — that file is the contract; every built-in theme is just a subset of it overridden. Model a new theme on any of the shipped files in src/styles/themes/.

Write your own theme — override the tokens in your CSS. Most surfaces derive from the base palette via color-mix, so a handful of overrides restyle the whole deck:

:root {
  /* base palette — drives slides AND chrome */
  --background: #0b0b10;
  --foreground: #f2f2f5;
  --border: #3a3a42;          /* control / panel borders */
  --primary: #7c5cff;         /* the signal color */

  /* slide-specific knobs (optional) */
  --theme-slide-accent: var(--primary);
  --theme-slide-rule-color: color-mix(in oklch, var(--foreground) 25%, transparent);
  --theme-slide-surface: #1a1a20;   /* card / bento surfaces */
  --theme-slide-quote-color: #d8d8de;
}

Key tokens: base palette--background, --foreground, --card, --muted, --muted-foreground, --border, --input, --primary, --primary-foreground, --accent; slides--theme-slide-bg, --theme-slide-accent, --theme-slide-rule-color, --theme-slide-rule-width, --theme-slide-surface, --theme-slide-muted, --theme-slide-code-bg, --theme-slide-quote-color, --theme-slide-stage-bg. The full set lives in src/styles/theme-defaults.css — copy it as a starting point for a custom theme.

Runtime light/dark toggle: import themes/dark is a hard swap. For a toggle, copy dark.css and re-scope its :root to e.g. [data-slides-theme="dark"], then set that attribute on a wrapper.

theme: frontmatter and runtime presets

Set theme: in frontmatter to any of the five built-in names and the deck restyles at runtime — your agent writes this line, or you change it by hand:

---
title: "My Talk"
theme: terminal
---

Load the runtime presets once, with a CSS @import in your Tailwind entry (the same place you import theme-defaults and styles — a JS import will not deliver it):

@import "tailwindcss";
@import "@atom63/slides/theme-defaults";
@import "@atom63/slides/themes";          /* all presets, switched at runtime */
@import "@atom63/slides/styles";

DeckSurface then reads meta.theme at runtime and sets data-slides-theme="<name>" on the surface wrapper, so the matching [data-slides-theme] rule activates — no build step required; the deck restyles live as the theme: line changes.

Present-only consumer path — if you embed a bare <SlidesPlayer> without DeckSurface, keep the same @import "@atom63/slides/themes" above and set the attribute on a wrapper around the player yourself:

import { resolveTheme } from "@atom63/slides"

<div data-slides-theme={resolveTheme(deck.meta)}>
  <SlidesPlayer deck={deck} onBack={onBack} />
</div>

The per-theme :root imports (@atom63/slides/themes/dark, etc.) remain available for a static build-time hard-swap where you want a single theme locked in at compile time, without the runtime bundle.

Authoring

See the reference deck for the full template catalog and slot APIs, and inspect templates programmatically:

import { templateRegistry, getTemplate, listTemplates } from '@atom63/slides'

getTemplate('StatBento')
// → { name, label, category, props: [...], slots: [{ name: 'Stat', min: 0, max: 6, props: [...] }, ...] }

Subpath exports

Beyond the engine entry (@atom63/slides) and the style sheets (@atom63/slides/styles, @atom63/slides/theme-defaults), two optional subpaths ship in the same package.

@atom63/slides/vite — build-time Vite plugins

For multi-deck apps, the Vite plugins extract MDX frontmatter into a static manifest (so decks code-split into lazy chunks) and make *.mdx?raw imports resolve to source even when @mdx-js/rollup is active. vite is an optional peer dependency — install it only if you use this subpath.

// vite.config.ts
import { mdxManifestPlugin, mdxRawPlugin } from '@atom63/slides/vite'

export default defineConfig({
  plugins: [mdxManifestPlugin(), mdxRawPlugin() /* …mdx(), react(), tailwindcss() */],
})

@atom63/slides/editor — optional live deck editor

Optional / experimental. The main path is agent-authored MDX (see Author with a coding agent); this GUI is a hand-steering escape hatch, not a required part of the workflow, and its API is the least stable in the package.

A GUI deck editor with a live, runtime-compiled preview (no bundler in the loop) and a registry-driven template palette. Import its chrome stylesheet as a side effect.

import { DeckEditor } from '@atom63/slides/editor'
import '@atom63/slides/editor/styles'

<DeckEditor source={deckMdxSource} onChange={setSource} />

License

MIT © You Zhang (ATOM63)