helldots

中文文档
0.13.0发布于 2026/11/04MITTypeScriptES Module零依赖构建来源已验证

Drop-in comment overlay for web apps — click anywhere to leave a comment anchored to that element, with an automatic screenshot and environment capture

原始使用文档
文档目录11 节
  1. Features
  2. Install
  3. Quick start
  4. Wiring it to your own backend
  5. Frameworks
  6. Handing a comment to a coding agent
  7. Common options
  8. Guides
  9. Browser support
  10. ESM only
  11. License

HellDots

Drop-in comment overlay for web apps. Your team clicks anywhere on a page, leaves a comment anchored to that element, and HellDots captures the context needed to act on it — a screenshot, the browser, the viewport, the DOM path.

npm bundle size license

Documentation · Playground · npm

Leaving a comment on a button, classifying it as a high-priority bug, opening its captured context, then the inbox and the metrics dashboard

Features

  • Anchored comments that survive reloads and re-anchor after the page changes — or are marked orphaned, never silently dropped
  • Automatic context: a screenshot, region crops, URL, viewport, browser, OS and the element's DOM path
  • Triage: status, type, priority, tags, reactions and an audit trail
  • Metrics dashboard with CSV and PDF export
  • Copy for agent: a plain-text context block built for AI coding assistants
  • You own the data: nothing is sent anywhere — wire the callbacks to your backend, or let the widget persist to localStorage
  • Isolated: renders inside a Shadow DOM, framework-agnostic, typed
  • English and Spanish built in

Install

npm install helldots

modern-screenshot (the screenshot renderer) is a peer dependency. npm 7+, pnpm 8+ and bun install it automatically; on Yarn, add it explicitly with yarn add modern-screenshot.

Quick start

import { createCommentOverlay } from "helldots";

createCommentOverlay({
  user: { name: "Ana" },
  persistence: "localStorage",
});

That's it. A toolbar appears at the bottom of the page. Alt+C (or Option+C on macOS) toggles comment mode; click anywhere to leave a comment, or drag to select a region and attach a screenshot of it.

Wiring it to your own backend

Skip persistence and use the callbacks instead. onChange carries every mutation as one stream; onReady is the safe place to restore:

import { createCommentOverlay } from "helldots";

createCommentOverlay({
  user: { name: currentUser.name, id: currentUser.id },
  onChange: (event) => api.post("/helldots-events", event),
  onReady: async (overlay) => {
    overlay.loadComments(await api.get("/comments"));
  },
});

Every comment is plain JSON: pass serializeComments() output straight to your API and hand it back to loadComments() later. Prefer one callback per event (onCommentCreated, onReplyAdded, …)? They fire at the same moments — see Events.

localStorage holds roughly a hundred comments with screenshots and assumes one active tab per page; past that, persist through the callbacks. To keep base64 images out of your database, upload them with transformScreenshot. → Persistence guide

Frameworks

Server-rendered apps (Next.js, Remix, Astro…): importing is safe — nothing touches the DOM at import time. Create the overlay on the client only:

useEffect(() => {
  const overlay = createCommentOverlay({ user, persistence: "localStorage" });
  return () => overlay.cleanup();
}, [user]);

Single-page apps: tell the widget when a navigation happened, and let its own cross-page jumps use your router:

const overlay = createCommentOverlay({
  user,
  navigate: (page) => router.push(page),
});

router.afterEach(() => overlay.notifyNavigation());

→ Frameworks guide

Handing a comment to a coding agent

Every comment has a copy button that puts a plain-text context block on the clipboard, built for pasting into an AI coding assistant:

Page: /pricing
Viewport: 1440x900
Anchor state: anchored
Status: open
Selector: #plans > div.card:nth-child(2) > button
Element: <button class="cta" data-plan="pro">
DOM path: body > main.layout > section#plans > div.card > button.cta
Nearby text: "Upgrade to Pro"
Comment by Ana (2026-07-29T10:14:00.000Z):
"This button does nothing on mobile"
Type: bug
Priority: high
Tags: checkout, ios
URL: https://example.com/pricing
Screen: 390x844
Browser: Safari 17.2
OS: iOS 17.2

Common options

OptionDefault
user"Anonymous"{ name, id? } — pass id whenever two people can share a name
persistence"none""localStorage", or handle it yourself through the callbacks
onChange—One stream for every mutation
onReady—Widget mounted; the safe place to loadComments()
autoScreenshottrueCapture a screenshot and environment snapshot per comment
transformScreenshot—Upload each image and store your URL instead of a base64 data URL
canown records onlyWho may edit and delete — a UI guard, not authorization
navigatefull page loadSPA router hook for the widget's cross-page jumps
localebrowser language"en" and "es" ship

→ All options · Events · Methods · Types

Guides

  • Captures — what is recorded, web fonts, slow or very long pages, iframes, timeouts
  • Identity — user.id, who can edit and delete, and what can does not secure
  • Triage — status, type, priority, tags, reactions and the audit trail
  • Metrics — the dashboard, getMetrics(), CSV and PDF export
  • Persistence — localStorage limits, your own backend, screenshot uploads
  • Deep links — shareable comment URLs, and loading only the linked comment
  • Realtime — syncing over a socket without echoing your own writes
  • Frameworks — server rendering, SPA routers, hotkeys, no-bundler setups, deferred mounts

Browser support

Modern evergreen browsers. The widget renders inside a Shadow DOM, so your page's CSS cannot leak into it and its styles cannot leak out.

ESM only

This package ships ES modules only. import works everywhere — bundlers, Vite, Next.js, Node ≥ 18, native <script type="module">. There is no CommonJS build, so require("helldots") will not work. TypeScript definitions ship with the package.

For a plain <script> tag with no bundler, a self-contained UMD build is on the CDN:

<script src="https://unpkg.com/helldots"></script>
<script>
  HellDots.createCommentOverlay({ user: { name: "Ana" } });
</script>

License

MIT

版本与发布记录

helldots 共发布 13 个版本,首次发布于 2026/07/30;过去 12 个月发布了 13 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.13.0latest2026/11/04今天
0.12.12026/09/091 个月前
0.12.02026/09/041 个月前
0.11.02026/09/042 个月前
0.10.02026/08/272 个月前
0.9.12026/08/262 个月前

关于 helldots 的常见问题

helldots 是什么?

插入式评论覆盖网络应用程序-点击任何地方留下评论锚定的元素,与自动截图和环境捕获

如何安装 helldots?

在项目目录运行 npm install helldots,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:modern-screenshot(^4.7.0)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

helldots 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

helldots 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

helldots 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=18。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

helldots 可以商用吗?

helldots 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

helldots 还在维护吗?

最新版本 0.13.0 发布于 2026/11/04(今天);至今共发布 13 个版本,其中过去 12 个月发布了 13 个;首次发布于 2026/07/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。