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

@tjcages/komo

v0.7.0

Published

Point, area, and threaded comments for website branches.

Readme

komo

npm version downloads

Comments for your website. Point at an element, mark an area, and leave feedback your team can reply to, resolve, or copy into a coding agent.

Framework independent. Shared persistence. Google identities and guest reviewers.

Website · Documentation · Playground

Review actions update immediately while saving in the background. Failed writes roll back with a notice; unsaved comment text is retained.

Install

npm install @tjcages/komo
npx @tjcages/komo init

Requires Node.js 22 or newer. The unscoped komo package on npm is unrelated; use @tjcages/komo.

The setup command detects your Git repository and generates komo.config.js before sign-in. Mount that helper in your app:

import { initKomo } from './komo.config.js';
initKomo();

Keep the setup terminal open and start your app in another terminal. Choose Connect komo in your app’s sidebar. Google sign-in opens in a separate window; komo creates the project and returns you to feedback on your site. The CLI saves the final public settings to .komo/project.json, updates the helper, and prints an inline configuration. Use --origin for a different dev port or deployed site. If interrupted or expired, run komo init again to resume; completed projects are never overwritten.

Hosted onboarding is available through the dedicated komo service. Self-hosting is available through the same CLI.

Usage

Mount after the page has loaded:

import { initKomo } from '@tjcages/komo';
initKomo({ project: 'YOUR_PROJECT_KEY' });

Optional configuration stays at the call site:

initKomo({
  project: 'YOUR_PROJECT_KEY',
  enabled: import.meta.env.DEV || import.meta.env.PUBLIC_PREVIEW === 'true',
  pageRoot: document.querySelector('#app'),
});

React

With React 18.2 or 19, call the hook once near your app root:

'use client'; // Required for Next.js App Router client components.
import { useKomo } from '@tjcages/komo/react';

export function Komo() {
  useKomo({ project: 'YOUR_PROJECT_KEY' });
  return null;
}

Render <Komo /> in your app or layout. The hook handles mounting, cleanup, and React Strict Mode. Inline configuration objects are supported; unchanged values do not restart komo. Changing configuration remounts it, and enabled: false removes it. Memoize callback options with useCallback and pass stable DOM elements for pageRoot or drawerContainer. Mount only one hook per page; do not combine it with a separate initKomo() call. Server rendering does not mount the tool.

The endpoint is the comments API, not your website or preview URL. Hosted komo defaults to https://komo.offbr.co. Google sign-in returns to https://komo.offbr.co/auth/google/callback, regardless of the website embedding komo. For self-hosting, pass your Worker or Node API URL as endpoint. Your current page comes from the browser. Setup detects repository metadata from Git; include its printed repo value to enrich agent prompts.

Comments are shared across deployments by default. Use pnpm exec komo init --branch-scope to separate them by branch. For automatic branch detection, import from the optional generated komo.config.js helper and run komo sync before builds. It detects the current branch from deployment environment variables or Git; set KOMO_BRANCH if neither is available. It fails rather than silently grouping unknown branches.

Features

  • Point and area comments anchored to page elements.
  • Replies, reactions, author-only editing, resolution, and undo.
  • Searchable sidebar, draggable dock, and Google or guest profiles.
  • Copy open feedback with selectors, source paths, page URLs, replies, and geometry into an agent.
  • Hosted Cloudflare storage, or your own Worker/D1 or Node/PostgreSQL service.

Agent CLI

komo init adds the default comment workflow to AGENTS.md, preserving existing instructions. For an existing project, run komo agents setup from its root. Commit the instructions so every agent uses them.

Before editing, agents read open comments, export the relevant prompt, and read replies. After verifying a simple fix, an agent can reply with evidence and resolve it at 90%+ confidence. Complex or uncertain work stays open with a question or progress reply. This is guidance for your coding agent; the CLI does not run an agent or measure its confidence.

Requires komo 0.2.0 or later. Connect your coding agent to the same comments your team sees in the browser:

npm install @tjcages/komo@latest
npx @tjcages/komo login
npx @tjcages/komo comments list
npx @tjcages/komo comments get THREAD_ID
npx @tjcages/komo comments reply THREAD_ID --body "Fixed and verified on mobile."
npx @tjcages/komo comments resolve THREAD_ID

Run these from a project configured with komo init. The CLI searches parent directories for .komo/project.json. Google sign-in opens a local browser handoff; --no-open prints the local sign-in link instead. Credentials are stored outside your repository in ~/.config/komo, with a private file per API/project. Sessions stay valid until you sign out. komo logout revokes the session and removes its file.

For an existing inline installation, pass --project YOUR_PROJECT_KEY --origin https://your-site.example. --origin is an approved website address; --endpoint is the comments API. New setups remember the website address. Older setups default to http://localhost:3000; override it if that site is not approved. --repo and --branch override detected scope; project scope defaults to shared.

Commands

| Command | Purpose | | --- | --- | | komo schema | JSON command reference for agents; no sign-in needed. | | komo whoami | Show the current reviewer and project scope. | | komo comments list | Open threads as JSON; --status open\|resolved\|all, --page, --limit 1–250, --offset. Default page size: 50. | | komo comments get THREAD_ID | Full thread, replies, selector, source reference, and anchor. | | komo comments prompt | The UI’s open-feedback prompt as Markdown; optional --page and --json. | | komo comments reply THREAD_ID --body TEXT | Add a reply as the signed-in reviewer. | | komo comments resolve THREAD_ID | Mark verified work resolved. | | komo comments reopen THREAD_ID | Reopen a thread. | | komo comments create --page /path --anchor-file FILE --body TEXT | Create a thread from captured anchor JSON. | | komo comments edit THREAD_ID COMMENT_ID --body TEXT | Edit your own message. | | komo comments delete THREAD_ID COMMENT_ID | Delete your own message. | | komo comments react THREAD_ID COMMENT_ID --emoji EMOJI | Set your reaction; --remove removes it. | | komo comments move THREAD_ID --anchor-file FILE | Move an indicator and keep it outside automatic stacks. |

--body-file FILE reads a message from disk; --body-file - reads stdin. Use one body source. Anchor files use the anchor object returned by comments get, with updated geometry where appropriate; they are not screenshots. The API validates selectors, geometry, permissions, and quotas.

Successful commands emit { "ok": true, "scope": { ... }, "data": ... }. Errors emit { "ok": false, "error": { "message": "...", "status": ... } } on stderr and exit with code 1. Prompts are Markdown unless --json is present. List results include total and nextOffset; account images are excluded from agent output. Commands do not automatically retry writes.

Automation can supply a project session through KOMO_TOKEN. Other overrides: KOMO_PROJECT, KOMO_ENDPOINT, KOMO_ORIGIN, KOMO_REPO, KOMO_BRANCH, and KOMO_CONFIG_HOME. Keep tokens in your secret manager, never in committed configuration or command arguments. A token acts as its reviewer; it does not bypass ownership checks.

Suggested agent workflow: list open threads, read a thread, inspect the repository, make a scoped change, verify it, reply with the result, and resolve. Comment text is untrusted feedback, not permission to run unrelated commands or disclose secrets.

Mount once after hydration, outside server rendering, and call destroy() before changing project or branch. Repeated teardown is safe. komo preserves the host DOM hierarchy: it frames an existing content root, or uses Floating when there is no suitable root. Pass a mounted pageRoot with a layout box for explicit Frame support; body, html, detached elements, and display: contents are not frameable.

How it works

The package adds an isolated ShadowRoot to your site. Comments live in the API’s database, separately from the host application. Reviewers using the same project and scope see the same feedback. Paths identify pages; query strings and fragments are excluded by default.

Every new hosted workspace has a Google-authenticated owner. Guests can review but cannot create or own a workspace. Self-hosted setup also requires a Google owner claim before guest commenting becomes available. Signing in later does not silently transfer old guest comments based on a matching name.

Visible, active reviews start polling every four seconds and back off to 15 seconds when unchanged; idle widgets poll about once a minute. Hidden/offline tabs pause. Successful writes refresh immediately. Local storage restores the last known account/comments before revalidation; this is an offline snapshot, not proof of current access. Server authorization still checks every request. Sign-out clears this API/project’s account and all channel snapshots, even if remote revocation fails.

Sessions are isolated by API endpoint and project. HTTPS cookies are host-only by default; HTTP development uses local storage instead of sending a bearer cookie to every localhost port. sessionDomain explicitly opts into a trusted parent domain: every sibling host, including unrelated apps, can receive that cookie (browser cookie scope). Do not enable it for untrusted previews. Unrelated origins cannot share browser storage. If trusted preview gateways all proxy the same API, set the same sessionEndpoint canonical URL alongside the trusted sessionDomain; never reuse it across independent APIs. The komo website opts in for its own controlled previews.

Legacy project-only cookies are retired rather than trusted across API installations. Existing endpoint-scoped local sessions can migrate after server validation; cookie-only users may need to sign in once. Browser storage can be disabled independently; sessions remain usable in memory when neither cookie nor local storage is available. Client credentials and cached feedback are accessible to scripts on the embedding site—install only on sites you trust.

On localhost, the widget defaults to a separate local channel in the configured API’s database. It is not a browser-only database or a private workspace per developer. Project permissions still apply; use a separate project/API for isolated development data. Switching to Shared selects the configured shared branch. pnpm dev:api is different: it starts a local API with its own local database.

Projects default to link access. Owners can restrict feedback to invited Google accounts in Account → Project settings. The public project key identifies a workspace; it is not a credential. Approved origins control embedding, and private-project membership controls feedback access. Your website and repository permissions remain separate.

Hosted setup

pnpm exec komo init

Mount the generated komo.config.js helper and open your app. Select Connect komo in the sidebar and sign in with Google. Review the detected production and preview addresses in the sidebar and add any others, one per line. Connecting approves the current site and those listed addresses, including production sites that have not launched. Remove a suggested address to leave it unapproved. Google credentials and account-wide management stay on the komo service; your site receives a session for its new project.

The CLI waits up to ten minutes and replaces the temporary setup configuration after connection. Keep the terminal open. Run komo init again after an interruption or expiry. The temporary polling secret stays in ignored .komo/setup.json and is never bundled into your site. A reload can resume commenting while the CLI finishes. Run komo sync before builds that use the generated helper.

If the app cannot run, use the hosted recovery link printed in the terminal, sign in, and select Create project. The CLI still writes the final configuration.

Approve your deployed website in Approved sites. komo detects deployment URLs when available; --origin can supply one. You can paste a full preview link—the modal extracts its site address. No DNS changes are required, including for pages.dev previews.

The setup page manages your account and approved sites. Leave comments on the website where you installed komo.

Return to /setup?workspace=<project key> to approve additional sites (up to ten). Only the Google owner can approve sites. The site address controls where that owner’s project can be embedded; it does not grant ownership of a domain or access to other projects. The API endpoint is the komo service, not your website URL.

Starter limits per owner/workspace:

| Limit | Allowance | | --- | --- | | Projects per Google owner | 3 | | Stored comments, including replies | 250 | | Logical storage budget | 10 MiB | | Write requests per project | 500/day | | Request body | 16 KiB | | Comment / reviewer name | 4,000 / 60 characters |

The storage budget accounts for text, anchors, reactions, and a fixed profile allowance per member. It is deliberately conservative, not a measurement of D1 disk usage. Soft-deleting or resolving a comment does not reset its quota. Inline file attachments are not supported; avatars have a bounded representation.

The service also applies per-IP and per-user limits, database-enforced quotas, owner-approved site restrictions, payload validation, project suspension, hourly cleanup, and a global daily request ceiling. Edge rate limiting runs before database work. These controls bound ordinary abuse; Google accounts and CORS do not eliminate automated abuse. The service remains a starter offering, not an unlimited storage service. Project exports, imports, and quota recovery are available below. Billing upgrades are not implemented yet.

Self-host

Install komo in your project, then run:

pnpm exec komo init --self-host --origin https://preview.example.com

The CLI signs into Cloudflare, creates a dedicated D1 database, applies migrations, deploys a Worker, and prompts for the Google client secret through Wrangler. It writes the deployment configuration into .komo/ so you own and can change it.

Create a Google OAuth Web application client with openid profile email access. Pass its public client ID with --google-client-id, or enter it when prompted. Add the callback printed after deployment:

https://YOUR-WORKER.workers.dev/auth/google/callback

Open the owner-claim link printed by setup and sign in with Google. The one-time claim key is saved in .komo/owner-key, excluded from Git, and only its hash is deployed. Ownership cannot be claimed again. Keep the Google secret out of browser code and configuration files.

If setup is interrupted, run pnpm exec komo deploy to resume the existing deployment. Do not rerun initialization to create another database. The generated .komo/wrangler.json supports explicit allowed preview domains and single-label wildcard origins. Only allow domains whose scripts you trust.

Self-hosted storage belongs to your Cloudflare account; its service limits and charges apply. Use komo deploy for package migrations and komo project export for feedback backups. The hosted service and self-hosted installations use separate databases.

For a Node container with PostgreSQL (including Cloud Run), use the Node self-hosting guide. It uses the same endpoint, project configuration, and CLI commands without Wrangler. Existing Worker installations do not change.

Configuration

Client options

Pass these to initKomo(config) from @tjcages/komo or useKomo(config) from @tjcages/komo/react.

YOUR_PROJECT_KEY is a placeholder for a string. Hosted komo generates the key during komo init; copy that value. For self-hosting, use the project identifier configured on your server. Reuse the same key across sites that should share feedback.

| Option | Type | Default | Purpose | | --- | --- | --- | --- | | endpoint | string | Hosted komo API | Comments API root; HTTPS outside localhost. | | project | string | Required | Public project identifier returned by setup. | | repo | string | Project key | Repository identifier, usually owner/repo. | | scope | "project" \| "branch" | "project" | "project" shares comments; "branch" separates branches. | | branch | string | Inferred by komo sync | Required only for branch scope. | | enabled | boolean | true | Set from your build environment to restrict review UI. | | pageRoot | HTMLElement | Sole existing content root, when present | Mounted element inside body to scale in Frame mode. Body and html are not supported. | | source(element) | (element: Element) => string \| undefined | Anchor metadata | Return a repository-relative source path. | | sourceUrl(source, branch) | (source: string, branch: string) => string | GitHub viewer | Custom source or editor link. | | page() | () => string | location.pathname | Canonical page identifier. | | drawerContainer | HTMLElement | Viewport | Element used to center the drawer before it is dragged. | | autoHideDrawer | boolean | true | Set false to keep the drawer visible away from the pointer. | | sidebar | "background" \| "edge" | "edge" | "edge" (Floating) is a draggable sidebar that parks off and peeks from the viewport edge while closed. "background" (Frame) frames the site and shows the sidebar in the scaled review sheet. Account → Sidebar switches the two; that choice is remembered per project. | | emojiDataSource | string | jsDelivr emoji data 1.8.0 | Full emoji JSON URL; fetched only after “Choose another emoji”. | | pollInterval | number | 4000 | Refresh interval in milliseconds, minimum 2000. | | sessionDomain | string | Host-only | Explicit trusted parent domain; all sibling hosts can receive the session. Empty string disables sharing. | | sessionEndpoint | string | endpoint | Canonical API identity for trusted gateways to the same service; never share across independent APIs. |

For a restricted CSP or offline deployment, host [email protected]/en/emojibase/data.json on your site and pass emojiDataSource: "/emoji/data.json". Allow that URL in connect-src; cache it with your service worker for first-use offline access. Quick reactions need no emoji data download. The full picker caches its data in IndexedDB after the first successful load.

The lower-level initComments export remains available. It requires explicit endpoint, project, repo, and branch; it does not infer scope. Existing integrations keep their branch grouping.

The returned controller has open(), close(), comment(element), refresh(), and destroy(). Repeated initialization returns the current controller; destroy it before switching projects. SSR returns a no-op controller. In React, use the useKomo hook. With Astro view transitions, destroy before swapping the document and initialize after navigation.

CLI

| Command / flag | Purpose | | --- | --- | | komo init | Create a Google-owned hosted workspace. | | komo init --self-host | Create your Worker and D1 database. | | komo sync | Regenerate the public client helper. Run before dev/build. | | komo deploy | Resume or redeploy generated self-host infrastructure. | | --origin URL | Optional website address. Otherwise detected from Cloudflare Pages, Vercel, or Netlify; defaults to localhost. | | --endpoint URL | Override hosted API or self-host deployment URL. | | --repo OWNER/REPO | Override Git detection. | | --branch-scope | Opt into separate comments per branch. | | --google-client-id ID | Self-hosted Google OAuth client ID. | | KOMO_BRANCH | Explicit build-time branch override. |

Branch detection also supports CF_PAGES_BRANCH, WORKERS_CI_BRANCH, VERCEL_GIT_COMMIT_REF, GITHUB_HEAD_REF, GITHUB_REF_NAME, and BRANCH, followed by the Git checkout.

Backend

PROJECTS is a JSON object keyed by public project ID. Each entry supports:

| Option | Default | Purpose | | --- | --- | --- | | repo | Required | Repository allowed for the project. | | origins | Required | Exact allowed origins; self-host supports single-label wildcards. | | allowGuests | true | Enable named guest sessions. | | allowGuestResolve | true | Allow guests to resolve threads. | | requireOwner | true in generated setups | Block reviewing until Google ownership is claimed. Legacy static projects remain compatible. | | bootstrapHash | Generated | SHA-256 owner-claim key hash. | | suspended | false | Disable a project. | | writesPerDay | 10000 self-hosted | Daily write-request allowance; hosted uses 500. |

Worker bindings: DB (D1), optional EDGE_LIMIT (rate limiter). Variables: PROJECTS, GOOGLE_CLIENT_ID, optional GITHUB_CLIENT_ID, KOMO_HOSTED="true" to enable hosted provisioning, and KOMO_PAUSED="true" to pause service requests. Store GOOGLE_CLIENT_SECRET and optional GITHUB_CLIENT_SECRET as Worker secrets. Hosted configuration uses an hourly cleanup trigger. /health remains available while paused.

Source context

Stable attributes make annotations resilient to layout changes:

<section data-comment-anchor="pricing" data-comment-source="src/components/Pricing.tsx">
  ...
</section>

Anchors may include bounded context strings for element tag, role, accessible label, nearby and selected text, CSS classes, styles, and DOM scope. Browser and CLI prompts quote these capture-time hints; agents must verify them against the current implementation. Older anchors remain supported.

If an element disappears, the original page position remains available. komo cannot inspect closed shadow roots, canvas internals, or cross-origin iframe content. It does not invent source line numbers.

Choose Copy all comments for agent to copy open feedback across the configured scope; the sidebar copy button includes open comments on its current page. Resolved threads and deleted messages are excluded. Copying does not send anything to an agent.

Development

Requires Node.js 22+, a modern browser, and Cloudflare access for deployment.

pnpm --filter @tjcages/komo typecheck
pnpm --filter @tjcages/komo test
pnpm --filter @tjcages/komo build

Tests use real workerd and isolated SQLite databases. To publish this repository’s package artifact and website review preview, run pnpm run comments:preview from a feature branch. It does not deploy the marketing Worker or replace the existing review database.

Credits

The dock adapts Danny Williams’s morphing menu. Icons come from Untitled UI. See NOTICE.md for attribution.

License

MIT.

Development

pnpm install
pnpm build
pnpm typecheck
pnpm test
pnpm size
pnpm dev

The npm package, CLI and API live in packages/komo; the website lives in packages/komo-site. pnpm dev:api starts a local API. Production deployments retain the existing hosted database; local development uses a separate database.

Source

Extracted from the komo product at source commit f57f3521 in the Cloudflare marketing workspace. Product development now lives in tjcages/komo. Third-party credits are preserved in each package’s NOTICE.md.

Project management

Sign in as the Google owner with npx @tjcages/komo login. In the widget, open Account → Project settings to manage access, download feedback, clear resolved threads, or delete a hosted project.

npx @tjcages/komo project info
npx @tjcages/komo project access --access private
npx @tjcages/komo project invite --email [email protected]
npx @tjcages/komo project export --out comments.json

On localhost, the widget defaults to a separate local channel in the configured API’s database. It is not a browser-only database or a private workspace per developer. Project permissions still apply; use a separate project/API for isolated development data. Switching to Shared selects the configured shared branch. pnpm dev:api is different: it starts a local API with its own local database.

Projects default to link access. Private projects require Google sign-in and owner-approved membership for reads and writes, including the CLI. Invitations match a verified email address, expire after seven days, and are single-use. Members can review; only owners manage access, export, import, or delete. Google accounts used before this release should sign out and back in to verify their email. Repository access is separate.

Quota recovery and migration

Export first, then permanently clear resolved threads with npx @tjcages/komo project clear-resolved --confirm PROJECT_KEY. This reclaims stored-comment quota. In the sidebar’s Resolved view, owners can also use the trash button to permanently delete only the currently filtered threads and their replies after confirmation. project delete --confirm PROJECT_KEY permanently deletes a hosted project and frees its project slot. Both are owner-only. The account panel also offers these actions with typed confirmation.

To migrate, export from your source, set up a destination using npx @tjcages/komo init --self-host in another directory, then sign in there and run:

npx @tjcages/komo project import --file /path/to/comments.json

Exports include threads, replies, reactions, anchors, and historical profiles across all pages and branches, including resolved feedback. They exclude sessions, credentials, verified emails, and membership. Imports use the destination repository and keep imported authors unverified. Retrying the same export is safe; existing imported records are not overwritten. Destination quotas still apply. Export retries are required if feedback changes while downloading. Keep export files private.

Upgrade self-hosted deployments with npm install @tjcages/komo@latest then npx @tjcages/komo deploy; the CLI applies bundled database migrations before redeploying. Self-hosted project removal is controlled by your Worker configuration. Account-wide data requests remain available at [email protected].

Without pageRoot, a sole existing content element with a layout box enables Frame. Script and style elements do not count as content roots. Multiple roots or display: contents use Floating; pass a suitable existing app container for Frame.