dsteem Modernization Plan -Final Phase -7
Day 7: the short, satisfying one. typedoc 0.13 → 0.28 (an absurd 15-minor-version jump), drop the ugly
sedpost-processing the old Makefile needed to fix absolute paths in the generated HTML, and replace it all with a four-linetypedoc.json. The API documentation regenerates cleanly with the modern layout. With this done, the modernization is feature-complete — every architectural change from the Phase 0 plan is in. All that's left is the release ceremony next week.

- Day 1 — Phase 0: dsteem Modernization Plan
- Day 2 — Phase 1: CI Plumbing on GitHub Actions
- Day 3 — Phase 2: Retiring tslint, Adopting ESLint 9
- Day 4 — Phase 3: TypeScript 3.1 → 5.6 + Strict Mode
- Day 5 — Phase 4: The @noble Crypto Swap
- Day 6 — Phase 5: tsup, Dual ESM/CJS, and 606 Packages Deleted
- Day 7 — Phase 6: Mocha 11, c8 Coverage, and Playwright Browser Tests
- Today — Phase 7: typedoc 0.13 → 0.28, and What's Left for Release (you are here)
- Next week — Phase 8: Cleanup, README refresh,
v0.12.0release, and the npm publish
Where typedoc Was Stuck
[email protected] was the version pinned in v0.11.3 from 2018. The current version is 0.28.19. Some of the things that changed between those two:
| Era | typedoc behavior |
|---|---|
| 0.13 (2018) | --mode file, baked absolute filesystem paths into output HTML, required CLI flags for everything |
| 0.20 (2021) | Added typedoc.json config file support |
| 0.22 (2021) | Removed --mode, switched to "entry point" model |
| 0.24 (2023) | Switched to TypeScript's own type-resolution machinery |
| 0.25 (2023) | Auto-detects tsconfig.json instead of needing --target ES6 --mode file |
| 0.28 (2025) | Modern responsive theme, proper search index, no absolute-path leakage |
The old Makefile invocation looked like this:
docs: $(SRC_FILES) node_modules
typedoc --gitRevision master --target ES6 --mode file --out docs src
find docs -name "*.html" | xargs sed -i '' 's~$(shell pwd)~.~g'
echo "Served at <https://jnordberg.github.io/dsteem/>" > docs/README.md
touch docs
That sed -i '' is BSD syntax (macOS-only) — GNU sed (Linux/Windows) accepts it as a filename argument and writes the substitution-result to a file literally named ''. So the old make docs target only worked on macOS, and the only reason it existed at all was to scrub the absolute path /Users/jnordberg/dsteem out of the generated HTML.
he New Setup
typedoc.json:
{
"$schema": "https://typedoc.org/schema.json",
"entryPoints": ["src/index.ts"],
"out": "docs",
"readme": "README.md",
"tsconfig": "tsconfig.json",
"excludePrivate": true,
"excludeInternal": true,
"gitRevision": "master"
}
package.json script:
+ "build:docs": "typedoc",
That's it. Modern typedoc:
- Auto-discovers the entry point and resolves the full export graph from
src/index.ts - Uses the project's existing
tsconfig.jsonfor type resolution (no duplicate config) - Doesn't bake absolute paths into the output (the
sedpost-processing is gone) - Generates a search index, a sidebar, and a responsive theme by default
- Hides
privateand@internal-tagged members from public docs automatically
The whole docs build is now npm run build:docs. No Makefile. No sed. Works on every platform.
The Phase 7 Result
$ rm -rf docs && npm run build:docs
[warning] BroadcastAPI, defined in dsteem/src/helpers/broadcast.ts, is referenced
by Client.broadcast but not included in the documentation
[warning] Manabar, defined in dsteem/src/steem/rc.ts, is referenced by
RCAPI.calculateRCMana but not included in the documentation
[info] html generated at ./docs
[warning] Found 0 errors and 10 warnings
$ ls docs/*.html | head -5
docs/hierarchy.html
docs/index.html
docs/modules.html
- 0 errors
- 10 warnings — all about transitively-referenced types that aren't directly exported from
src/index.ts. They're internal-shape types (BroadcastAPI,Manabar,RCAccount) accessed viaClient.broadcast/Client.rc. Adding them to the entry-point export list would fix the warnings; deferring for now since they're warnings, not blockers. - Generated HTML in
docs/with the new theme — works directly on GitHub Pages.
🧠 The Meta-Lesson
Doc-gen tools age in a peculiar way: they often work just well enough that nobody notices they're broken until a fresh person tries to regenerate the site on a clean machine and discovers sed writes a file literally called ''. The cost of keeping them current is low (an annual npm install --save-dev typedoc@latest and a rerun); the cost of skipping it is the slow accumulation of platform-specific hacks like that find ... | xargs sed -i '' workaround.
The pattern generalizes. Every dev tool that ships HTML/markdown output deserves the same yearly check: does it still work on Linux + Mac + Windows? Does its config format still match the docs? Is its default theme still readable?
If you can't say yes to all three, swap it out before the workaround crust gets any thicker.
The Modernization Is Feature-Complete
Phases 0 through 7 have shipped. Here's the full end-state of the project today:
Production dependency tree (5 packages)
@noble/curves ← secp256k1 ECDSA (audited, pure-JS)
@noble/hashes ← SHA256, RIPEMD160 (audited, pure-JS)
bs58 ← Base58 encoding (for WIF)
bytebuffer ← binary serialization
verror ← error wrapping
Test + build pipeline (npm scripts only)
npm run lint ← ESLint 9 flat config (0 errors)
npm run build ← tsup → dist/index.{cjs,mjs,d.ts} + dsteem.browser.global.js
npm test ← mocha 11, 50 passing, 438ms
npm run coverage ← c8 with 70% line-coverage gate (currently 73.22%)
npm run test:browser ← Playwright headless smoke against the bundled artifact
npm run build:docs ← typedoc 0.28
npm run prepublishOnly← lint + build + test in one
Final checklist (all green)
| Check | Result |
|---|---|
npm run lint | 0 errors, 43 warnings (unused-vars only) |
npm run build | dist/index.{cjs,mjs,d.ts} + dist/dsteem.browser.global.js |
npm test | 50 passing |
npm run coverage | 73.22% line coverage — passes 70% gate |
npm run test:browser | Playwright chromium: smoke passes |
npm run build:docs | docs/index.html regenerated |
Live api.steemit.com | head block 106461966 ✓ |
Live api.moecki.online | head block 106461967 ✓ |
npm audit --omit=dev | 0 vulnerabilities in production deps |
npm pack --dry-run | 11 files, 792.7 KB tarball |
| Browser bundle size | 351 KB (down from 782 KB — -55%) |
| Public API surface | byte-compatible with v0.11.x (golden vectors confirm) |
| Node version supported | >=22.0.0 |
What's Left for Phase 8 (Next Week)
Phase 8 is the release ceremony, not an engineering phase. The work left:
- Update
README.mdwith the new install instructions, CDN URLs, Node 22 minimum, and the dual-RPC documentation - Update
CLAUDE.mdto replace Makefile references with the newnpm run *scripts (done in passing as part of the Phase 5/6 work — needs a final review) - Bump
package.jsonto"version": "0.12.0"(done in passing — Phase 8 will verify) - Run
npm publish --dry-runand visually inspect the file list - Tag
v0.12.0, push, let CI build, confirm green npm publish
Plus the things I deliberately deferred for the release post:
- Final security retrospective: what the threat model looked like at v0.11.3 vs. v0.12.0
- Migration guide for anyone with
[email protected]inpackage.json(spoiler: it'snpm install dsteem@^0.12) - A "thanks" section to the upstream maintainers, the @noble crypto ecosystem, and everyone who pinged me with questions during the week
The Phase 8 post lands next week, after the npm publish. Until then, the work is on the blazeapps007/dsteem fork — pull it, try it, file issues.
🧠 The Whole-Week Meta-Lesson
Modernizing a multi-year-stale library is not glamorous. There's no exciting new feature to announce, no benchmark to brag about, no architecture diagram that makes everyone nod sagely. It's a week of replacing one tool with another and then making sure nothing broke.
But that week of work matters for everyone who builds on Steem. Every developer who picks up [email protected] will:
- Skip the
node-gyprabbit hole that bit them at[email protected] - Get TypeScript IntelliSense that actually works (proper
.d.tsinstead of one giant declaration file) - Use the package in modern bundlers (Vite, esbuild, webpack 5) without
browserfield hacks - Avoid the high-severity CVE that's sitting in their
node_modulesright now - Run the package on Node 22 / Node 24 / Bun / Deno without compatibility shims
That's the value. Not novelty — removed friction. And friction removed is friction that won't keep nudging some future developer toward abandoning Steem dev because "the SDK is annoying."
Boring modernization work is the unsexy half of OSS sustainability. I hope this week of posts makes the why of that work visible to people who use the result without ever seeing the code.
🙏 Halfway Thank-You
This is post 7 of 8. The release post is next week. Thank you to everyone who's been reading the series, vote-boosting the posts, and following along on GitHub. The witness votes since the series started have been genuinely motivating — if you're enjoying the technical depth, please keep them coming for next week's release post too.
🤝 How You Can Help
- 🔍 Watch the repo:
blazeapps007/dsteem - 🧪 Test the pre-release: clone the repo,
npm install,npm test, trynpm packandnpm install ./dsteem-0.12.0.tgzin one of your existing projects. The whole point of API compatibility is that nothing should break. - 🐛 File issues: anything that misbehaves between v0.11.3 and the upcoming v0.12.0 is a P0. API compatibility is non-negotiable.
- 💬 Comment: questions about specific phase choices help shape the rest of the series — and the release post next week is a great place to ask "but why didn't you do X?"
This work was developed with Claude AI assistance. All technical decisions reflect Steem ecosystem needs and the hard requirement of zero breaking .
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
Disclaimer: This post describes work in progress on the blazeapps007/dsteem fork. The release will be tagged v0.12.0 after Phase 8 ships next week.