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

@f12o/markable

v2026.6.3

Published

Headless interaction layer for marking artifacts with structured feedback and rewrite annotations.

Readme

markable

日本語版

Make anything markable.

markable is a headless interaction layer for attaching structured feedback, review comments, and rewrite annotations to artifacts without changing the existing app implementation.

Two modes:

  • dev: developer-oriented review annotations that can be consumed by agents and rewrite tools.
  • prod: user-facing feedback and inquiry capture with URL, selection, viewport, and optional context.

Install

npm install @f12o/markable

Subpath exports are used for integrations:

import { createMarkable } from "@f12o/markable/core";
import { createDomAdapter } from "@f12o/markable/dom";
import { markable } from "@f12o/markable/vite";

Vite usage

import { defineConfig } from "vite";
import { markable } from "@f12o/markable/vite";

export default defineConfig({
  plugins: [
    markable({
      mode: process.env.NODE_ENV === "production" ? "feedback" : "review",
      locale: "en",
      commentsFile: ".markable/comments.json",
      endpoint: "/__markable/comments",
      // Set to false to hide the default "Powered by Markable" footer link.
      poweredBy: true,
    }),
  ],
});

CLI: dev-only setup

For projects that use Markable only as a developer review tool, the bundled CLI wires up a safe, development-only configuration:

pnpm dlx @f12o/markable init

init adds @f12o/markable to devDependencies, writes a Markable-owned markable.config.ts, adds a minimal markable() plugin call to your existing vite.config.*, and appends .markable/ to .gitignore. The vite config edit is a byte-range insertion that preserves your formatting, comments, and plugin order; complex configs are never overwritten — the CLI prints a manual snippet instead.

// markable.config.ts (generated)
import { defineMarkableConfig } from "@f12o/markable/config";

export default defineMarkableConfig({
  devOnly: true,
  mode: "review",
  commentsFile: ".markable/comments.json",
  endpoint: "/__markable/comments",
});

With devOnly: true, Markable runs under vite dev and is excluded from vite build. Running init again is idempotent. Two more commands are available:

markable doctor   # report the current integration status
markable remove   # undo the CLI-owned edits (only when still unmodified)

The devOnly option is also available directly on the plugin (markable({ devOnly: true })), which sets Vite's apply: "serve".

UI locale

The UI injected by Markable supports English and Japanese. English is the default locale.

markable({ locale: "en" }); // English, default
markable({ locale: "ja" }); // Japanese

Localized strings include the floating launcher, composer, tabs, placeholders, target summaries, recent submission list, copy results, and submission status. The selected locale is also recorded as context.markableLocale in submitted annotations.

Vite+ compatibility

Vite+ is expected to run normal Vite plugins when it loads a Vite-compatible config. markable is a standard Vite plugin and does not expose a Vite+-specific API.

Initial compatibility target:

vp dev
vp build

The plugin currently uses standard Vite hooks:

transformIndexHtml
configureServer
resolveId
load

Core idea

artifact
  -> mark target
  -> annotate / comment / feedback
  -> structured event
  -> ticket / JSON / agent input
  -> rewrite / resolve / follow-up

markable does not own your UI. The core is headless. DOM and Vite integrations provide capture and injection only.

Current status

Initial scaffold.

Inspiration

The production feedback selection UX is inspired by u-ichi/reviewable-html-workbench, particularly its clear review state, contextual highlighting, and visually anchored comments. markable generalizes that interaction pattern for production web app feedback while keeping the core package headless.

Demo app

A lightweight Vue 3 + Vite Todo demo lives in examples/vite-todo. It is intentionally small so the markable integration is easy to inspect:

pnpm install
pnpm build
pnpm --filter @f12o/markable-vite-todo-demo dev

The demo config uses the package Vite plugin directly:

markable({
  mode: "auto",
  commentsFile: ".markable/comments.json",
  endpoint: "/__markable/comments",
});

In Vite development mode, mode: "auto" resolves to review mode. Use the floating Mark button to open a composer. Practical page elements highlight automatically as you move over them; click a highlighted element to attach the mark to that DOM element, drag an empty page area to attach it to a rectangular screen region, or save without choosing a target to attach it to the current page. The dev server endpoint writes structured annotation JSON to .markable/comments.json inside the demo app.

In production builds, mode: "auto" resolves to feedback mode. The floating Feedback button opens a user-facing feedback panel with Feedback and Question tabs, the same automatic element and box targeting behavior, and an in-session list of recent submissions. Captured context includes URL, title, viewport, user agent, the active tab intent, UI locale, and the optional selected element or rectangle.

shadcn-admin example

A larger React dashboard example lives in examples/shadcn-admin. It vendors satnaing/shadcn-admin at commit e16c87f213a5ba5e45964e9b67c792105ec74d26 and adds the markable Vite plugin so the overlay can be exercised against a realistic shadcn UI:

pnpm install
pnpm --filter @f12o/markable-shadcn-admin-demo dev
pnpm --filter @f12o/markable-shadcn-admin-demo build

The example config uses the same local development endpoint as the Todo demo:

markable({
  mode: "auto",
  commentsFile: ".markable/comments.json",
  endpoint: "/__markable/comments",
});

In local development, submitted marks are persisted to examples/shadcn-admin/.markable/comments.json.

GitHub Pages deployment

The Deploy demo to GitHub Pages workflow builds the package, builds the examples, generates an example index, and publishes the static output to GitHub Pages at:

https://f4ah6o.github.io/markable/
https://f4ah6o.github.io/markable/vue-todo/
https://f4ah6o.github.io/markable/shadcn-admin/

The index page is generated from examples/examples.json by scripts/build-pages-index.mjs, so new examples can be added to the listing by updating the manifest.

GitHub Pages is static hosting, so it can demonstrate the example apps and injected feedback overlay but cannot persist POSTed feedback to /.markable or /.json files. For public static deployments, treat submitted feedback as local/session-only unless a remote endpoint is configured.

Cloudflare Workers follow-up

For persistent production feedback, point the markable endpoint at a Worker route such as /api/feedback:

browser
  -> markable feedback UI
  -> /api/feedback
  -> Cloudflare Worker
  -> D1, KV, R2, GitHub Issues, a queue, or a webhook

That follow-up can keep the static GitHub Pages demo lightweight while adding real storage, notification, or issue creation behind a Worker-backed endpoint.