Skip to content

feat: migrate build pipeline from tsc to tsdown#369

Open
chybisov wants to merge 2 commits intomainfrom
feat/tsdown-migration
Open

feat: migrate build pipeline from tsc to tsdown#369
chybisov wants to merge 2 commits intomainfrom
feat/tsdown-migration

Conversation

@chybisov
Copy link
Member

@chybisov chybisov commented Mar 20, 2026

Migrate build pipeline from tsc to tsdown

Closes EMB-317

TL;DR

Replace tsc --build with tsdown (powered by Rolldown/OXC in Rust) across all 5 SDK packages. Build time drops from ~13s to ~650ms (~20x faster).

DESCRIPTION

Before vs After

Metric Before (tsc) After (tsdown) Improvement
Full build time ~13s ~650ms ~20x faster
Build passes per package 3 serial (CJS, ESM, types) 2 parallel (ESM+DTS, CJS) Fewer passes
Package parallelism SDK first, then 4 providers All 5 fully parallel No dependency ordering
Type checking Coupled with build Separate check:types step Build never fails on type errors
Per-package (sdk) ~8s ~650ms ~12x faster
Per-package (provider) ~3s ~450ms ~7x faster

What changed

Root:

  • Added tsdown as root devDependency
  • Added isolatedDeclarations: true to root tsconfig (enables OXC-powered .d.ts generation)
  • Simplified root build script to run all packages in parallel (no SDK-first ordering needed)
  • Added scripts/build.js — wraps tsdown with per-package timing output

Per package (5 packages):

  • Created tsdown.config.ts with ESM+DTS and CJS configs (ESM-only for sui)
  • Replaced build:cjs / build:esm / build:types / build:clean with single tsdown call
  • .d.ts files now live alongside ESM in dist/esm/ (no separate dist/types/)
  • Updated types/typings/exports fields to point to dist/esm/index.d.ts
  • watch updated to tsdown --watch
  • check:types remains tsc --noEmit (no faster alternative exists yet)

Source files (~30 files):

  • Added explicit return type annotations to all exported functions/constants (required by isolatedDeclarations)
  • parseAbi results in abi.ts typed as Abi (viem's narrow generics incompatible with isolated declarations); downstream multicall results use as casts
  • Removed dead return this from HTTPError.buildAdditionalDetails
  • Fixed pre-existing TS2339 in parseEthereumErrors.ts

Why tsdown?

  • Rust-powered: Uses Rolldown (Rust bundler) + OXC (Rust TypeScript toolchain) instead of the JavaScript-based tsc
  • Parallel by design: ESM, CJS, and DTS builds run concurrently within each package
  • isolatedDeclarations: Each file's .d.ts is generated independently without cross-file type resolution, enabling massive parallelism
  • Drop-in: Output is semantically equivalent to tsc — same file structure, same module format, same declaration files

STEPS TO TEST

# Clean build
pnpm clean && pnpm build

# Verify outputs exist
ls packages/sdk/dist/esm/index.js packages/sdk/dist/cjs/index.js packages/sdk/dist/esm/index.d.ts

# Type checking (separate from build)
pnpm check:types

# Lint
pnpm check

# Tests
pnpm test:unit

EXPECTED RESULTS

  • All 5 packages build successfully with timing output
  • dist/esm/ contains .js, .js.map, .d.ts, .d.ts.map files
  • dist/cjs/ contains .js, .js.map files (not for sui)
  • All 284 unit tests pass
  • pnpm check (biome) passes
  • pnpm check:types passes

CHECKLIST

  • Performed a self-review of my code
  • Added comments to the code for better readability
  • Added tests that cover the new functionality
  • Made sure that existing tests are still passing.

chybisov and others added 2 commits March 20, 2026 15:12
Replace tsc --build with tsdown (Rolldown/OXC) for all 5 SDK packages.

- Add tsdown as root devDependency with per-package configs
- Enable isolatedDeclarations for OXC-powered .d.ts generation
- Add explicit return types to all exported functions/constants
- Build all packages fully in parallel (no dependency ordering)
- DTS lives alongside ESM in dist/esm/ (no separate dist/types/)
- Add scripts/build.js for per-package timing output

Build time: ~13s → ~1.9s (~7x faster)

Closes EMB-317

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
"type": "module",
"scripts": {
"build": "pnpm --filter @lifi/sdk build && pnpm -r --parallel --filter './packages/**' --filter '!@lifi/sdk' build",
"build": "pnpm -r --parallel --filter './packages/**' build",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SDK provider packages rely on core SDK package - shouldn't we still build core SDK first, or it's handled anyhow differently now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants