app.use(redPen()) injects a review-notes overlay into every HTML page your Express app serves. Pin notes to elements while you build; they persist to an append-only log in your repo, right next to the code they are about.
CommonJS, zero runtime deps, and it switches itself off in production, and off-machine either way.
It behaves like every middleware you already use: one require, one app.use, no config required.
Grab it from GitHub, a single CommonJS module with zero runtime dependencies. No build step of its own.
app.use(redPen()) before your routes. It only injects into HTML responses, and only outside production.
Every page your app serves gets the overlay. Click an element, leave the note, keep moving.
Notes persist to .redpen/notes.jsonl, an append-only log. It travels with the repo, merges cleanly across branches, and never ships to prod.
In a file in your repo, on the routes they are about, instead of a SaaS board three tabs away.
An append-only log holds every note, shipped with a merge=union rule. Commit it, and two branches of notes merge instead of clobbering each other.
When NODE_ENV is production the middleware becomes a no-op pass-through. Nothing injected, nothing served.
A built-in notes view aggregates every note across every route, with numbered pins, locate and filters.
Four note types, three statuses, low/normal/high priority, and replies threaded under the note in the overlay. Ctrl or Cmd with Enter submits; Escape cancels a pin.
Your notes file is a machine-readable queue. Point an AI coding agent at it and let it work the list.
It is a plain (req, res, next). Nothing lands in your lockfile and nothing phones home.
If you have several services or side projects on the go, each app sends its notes to the Red Pen Hub, one local board that sees all of them.
The Hub is a small local Express app itself, running on your machine. Nothing in it counts projects, so the number of apps you connect is up to your disk.
The middleware is free in full, permanently: injection, pinning, the repository, the notes file. There is no paid tier above it.
Red Pen is running on this page too. Try the red button in the corner.
Not unless you force it to, and there are two gates rather than one. With NODE_ENV=production the middleware is a pass-through no-op that injects nothing and registers no routes. Separately it answers only connections from this machine, checked against the connection's actual remote address; pass localOnly: false when you deliberately want someone else on the network in.
Nothing. Zero runtime dependencies; Express itself is only a devDependency for its own tests. It is a plain (req, res, next) function.
In .redpen/notes.jsonl at your project root, one JSON record per line. Commit it: that is what the shipped merge=union rule is for, and it is how a second person gets in. A derived notes.json snapshot sits beside it for tools that read notes off disk, and it is gitignored for you. Either file is plain text that is yours.
It injects into any HTML response your app serves: EJS, Pug, plain res.send, whatever. For a fully client-rendered SPA served elsewhere, use the drop-in script surface instead; same notes model.
Same overlay, same notes model, different host. WordPress gets a plugin, static sites get a script tag, Express gets middleware. Learn it once, use it everywhere, and the Hub can aggregate all of them. Screenshots and custom note types ship on WordPress and the drop-in script; they are not in this port yet.