Building TypeScript libraries has been painful for too long. Slow builds that take seconds. Complex configurations. Manual package.json maintenance. It's 2025, and we deserve better.
This guide shows you how to build modern TypeScript libraries with exceptional speed and ergonomics using Bunup, powered by Bun's native bundler.
Getting Started
Let's create a simple TypeScript library. First, ensure you have Bun installed, then create your project structure:
mkdir my-library
cd my-library
bun init -y
Create your first TypeScript file:
// src/index.ts
export function greet(name: string): string {
return `Hello, ${name}!`;
}
export function add(a: number, b: number): number {
return a + b;
}
The Speed Revolution
Here's where things get interesting. Traditional tools take seconds to build even simple libraries. Let's see the difference:
# Traditional approach with tsup
$ tsup src/index.ts
✓ Build completed in 1.4s
# Modern approach with bunup
$ bunup src/index.ts
✓ Build completed in 37ms
That's 37 milliseconds. Not 1.4 seconds. Not 400ms. Just 37ms.
This isn't about saving a second here and there. Instant builds fundamentally change how you work. Your development flow stays uninterrupted. Watch mode becomes instantaneous. Pre-commit hooks run without friction. Building becomes invisible.
Setting Up Your Build
Install bunup as a development dependency:
bun add --dev bunup
Create a configuration file:
// bunup.config.ts
import { defineConfig } from 'bunup';
export default defineConfig({
entry: 'src/index.ts',
format: ['esm', 'cjs'],
});
Add build scripts to your package.json:
{
"scripts": {
"build": "bunup",
"dev": "bunup --watch"
}
}
Now build your library:
bun run build
Your library is built in both ESM and CommonJS formats, with TypeScript declarations, in milliseconds.
Modern TypeScript Configuration
For the best performance and compatibility, enable isolatedDeclarations
in your tsconfig.json:
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"declaration": true,
"isolatedDeclarations": true,
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
This enables dramatically faster declaration generation while ensuring your types are explicit and predictable. Learn more about isolated declarations.
Automatic Package Exports
One of the most tedious parts of library development is maintaining your package.json exports. Bunup handles this automatically.
Add the exports plugin to your configuration:
// bunup.config.ts
import { defineConfig } from 'bunup';
import { exports } from 'bunup/plugins';
export default defineConfig({
entry: 'src/index.ts',
format: ['esm', 'cjs'],
plugins: [exports()]
});
Build your library and watch your package.json transform:
{
"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"
}
}
}
}
Every path is correct. Every format is mapped. Every type declaration is in place. You never touch it manually again.
Multiple Entry Points
Real libraries often have multiple entry points. Bunup makes this effortless:
// bunup.config.ts
export default defineConfig({
entry: ['src/index.ts', 'src/utils.ts', 'src/math.ts'],
format: ['esm', 'cjs'],
plugins: [exports()]
});
Each entry point gets its own output files and proper exports mapping. Your consumers can import exactly what they need:
import { greet } from 'my-library';
import { formatDate } from 'my-library/utils';
import { calculate } from 'my-library/math';
Keeping Your Library Clean
Bunup helps you maintain a clean, efficient library with the unused dependencies plugin:
// bunup.config.ts
import { defineConfig } from 'bunup';
import { exports, unused } from 'bunup/plugins';
export default defineConfig({
entry: 'src/index.ts',
plugins: [
exports(),
unused()
]
});
During build, you'll get warnings about dependencies you're not using, dependencies in the wrong section, and missing peer dependencies. Your library stays lean and your dependencies stay accurate.
Monorepo Support
Building a design system or component library with multiple packages? Bunup's workspace support makes monorepo development seamless:
// bunup.config.ts
import { defineWorkspace } from 'bunup';
export default defineWorkspace([
{
name: 'core',
root: 'packages/core'
},
{
name: 'utils',
root: 'packages/utils'
},
{
name: 'components',
root: 'packages/components'
}
]);
Build all packages with a single command:
bunup
Bunup handles incremental builds, only rebuilding packages that have changed. Watch mode works across all packages. Dependencies between packages are resolved automatically.
Advanced Configuration
For more complex scenarios, bunup provides additional options while keeping the experience simple. You can configure minification, source maps, externals, and more. See the bunup documentation for all available options.
// bunup.config.ts
export default defineConfig({
entry: 'src/index.ts',
format: ['esm', 'cjs'],
minify: true,
sourcemap: 'linked',
target: 'node',
plugins: [exports()]
});
Development Workflow
Your daily workflow becomes effortless:
# Start development with watch mode
bun run dev
# Build for production
bun run build
# Type check your code
bun run typecheck
Changes rebuild instantly. Type declarations generate automatically. Package exports stay synchronized. Everything just works.
Why This Matters
This isn't just about faster builds or better configuration. It's about removing friction from library development. When builds are instant, you experiment more freely. When configuration is automatic, you focus on your code. When everything works out of the box, you ship faster.
Traditional build tools were designed for a different era. They carry the weight of legacy decisions and plugin ecosystems. Bunup is designed for today, leveraging Bun's native speed and modern TypeScript features to deliver an experience that feels right.
Start Building
Create your next TypeScript library with bunup:
bunx @bunup/cli@latest create
Choose the TypeScript template and start building. Your library will have instant builds, automatic exports, proper TypeScript configuration, and everything you need to publish to npm.
The future of TypeScript library development is here. Fast, ergonomic, and joyful. Welcome to modern library development with bunup.
Top comments (0)