This project uses tsdown to generate CommonJS, ESM, and TypeScript declaration files from a single TypeScript codebase.
dist/
├── *.js # ES Modules (for import statements)
├── *.cjs # CommonJS modules (for Node.js require())
├── *.d.ts # TypeScript declarations for ESM
├── *.d.cts # TypeScript declarations for CommonJS
└── [subdirs]/ # Subpath exports (accounts, chains, query, etc.)
All build outputs are organized directly in dist/ with different file extensions to distinguish formats.
The build uses tsdown configured in tsdown.config.ts:
- Single pass build - Generates both ESM and CommonJS formats simultaneously
- Type declarations - Automatically generates
.d.ts(ESM) and.d.cts(CommonJS) files - Source maps - Includes
.js.mapand.d.ts.mapfiles for debugging - Platform neutral - Supports both browser and Node.js environments
- External dependencies - Properly handles external packages like
brotli-wasm
# Build all outputs (ESM + CJS + Types)
bun run build
# Type-check without emitting files
bun run type-check
# Package for distribution
bun run package
bun run package:test # Creates arkiv-network-sdk-latest.tgz for testingThe library supports multiple module formats via package.json exports with conditional exports:
{
"main": "./dist/index.cjs", // CommonJS entry (legacy)
"module": "./dist/index.js", // ESM entry (legacy)
"types": "./dist/index.d.cts", // TypeScript types (legacy)
"exports": {
".": {
"bun": "./src/index.ts", // Bun uses TypeScript source
"import": "./dist/index.js", // Node.js ESM
"require": "./dist/index.cjs" // Node.js CommonJS
}
}
}All major subpaths are exported:
.- Main entry./chains- Chain configurations./accounts- Account utilities./utils- Utility functions./query- Query builder./types- Type definitions
Each export provides 3 resolution paths:
bun- TypeScript source files fromsrc/*.ts(for Bun runtime or experimental feature of Node)import- ES Modules fromdist/*.jswith types fromdist/*.d.ts(for Node.js ESM)require- CommonJS fromdist/*.cjswith types fromdist/*.d.cts(for Node.js CommonJS)
Bun (TypeScript native):
import { createPublicClient } from '@arkiv-network/sdk'; // Uses src/*.ts directlyBun automatically resolves to the bun export condition, which points to TypeScript source files. No transpilation needed!
Node.js (ESM):
import { createPublicClient } from '@arkiv-network/sdk'; // Uses dist/*.jsNode.js (CommonJS):
const { createPublicClient } = require('@arkiv-network/sdk'); // Uses dist/*.cjsThis configuration provides:
- Maximum compatibility - Supports CJS, ESM, and TypeScript-native runtimes (Bun)
- Single build tool - One command generates all formats and types
- Zero transpilation for Bun - Bun can use TypeScript source files directly from the package
- Tree-shaking - ESM allows bundlers to optimize imports
- Type safety - Full TypeScript support with declaration maps for both formats
- Source maps - Easy debugging with
.js.mapand.d.ts.mapfiles - Clean structure - All build outputs organized in
dist/with clear file extensions - Fast builds - Efficient single-pass compilation
When working on the library:
- Source files live in
src/ - Run
bun run buildto compile with tsdown - Outputs go to
dist/(gitignored) - Package includes both
src/anddist/directories:src/- TypeScript source files for Bun runtime (viabunexport condition)dist/- Compiled ESM, CJS, and type declarations for Node.js
The build configuration is defined in tsdown.config.ts and handles:
- Multiple entry points (
src/**/index.ts) - ESM and CommonJS output formats
- Type declaration generation
- External dependency handling
- Source map generation
Note: The src/ folder is included in the published package (via package.json files field) to enable Bun's zero-transpilation workflow, where Bun can directly import and execute TypeScript files.