Part 3 — Library ecosystem
1. Using JavaScript libraries directly
Any npm package works at runtime. Types from .d.ts files are not consumed as-is — treat untrusted values as dynamic and narrow:
import { readFileSync } from "node:fs"
function loadJson(path: string): Result<dynamic, string> {
try {
const text: string = readFileSync(path, "utf8")
const value: dynamic = JSON.parse(text)
return Ok(value)
} catch (e) {
return Err("read failed")
}
}For repeated shapes, add validators (manual if chains, or @superjs/stdlib schema helpers when available).
2. @superjs/types-* wrappers
Wave-1 typed bindings cover 30 popular packages. Install the wrapper alongside the runtime package:
npm install fastify @superjs/types-fastifyimport { fastify } from "fastify"
const app = fastify()
app.get("/health", async () => ({ ok: true }))Coverage and status per package: Compatibility matrix (generated from each wrapper's STATUS.md).
Wave-1 backends and data
fastify, express, hono, koa, connect, pg, mysql2, prisma, mongoose, redis
Utilities and auth
zod, joi, axios, node-fetch, undici, pino, winston, dotenv, jsonwebtoken, passport
Cloud and testing
aws-sdk-core, cloudflare-workers, bullmq, multer, supertest
Frontend and test runners
react, nextjs, vite, vitest, jest
When no wrapper exists, use dynamic at the import boundary and file an issue or contribute a wrapper under superjs/libs/types-*.
3. superjs migrate from-prototype
Early SuperJS prototypes used deep relative imports into prototype/ packages. The CLI rewrites those to @superjs/* workspace packages and emits a report:
# Preview changes
superjs migrate from-prototype ./src --dry-run
# Write migrated tree + MIGRATION_REPORT.md
superjs migrate from-prototype ./src --out ./migratedThis does not convert TypeScript syntax — run it after .sjs files exist and you need import-path cleanup (WS-A5).
Assisted TS → SJS migration (separate subcommand):
superjs migrate from-ts ./src4. Gradual migration strategy
Recommended order for a brownfield TypeScript repo:
- Pick a leaf module — no decorators, few dependencies (index walkthrough).
- Rename
.ts→.sjsone file at a time; fix parse errors first. - Clear banned constructs —
any,enum,namespace, intersections, conditional types (Part 1). - Replace
anywithdynamic+ validation at module boundaries. - Convert
enumto sum types; replaceswitchwithmatch. - Replace throw-based control flow with
Result+matchwhere failures are expected (Part 2). - Add wrappers — swap
dynamicfacades for@superjs/types-*as they land on the compat matrix. - Wire CI —
superjs checkonsrc/**/*.sjsin your pipeline.
Keep TypeScript files until their dependency cone is migrated — mixed .ts / .sjs repos are fine during transition if your bundler resolves both.
Related
- Why SuperJS — when migration is worth the cost
- CLI reference —
check,build,migrate - mvb-fastify example — end-to-end backend sample