Choose between porting a library and reimplementing it
Decide how a library reaches a second language by running one shared case against every candidate, and record which reimplementations already disagree with it.
How-to › Section 17
For library maintainers: porting with parity, one test corpus for every port, plugin systems that work the same everywhere, and the small utilities that recur.
13 guides in 4 topics. Every guide compares its approaches and shows the output its commands printed.
The canonical-plus-ports pattern (a TypeScript canonical, ports kept at parity: struct in 23 languages, plugin in 17, sekreto in 12, aontu, jostraca and apidef in Go), byte-identical output checks, idiom versus parity trade-offs, first-tier versus second-tier polish, release cadence across ports; compared with transpiling, sharing one implementation through WASM (wasm-bindgen, Extism) or FFI, and independent reimplementations (jq clones, lodash ports).
Decide how a library reaches a second language by running one shared case against every candidate, and record which reimplementations already disagree with it.
Link a canonical library and its npm, PyPI, Go, and Rust ports to one version, tag the Go module where Go looks, and check every artifact before anything publishes.
Compile one Rust core to WebAssembly, call it from Node, Python, and Go through thin wrappers, and measure what the boundary costs before you retire a port.
One spec, many languages: JSON test corpora authored once and run by a per-language runner, omni (24 languages, zero runtime dependencies), the corpora behind struct, jostraca, aontu and the sdkgen .sdk/test/feature files, compared with Cucumber and Gherkin, JSON fixtures with hand-written runners, property-based testing (fast-check, Hypothesis, gopter) and Pact; corpus design, golden files, marking a case as expected to differ in one language, reporting parity gaps.
Test each port's own logic with a shared corpus and its HTTP calls with Pact, and know which bug each one cannot see.
Fix the fields every case carries before you write a second runner: a stable id, a doc line, one input, one expectation, and sentinels for what JSON cannot say.
Extending an application or library without forking it: @voxgig/plugin (definition, instance, declared, loaded and live lifecycle, reversible activation, 17 languages), the ESLint, Vite and Rollup plugin models, pluggy, the Go plugin package and hashicorp/go-plugin, OSGi, Ruby gem hooks, sandboxing third-party plugins, and sdkgen packages as an applied example.
Find plugins because they are installed, with Python entry points, a gem file convention or a Node prefix scan, and refuse to start when two claim one name.
Declare one plugin definition under two refs, each with its own options, state, and connection, and reconfigure one without touching the other.
Drive one plugin from registration through activation to deactivation inside a test, and assert what it released, without touching a real network.
The small libraries that recur in integration code, each against its mainstream peer: nid against uuid, nanoid and ulid (for idempotency keys and request ids); eraro against VError, Error.cause and Error subclasses; gex against minimatch and picomatch; inks against template literals and Mustache; ordu against p-series and a task queue; norma for argument normalization; and when to write your own versus depend.
Match a call's arguments against a pattern of names and types, so one function accepts several shapes without a chain of typeof checks.
Check each small dependency for a built-in, a risky edge, a one-line rewrite, or code you can copy, and test the replacement before the package goes.
Take four numbers for a one-purpose package, install size, bundle bytes, parse cost, and maintenance, and set them beside a copy and a version of your own.
Publish one zero-dependency function so it imports cleanly in Node, Deno, Bun, and a bundler, and prove it against the packed tarball rather than the source tree.
Wrap a failed fetch or query in a domain error with the cause option, and keep the original error, its stack, and its code reachable.
Retries, timeouts, pagination and auth are the same problems in every client. Voxgig generates them from your OpenAPI description, in 23 languages, from one model.
Since 2018, Richard Rodger has talked with developer advocates, event organizers, and the people who build developer-facing companies about the specifics of the work.