All projects open-source/ · reviewed from the outside

Open source: code reviewed by people who don't know me

Period
August 2026 · ongoing
Role
external contributor
Projects
undici, lexical, axios, svelte, pino, isomorphic-git, next.js, storybook and others
Measured on

What got in and what is in the queue

In August 2026 I started sending fixes to projects that are not mine. Not as an exercise: picking real defects, writing the test that fails without the fix, and sending it through whatever process each project asks for, which in some cases means opening an issue first and waiting for a reply before writing a line.

The two tables below are the state of everything, read from the GitHub API and rewritten by a script on this site. Merged is merged. In review can turn into anything, including nothing. Merged and in review never appear added together, because that sum would be this page's first easy lie.

One of them closes a loop. BetonQuest is a quest plugin for Minecraft servers, and the first thing I ever tried to program, at ten years old, was a Minecraft mod that came to nothing. This time the code made it in.

215pull requests opened
150+already merged
44projects that accepted
68projects reached

Where the code landed

The strongest of the 44 projects that have merged a fix of mine. Count is not the only criterion: pnpm with one pull request says more to a reader than a project with two that nobody recognizes. The full list of 68, rejected and superseded included, opens at the end of the section.

ProjectWhat it isMergedIn review
warrena control plane for coding agents running in isolation290
isomorphic-gitgit written in JavaScript, running in the browser160
orvalgenerates a typed client from OpenAPI130
lexicalMeta's text editor framework100
kaneoopen source project management50
postala terminal coding agent written in Python40
zigbee2mqtta bridge from Zigbee devices to MQTT, with no proprietary hub40
urwida terminal user interface library for Python40
redocly-clilints, bundles and publishes OpenAPI descriptions21
pnpma package manager that doesn't duplicate dependencies on disk20
pinothe logger underneath Fastify11
MathCATturns math into speech and braille for screen readers10
luigia micro frontend framework, maintained by SAP10
Open the full list: 68 projects, one by one

Projects that accepted

ProjectWhat it isMergedIn reviewRejectedSuperseded
warrena control plane for coding agents running in isolation29000
isomorphic-gitgit written in JavaScript, running in the browser16000
RustPythona Python interpreter written in Rust, which also runs in WebAssembly15000
orvalgenerates a typed client from OpenAPI13000
lexicalMeta's text editor framework10000
coreutilsls, cp and the rest of the GNU utilities rewritten in Rust6000
compiler-explorerruns compilers in the browser and shows the assembly they emit5300
mongoosethe modelling layer almost every Node app with MongoDB uses5000
kaneoopen source project management5000
skillfilefinds and installs agent skills, and tracks which version is where4100
postala terminal coding agent written in Python4000
zigbee2mqtta bridge from Zigbee devices to MQTT, with no proprietary hub4000
urwida terminal user interface library for Python4000
CodeceptJSend-to-end testing framework3000
hls.jsplays HLS streaming in the browser, with no plugin3000
undicithe HTTP client inside Node's fetch2305
redocly-clilints, bundles and publishes OpenAPI descriptions2100
brusha bash and POSIX compatible shell, written in Rust2100
gitlab-ci-localruns GitLab CI pipelines on your own machine2000
loopxa state kernel for long-running AI agent teams2000
markedturns Markdown into HTML, and is the converter many tools embed2000
pokeroguea browser RPG with Pokémon battles and a map that changes every run2000
pnpma package manager that doesn't duplicate dependencies on disk2000
react-jsonschema-formbuilds a React form out of a JSON Schema2000
syftreads a container image and lists everything inside it1100
grafanathe observability dashboard almost every company keeps open1100
playwright-skillPlaywright browser automation packaged as an agent skill1100
openeverestautomated database provisioning and management1100
pinothe logger underneath Fastify1100
BetonQuesta quest plugin for Minecraft servers, with dialogue and conditions1000
MathCATturns math into speech and braille for screen readers1000
sigma-rule-deploymentships Sigma detection rules into Grafana Alerting1000
ciso-assistantrisk and compliance management, with ISO 27001 and NIST controls1000
sunsynkreads Deye and Sunsynk solar inverters inside Home Assistant1000
zigbee-herdsman-convertersthe device definitions zigbee2mqtt uses to understand each appliance1000
likec4system architecture written as code and drawn from it1000
luigia micro frontend framework, maintained by SAP1000
herban HTML-aware toolchain for ERB, Rails' template language1010
pyrightthe Python type checker running inside VS Code1000
mlodadata access for AI and ML, plugin-based and with lineage1000
plurshared memory across AI agents1000
blackthe Python code formatter that refuses to be configured1000
semanticagraph infrastructure for agent context1000
webdriveriobrowser and mobile automation for testing1000

In review, rejected and superseded

Rejected and superseded are not the same thing. Rejected means the maintainer closed the pull request. Superseded means I closed it, because the same fix became another pull request in the same project. Adding the two together would say the project told me no where it asked for something else.

ProjectWhat it isIn reviewRejectedSuperseded
payloadheadless CMS on Next.js501
luxondates and time zones in JavaScript, Moment's successor200
axiosthe most used HTTP client in JavaScript100
freebuffa command-line coding agent110
discord.jsthe library most Discord bots are written on top of100
DSpacethe digital repository universities use to publish collections and research100
open-designan open, local-first alternative to Claude Design100
nodethe JavaScript runtime outside the browser100
nxa monorepo build system that only rebuilds what changed100
pygmentshighlights code in hundreds of languages, and is what Sphinx and Jekyll use100
mypyPython's static type checker, maintained alongside the language project100
rollupthe ES module bundler100
storybookbuilds, documents and tests UI components in isolation100
strapiheadless CMS in JavaScript100
supabasemanaged Postgres with API, auth and storage100
sveltethe UI compiler100
next.jsVercel's React framework100
zwave-jsspeaks the Z-Wave protocol from Node, for home automation100
angularGoogle's web application framework010
apollo-clientApollo's GraphQL client010
celerythe background task queue of the Python world001
three.js3D in the browser010
nesta Node backend framework, with the module architecture Angular made popular010
opensrea toolkit for building agents that investigate production incidents010

The same broken key in 10 projects

__proto__ is not a property name like the others. In an object literal, o['__proto__'] = x doesn't store anything: it swaps the object's prototype. And reading o['__proto__'] returns the inherited prototype, not a value someone put there. Every place that builds a dictionary from a string that came from outside has this hole, and the hole is always the same one.

I found the first one in a logger and went after the rest: 15 pull requests across 10 projects: axios, svelte, apollo-client, angular, storybook, next.js, undici (6 in that one alone), pino, orval and lexical. In axios and undici the string is an HTTP header, meaning it comes from whoever is on the other end of the connection. It's not a lab curiosity.

redaction.js see full file ↗
    o[ns].push(nextPath)
    return o
    // The keys here are the first segment of each redact path, so they are the
    // user's strings. On a plain object a path like 'constructor.secret' reads
    // the inherited function, and `o[ns] = o[ns] || []` keeps it.
  }, Object.create(null))

  // the redactor assigned to the format symbol key
  // provides top level redaction for instances where
  // an object is interpolated into the msg string
  // Same reason as the shape above: the keys come from the redact paths, and
  // this object is later indexed with them by `asJson`.
  const result = Object.assign(Object.create(null), {
    [redactFmtSym]: Redact({ paths, censor, serialize, strict, remove })
  })

The comments in this excerpt are mine, and they're in English, because the repository belongs to someone else. It's the same rule in reverse here: the comments on this site are in Portuguese, because I'm the one who maintains it.

The 4 that got merged came together with the test that fails without them. No maintainer asked for it. That's what lets the reviewer say yes without having to trust me.

In undici the maintainer asked me to fold the call sites into a single pull request instead of one per site. I closed the 4 and opened #5688, with the guard in one util instead of four copies of the same function. They sit in the table as superseded, and not as rejected, because they weren't rejected: "the maintainer didn't want it" and "the maintainer wanted it another way" are not the same thing.

16 merged pull requests inside someone else's git

isomorphic-git is real git, written in pure JavaScript, running inside the browser. 16 of my fixes made it in, and another 0 are in the queue. The ones that change behavior are in the list below. The one missing from it is a fix to their continuous integration, which went in with them:

  • core.autocrlf wasn't respected when status hashed the working copy: on Windows, a file nobody had touched showed up as modified.
  • splitLines split a CRLF that happened to land right on the boundary between two stream chunks, and one line became two.
  • .gitignore was applied to files already tracked too, which is exactly the case where git says to ignore the ignore.
  • expanding a ref swept up git's own system files along with it.
  • an annotated tag whose target the prefix filter had removed brought down the entire read.
  • a credential written inside the URL is now read by the WHATWG parser, instead of a regular expression.
  • scp-style syntax with a user other than git wasn't recognized.
  • checkout with filepaths and no ref restored from HEAD instead of from the index, throwing away whatever was staged.
  • with core.symlinks off, git materializes a symlink as a regular file, and the browser fixtures' symlink map came out empty.

There's a joke in the second item on this list. This site already documented a cousin of it before any of these pull requests existed: the check that verifies the security policy's hash normalizes CRLF to LF before hashing, because what actually ships is LF, and anyone who has been bitten by a CRLF boundary before recognizes the mark.

What is still in review

Most of the pull requests are still open, 37 of them, and the page says so instead of rounding up. In some projects the queue is long for a good reason: undici runs inside Node's fetch, and getting it wrong there is expensive for a lot of people.

I have a number for that wait because I measured it. merge-odds samples a project's last hundred closed pull requests and works out what fraction came from an outside author: in the ones it measured, the rate runs from a third to nine tenths. An open pull request is not an accepted pull request, and a high rate describes a hundred people who are not you.

7 were rejected, and they are in the table for the same reason as the rest. On apollo-client I opened the issue first, as their policy asks, tagged the pull request with the robot emoji they require for AI-assisted contributions, and discussed the fix with the maintainer, including to say that one of my three tests was wrong, and why. They closed it as “solution in search of a problem”: they wanted to see the bug hurting someone in production, not just in theory. It is a fair bar, and it holds for the rest of this page too.

The others were shorter. On angular the maintainer replied that a pull request for the same bug was already waiting for review, which is the best reason there is to close mine. On opensre they closed it without a comment, and I do not know why.

And what is mine

This page is what I send to projects that are not mine. The other side, what I publish and other people install, moved out of here and got its own page: what I publish. Two npm packages and two Claude Code plugins, one of them the merge-odds quoted above.