name: build-tools description: Build tool configuration for tsup, tsx, and bundlers. Use when setting up build pipelines.
Build Tools Skill
This skill covers build tool configuration for TypeScript projects.
When to Use
Use this skill when:
- Setting up build pipelines
- Configuring library bundling
- Running TypeScript directly
- Choosing between build tools
Core Principle
RIGHT TOOL FOR THE JOB - Use tsup for libraries, tsx for scripts, Vite for apps.
Tool Selection Guide
| Use Case | Recommended Tool |
|---|---|
| Library/Package | tsup |
| CLI Application | tsup + tsx |
| Script Execution | tsx |
| React SPA | Vite |
| Full-Stack App | Next.js |
tsup - Library Bundler
Installation
npm install -D tsup
Basic Configuration
// tsup.config.ts
import { defineConfig } from 'tsup';
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm', 'cjs'],
dts: true,
clean: true,
splitting: false,
sourcemap: true,
minify: false,
treeshake: true,
});
Package.json for Library
{
"name": "my-library",
"version": "1.0.0",
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": {
"types": "./dist/index.d.ts",
"default": "./dist/index.js"
},
"require": {
"types": "./dist/index.d.cts",
"default": "./dist/index.cjs"
}
}
},
"files": ["dist"],
"scripts": {
"build": "tsup",
"dev": "tsup --watch"
}
}
Multiple Entry Points
// tsup.config.ts
export default defineConfig({
entry: {
index: 'src/index.ts',
utils: 'src/utils/index.ts',
cli: 'src/cli.ts',
},
format: ['esm', 'cjs'],
dts: true,
});
CLI with Shebang
// tsup.config.ts
export default defineConfig({
entry: ['src/cli.ts'],
format: ['esm'],
banner: {
js: '#!/usr/bin/env node',
},
clean: true,
});
tsx - TypeScript Execution
Installation
npm install -D tsx
Usage
# Run TypeScript file directly
npx tsx src/script.ts
# Watch mode
npx tsx watch src/server.ts
# With Node.js flags
npx tsx --inspect src/debug.ts
Package.json Scripts
{
"scripts": {
"dev": "tsx watch src/index.ts",
"start": "tsx src/index.ts",
"script": "tsx scripts/migrate.ts"
}
}
tsconfig.json for tsx
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler",
"esModuleInterop": true
}
}
TypeScript Compiler (tsc)
Build Only (No Bundling)
{
"compilerOptions": {
"outDir": "./dist",
"declaration": true,
"declarationMap": true,
"sourceMap": true
}
}
{
"scripts": {
"build": "tsc",
"build:watch": "tsc --watch"
}
}
Vite - Application Bundler
Installation
npm create vite@latest
Configuration
// vite.config.ts
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
export default defineConfig({
plugins: [react()],
build: {
target: 'ES2022',
sourcemap: true,
outDir: 'dist',
},
resolve: {
alias: {
'@': '/src',
},
},
});
Library Mode
// vite.config.ts
import { defineConfig } from 'vite';
import { resolve } from 'node:path';
export default defineConfig({
build: {
lib: {
entry: resolve(__dirname, 'src/index.ts'),
name: 'MyLib',
fileName: 'my-lib',
formats: ['es', 'cjs'],
},
rollupOptions: {
external: ['react', 'react-dom'],
},
},
});
Build Scripts
Complete Build Pipeline
{
"scripts": {
"prebuild": "npm run clean",
"build": "tsup",
"postbuild": "npm run type-check",
"clean": "rm -rf dist",
"type-check": "tsc --noEmit"
}
}
Watch Mode
{
"scripts": {
"dev": "tsup --watch",
"dev:run": "tsx watch src/index.ts"
}
}
Output Formats
ESM (ES Modules)
// Output: dist/index.js
export function hello() { }
CJS (CommonJS)
// Output: dist/index.cjs
module.exports.hello = function() { }
Dual Package
// tsup.config.ts
export default defineConfig({
format: ['esm', 'cjs'],
dts: true,
});
Declaration Files
Generate .d.ts
// tsup.config.ts
export default defineConfig({
dts: true, // Generate declaration files
});
Separate Declaration Build
{
"scripts": {
"build": "tsup && tsc --emitDeclarationOnly"
}
}
Source Maps
// tsup.config.ts
export default defineConfig({
sourcemap: true, // Generate source maps
});
Tree Shaking
// tsup.config.ts
export default defineConfig({
treeshake: true, // Remove unused code
});
Minification
// tsup.config.ts
export default defineConfig({
minify: true, // Minify output (production)
});
External Dependencies
// tsup.config.ts
export default defineConfig({
external: ['react', 'react-dom'], // Don't bundle these
});
Best Practices Summary
- Use tsup for libraries - Simple, fast, handles dual packages
- Use tsx for scripts - Direct execution without build
- Use Vite for apps - Fast dev server, optimized builds
- Generate type declarations - Always include .d.ts files
- Support both ESM and CJS - Dual package format
- Enable source maps - For debugging
- Tree shake in production - Remove unused code
Code Review Checklist
- Correct build tool selected for use case
- tsup.config.ts or vite.config.ts present
- Declaration files generated (dts: true)
- Both ESM and CJS formats for libraries
- Source maps enabled
- External dependencies configured
- Clean script removes old builds