Modernizing Steem.js — Day 6: Cross-Runtime Verification & 100% Docs

in Steem Devyesterday

Part 6 of my 7-part Steem.js modernization series. The code is modern, typed, and byte-compatible. But "it works on my machine" isn't good enough for a library that claims to run everywhere. Today: proving it runs everywhere, and documenting all of it.

Bundle hygiene: trust, but verify

The whole isomorphic promise rests on one fact: the shipped bundle must contain no Node built-ins, no Buffer, no process, no dynamic require. So I audited the built output directly for forbidden tokens:

  • ❌ no require('crypto') / bare Node built-ins
  • ❌ no top-level Buffer / process / window
  • ✅ only externals: @noble/*, @scure/base, bs58, retry (+ optional ws)

Buffer is injected from a pure-JS polyfill at build time; assert / events / debug are aliased to tiny in-repo shims via a tsup onResolve plugin. Nothing Node-specific leaks into the ESM/edge output.

A byte-exact, cross-runtime smoke test

scripts/smoke.mjs loads the built bundle (not the source) and runs the critical path on multiple runtimes, asserting byte-exact results:

// scripts/smoke.mjs — runs under both Node and Deno
import steem from '../dist/index.mjs';

const wif = steem.auth.toWif('alice', 'password', 'active');
const sig = steem.auth.signTransaction(tx, [wif]);
const memo = steem.memo.encode(/* … */);

assertEqual(wif, EXPECTED_WIF);   // identical on Node + Deno
assertEqual(sig, EXPECTED_SIG);

Running it under both node and deno run confirms the same keys, signatures, and memos come out on completely different runtimes.

CI matrix

.github/workflows/build.yml now builds and tests across a matrix:

  • Node 18, 20, 22import (ESM) and require (CJS), full Vitest suite
  • Deno — a dedicated job running the smoke script

Every push is verified on every supported runtime. The old Docker / circle.yml path is gone.

100% generated documentation

A modern library deserves documentation that can't go stale. The docs site at blazeapps007.github.io/steem-js is a Jekyll + just-the-docs site, and its reference pages are generated from the same descriptors that drive the runtime:

  • scripts/gen-docs.js reads methods.js / operations.js and emits the complete reference — 108 API methods + 67 broadcast entries, each with signature, required roles, RPC name, parameters, an example, and the return shape.
  • Per-method prose lives in docs/_details/*.md and is spliced in, so coverage can never drift below 100%.
  • Every guide and reference page now leads with modern ESM usage:
import steem from '@steemit/steem-js';
// CommonJS: const steem = require('@steemit/steem-js');

If a method is added to the descriptor but lacks a detail block, the generator tells you. Docs stay honest by construction.

Where that leaves us

Six phases in, Steem.js is:

  • ✅ byte-for-byte compatible (golden vectors green throughout)
  • ✅ running on Node 18/20/22, browsers, edge, and Deno — verified in CI
  • ✅ typed, tree-shakeable, dependency-light
  • ✅ 100% documented from source

Tomorrow, the finale: the official release post tying it all together.

Links

Support Secure Steem Development

If you value proactive engineering, UX polish, and performance optimizations for the STEEM ecosystem, please consider supporting my witness: blaze.apps

🗳️ Vote Here:
Vote for blaze.apps Witness

Sort:  
Loading...