963 markdown files reformatted with the repository's pinned prettier so pnpm format:check covers the folded tree like every other repo file. The formatter's embedded-language pass also normalized code fences (TS semicolons, closed HTML tags in examples, lowercased CSS hex colors, one renumbered list that skipped an index). Alphanumeric token deltas vs the fold commit were audited file-by-file; all are formatter-equivalent markup normalizations plus the four sanitized skills.
6.0 KiB
6.0 KiB
Programmatic Usage
Use tsdown from JavaScript/TypeScript code.
Overview
tsdown can be imported and used programmatically in your Node.js scripts, custom build tools, or automation workflows.
Basic Usage
Simple Build
import { build } from 'tsdown';
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
});
With Options
import { build } from 'tsdown';
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
outDir: 'dist',
dts: true,
minify: true,
sourcemap: true,
clean: true,
});
API Reference
build()
Main function to run a build.
import { build } from 'tsdown';
await build(options);
Parameters:
options- Build configuration object (same as config file)
Returns:
Promise<void>- Resolves when build completes
Throws:
- Build errors if compilation fails
Configuration Object
All config file options are available:
import { build, defineConfig } from 'tsdown';
const config = defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
minify: true,
sourcemap: true,
external: ['react', 'react-dom'],
plugins: [
/* plugins */
],
hooks: {
'build:done': async () => {
console.log('Build complete!');
},
},
});
await build(config);
See Config Reference for all options.
Common Patterns
Custom Build Script
// scripts/build.ts
import { build } from 'tsdown';
async function main() {
console.log('Building library...');
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
clean: true,
});
console.log('Build complete!');
}
main().catch(console.error);
Run with:
tsx scripts/build.ts
Multiple Builds
import { build } from 'tsdown';
// Build main library
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
outDir: 'dist',
dts: true,
});
// Build CLI tool
await build({
entry: ['src/cli.ts'],
format: ['esm'],
outDir: 'dist/bin',
platform: 'node',
shims: true,
});
Conditional Build
import { build } from 'tsdown';
const isDev = process.env.NODE_ENV === 'development';
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
minify: !isDev,
sourcemap: isDev,
clean: !isDev,
});
With Error Handling
import { build } from 'tsdown';
try {
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
});
console.log('✅ Build successful');
} catch (error) {
console.error('❌ Build failed:', error);
process.exit(1);
}
Automated Workflow
import { build } from 'tsdown';
import { execSync } from 'child_process';
async function release() {
// Clean
console.log('Cleaning...');
execSync('rm -rf dist');
// Build
console.log('Building...');
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
minify: true,
});
// Test
console.log('Testing...');
execSync('npm test');
// Publish
console.log('Publishing...');
execSync('npm publish');
}
release().catch(console.error);
Build with Post-Processing
import { build } from 'tsdown';
import { copyFileSync } from 'fs';
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
hooks: {
'build:done': async () => {
// Copy additional files
copyFileSync('README.md', 'dist/README.md');
copyFileSync('LICENSE', 'dist/LICENSE');
console.log('Copied additional files');
},
},
});
Watch Mode
Unfortunately, watch mode is not directly exposed in the programmatic API. Use the CLI for watch mode:
// Use CLI for watch mode
import { spawn } from 'child_process';
spawn('tsdown', ['--watch'], {
stdio: 'inherit',
shell: true,
});
Integration Examples
With Task Runner
// gulpfile.js
import { build } from 'tsdown';
import gulp from 'gulp';
gulp.task('build', async () => {
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
});
});
gulp.task('watch', () => {
return gulp.watch('src/**/*.ts', gulp.series('build'));
});
With Custom CLI
// scripts/cli.ts
import { build } from 'tsdown';
import { Command } from 'commander';
const program = new Command();
program
.command('build')
.option('--prod', 'Production build')
.action(async (options) => {
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
minify: options.prod,
sourcemap: !options.prod,
});
});
program.parse();
With CI/CD
// .github/scripts/build.ts
import { build } from 'tsdown';
const isCI = process.env.CI === 'true';
await build({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
minify: isCI,
clean: true,
});
// Upload to artifact storage
if (isCI) {
// Upload dist/ to S3, etc.
}
TypeScript Support
// scripts/build.ts
import { build, type UserConfig } from 'tsdown';
const config: UserConfig = {
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
};
await build(config);
Tips
- Use TypeScript for type safety
- Handle errors properly
- Use hooks for custom logic
- Log progress for visibility
- Use CLI for watch mode
- Exit on error in scripts
Troubleshooting
Import Errors
Ensure tsdown is installed:
pnpm add -D tsdown
Type Errors
Import types:
import type { UserConfig } from 'tsdown';
Build Fails Silently
Add error handling:
try {
await build(config);
} catch (error) {
console.error(error);
process.exit(1);
}
Options Not Working
Check spelling and types:
// ✅ Correct
{
format: ['esm', 'cjs'];
}
// ❌ Wrong
{
formats: ['esm', 'cjs'];
}
Related
- Config File - Configuration options
- Hooks - Lifecycle hooks
- CLI - Command-line interface
- Plugins - Plugin system