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

deckthis

v0.1.8

Published

Write presentations as HTML files, served with a lightweight dev server

Readme

deckthis

用 HTML 文件写演示文稿,在浏览器里展示。每张幻灯片就是一个普通的 .html 文件——无需框架,无需构建,打开编辑器就能写。

English →

安装

npm install -g deckthis

或者直接使用,无需安装:

npx deckthis <目录>

快速开始

  1. 创建一个目录,放入幻灯片 HTML 文件:
my-talk/
  01.html
  02.html
  03.html
  1. 启动开发服务器:
deckthis my-talk
  1. 浏览器打开 http://localhost:39200

幻灯片按文件名字母序自动发现。修改任意文件,浏览器自动刷新。

操作方式

| 操作 | 说明 | | ------------------- | ---------- | | / / Space | 下一张 | | / | 上一张 | | 左右滑动 | 移动端翻页 |

目录结构

my-talk/
  01.html              # 幻灯片——按文件名字母序自动发现
  02.html
  03.html
  _overlay.html        # 前景层(页码、Logo 等)——可选
  _underlay.html       # 背景装饰层——可选
  deckthis.config.ts   # 配置文件——可选
  • _ 前缀文件不会被当作普通幻灯片,用于 overlay / underlay。
  • 配置文件为 deckthis.config.ts,使用 defineConfig 导出以获得类型提示。

配置(deckthis.config.ts

import { defineConfig } from "deckthis";

export default defineConfig({
  // 自定义幻灯片顺序(接收自动发现的列表,返回最终顺序)
  order: (discovered) => {
    const intro = discovered.find((s) => s === "/intro.html");
    const rest = discovered.filter((s) => s !== "/intro.html");
    return intro ? [intro, ...rest] : discovered;
  },

  // 额外静态资源目录(绝对路径,在 deck folder 之后按顺序回退查找)
  assets: ["/path/to/theme-assets"],

  // 在每张幻灯片 HTML 被服务前转换(不作用于 overlay/underlay)
  beforeEach: (html, ctx) => {
    return html.replace("</head>", '<link rel="stylesheet" href="/theme.css"></head>');
  },

  // 手动指定 overlay / underlay(默认自动检测目录下的 _overlay.html / _underlay.html)
  overlay: "/_overlay.html",
  underlay: "/_underlay.html",
});

配置项说明

| 字段 | 类型 | 说明 | | ------------ | ------------------------------------------ | ---------------------------------------------- | | order | (discovered: string[]) => string[] | 控制幻灯片顺序,可插入插件提供的额外页 | | assets | string[] | 绝对目录路径列表,按请求路径顺序回退查询 | | beforeEach | (html, ctx) => string \| Promise<string> | 每张 slide 的 HTML 转换钩子 | | overlay | string | 前景 iframe URL,默认自动检测 _overlay.html | | underlay | string | 背景 iframe URL,默认自动检测 _underlay.html |

Overlay 与 Underlay

_overlay.html 叠加在所有幻灯片上方(默认禁用鼠标事件),_underlay.html 叠加在下方。

每次切换幻灯片,deckthis 会向两个 iframe 广播 postMessage

window.addEventListener("message", (e) => {
  if (e.data?.type !== "deckthis:slide-change") return;
  const { current, total, title } = e.data;
  // current: 当前页码(从 1 开始)
  // total: 总页数
  // title: 来自 <meta name="deckthis:title"> 或 <title>
});

在幻灯片中添加元数据:

<meta name="deckthis:title" content="项目背景" /> <meta name="deckthis:section" content="01" />

title 回退规则:如果没有 deckthis:title,自动使用 <title> 标签内容。

插件

插件是一个普通函数,接收用户配置,返回合并后的配置对象:

// _plugin/my-theme.ts
import type { DeckthisConfig } from "deckthis";

export function myTheme(userConfig: DeckthisConfig = {}): DeckthisConfig {
  return {
    overlay: "/_plugin/overlay.html",
    assets: ["/path/to/_plugin"],
    order: (discovered) => [
      "/_plugin/cover.html",
      ...(userConfig.order ? userConfig.order(discovered) : discovered),
      "/_plugin/thanks.html",
    ],
    beforeEach: async (html, ctx) => {
      const base = userConfig.beforeEach ? await userConfig.beforeEach(html, ctx) : html;
      return base.replace("</head>", '<link rel="stylesheet" href="/_plugin/theme.css"></head>');
    },
  };
}
// deckthis.config.ts
import { myTheme } from "./_plugin/my-theme";

export default myTheme({
  // 传入自己的配置,插件负责包裹
});

插件约定:

  • 插件文件放在 _plugin/_ 前缀目录下,不会被当作幻灯片。
  • 插件是纯函数,不感知框架内部,只做配置变换。
  • 需要包裹 order / beforeEach 时,先调用用户版本再追加插件逻辑。

CLI 命令

deckthis <目录>              # 启动 dev server(默认端口 39200)
deckthis <目录> --port 3000  # 指定端口

deckthis demo list           # 列出内置 demo
deckthis demo <name>         # 复制 demo 到当前目录

deckthis skill               # 复制 AI 编程 skill 到指定目录

deckthis export <目录>                          # 导出为 PPTX(presentation.pptx)
deckthis export <目录> -o my-talk.pptx          # 指定输出路径
deckthis export <目录> --width 1920 --height 1080  # 视口尺寸(默认 1920×1080)
deckthis export <目录> --scale 2                # 提高截图分辨率
deckthis export <目录> --wait 3000              # 截图前额外等待更久

导出为 PPTX

export 命令会按顺序截取每张幻灯片,打包成 .pptx 文件。每张幻灯片以全屏图片的形式嵌入,完整保留 CSS 样式、字体以及三层渲染结构(underlay + slide + overlay)。

export 依赖 playwright-chromium,需在项目中安装(仅需一次):

npm install -D playwright-chromium
npx playwright install chromium

安装完成后即可导出:

deckthis export my-talk -o my-talk.pptx

如果某个 deck 里有较慢的 CSS transition 或 overlay 延迟更新,可以通过 --wait <毫秒> 调整导出前的等待时间。默认值是 1500,所以大多数情况下不需要显式配置。

也可以在 deckthis.config.ts 中提供默认导出配置:

import { defineConfig } from "deckthis";

export default defineConfig({
  export: {
    width: 1504,
    height: 831,
    wait: 3000,
  },
});

CLI 参数优先级高于 config.export

getDeckDir()

deckthis.config.ts 内调用 getDeckDir() 可获取当前 deck folder 的绝对路径,适合动态构建资源路径:

import { defineConfig, getDeckDir } from "deckthis";
import path from "node:path";

export default defineConfig({
  assets: [path.join(getDeckDir(), "_assets")],
});

示例

安装后,复制并运行内置 demo:

deckthis demo basic        # 最简示例,3 张幻灯片
deckthis demo with-config  # 演示所有 defineConfig 选项
deckthis demo with-plugin  # 演示插件模式
cd basic && deckthis .

开发(monorepo)

pnpm install

# 构建浏览器运行时(首次运行或修改 core 后需执行)
pnpm build:core

# 运行所有测试
pnpm test

# 只运行某个包的测试
pnpm test:core
pnpm test:cli

项目结构

packages/
  deckthis-core/          # 浏览器端运行时(SlideDeck)
    src/core.ts           # iframe 布局、键盘/触摸导航、overlay/underlay
    src/wrapper.ts        # IIFE 入口,fetch /__deckthis/config 后初始化 SlideDeck
  deckthis-cli/           # 开发服务器 + CLI
    src/cli.ts            # CLI 入口,端口管理,文件监听重启
    src/dev-server.ts     # Hono 服务器,SSE 热更新,assets/beforeEach 管道
    src/load-config.ts    # 动态 import 加载 deckthis.config.ts
    src/types.ts          # DeckthisConfig、defineConfig、getDeckDir