Bundle your TypeScript library with no config, powered by esbuild.
Anything that's supported by Node.js natively, namely .js
, .json
, .mjs
. And TypeScript .ts
, .tsx
. CSS support is experimental.
Install it locally in your project folder:
npm i tsup -D
# Or Yarn
yarn add tsup --dev
You can also install it globally but it's not recommended.
tsup [...files]
Files are written into ./dist
.
You can bundle multiple files in one go:
tsup src/index.ts src/cli.ts
This will output dist/index.js
and dist/cli.js
.
By default tsup bundles all import
-ed modules but dependencies
and peerDependencies
in your packages.json
are always excluded, you can also use --external <module>
flag to mark other packages as external.
If you are using tsup to build for Node.js applications/APIs, usually bundling dependencies is not needed, and it can even break things, for instance, while outputting to ESM.
tsup automatically excludes packages specified in the dependencies
and peerDependencies
fields in the packages.json
, but if it somehow doesn't exclude some packages, this library also has a special executable tsup-node
that automatically skips bundling any Node.js package.
tsup-node src/index.ts
All other CLI flags still apply to this command.
You can also use tsup
using file configurations or in a property inside your package.json
, and you can even use TypeScript
and have type-safety while you are using it.
Most of these options can be overwritten using the CLI options
You can use any of these files:
tsup.config.ts
tsup.config.js
tsup.config.cjs
tsup.config.json
tsup
property in yourpackage.json
In all the custom files you can export the options either as
tsup
,default
ormodule.exports =
// tsup.config.ts
import type { Options } from 'tsup'
export const tsup: Options = {
splitting: false,
sourcemap: true,
clean: true,
entryPoints: ['src/index.ts'],
}
// tsup.config.cjs
/**
* @type {import("tsup").Options}
*/
module.exports = {
splitting: false,
sourcemap: true,
clean: true,
entryPoints: ['src/index.ts'],
}
{
"tsup": {
"splitting": false,
"sourcemap": true,
"clean": true,
"entryPoints": ["src/index.ts"]
},
"scripts": {
"build": "tsup"
}
}
tsup index.ts --dts
This will emit ./dist/index.js
and ./dist/index.d.ts
.
If you have multiple entry files, each entry will get a corresponding .d.ts
file. So when you only want to generate declaration file for a single entry, use --dts <entry>
format, e.g. --dts src/index.ts
.
Note that --dts
does not resolve external (aka in node_modules
) types used in the .d.ts
file, if that's somehow a requirement, try the experimental --dts-resolve
flag instead.
tsup index.ts --sourcemap
This will emit ./dist/index.js
and ./dist/index.js.map
.
If you set multiple entry files, each entry will get a corresponding .map
file.
If you want to inline sourcemap, you can try:
tsup index.ts --sourcemap inline
Supported format: esm
, cjs
, (default) and iife
.
You can bundle in multiple formats in one go:
tsup src/index.ts --format esm,cjs,iife
That will output files in following folder structure:
dist
├── index.mjs # esm
├── index.global.js # iife
└── index.js # cjs
If the type
field in your package.json
is set to module
, the filenames will be slightly different:
dist
├── index.js # esm
├── index.global.js # iife
└── index.cjs # cjs
Read more about esm
support in Node.js.
If you don't want extensions like .mjs
or .cjs
, e.g. you want your library to be used in a bundler (or environment) that doesn't support those, you can enable --legacy-output
flag:
tsup src/index.ts --format esm,cjs,iife --legacy-output
..which outputs to:
dist
├── esm
│ └── index.js
├── iife
│ └── index.js
└── index.js
Code splitting currently only works with the esm
output format, and it's enabled by default. If you want code splitting for cjs
output format as well, try using --splitting
flag which is an experimental feature to get rid of the limitation in esbuild.
To disable code splitting altogether, try the --no-splitting
flag instead.
You can use --target es5
to compile the code down to es5, it's processed by buble. Some features are NOT supported by this target, namely: for .. of
.
You can use --env
flag to define compile-time environment variables:
tsup src/index.ts --env.NODE_ENV production
When an entry file like src/cli.ts
contains hashbang like #!/bin/env node
tsup will automatically make the outout file executable, so you don't have to run chmod +x dist/cli.js
.
tsup src/index.ts --watch
You can also specify the directories to be watched. By default, if no path is specified, it watches the current directory.
tsup src/index.ts --watch src
You can specify more than a single directory
tsup src/index.ts --watch src --watch lib
You can specify one or more extra folders to be ignored while watching changes
By default it always ignores
dist
,node_modules
&.git
tsup src/index.ts --watch --ignore-watch ignore-this-folder
You can specify more than a folder repeating "--ignore-watch", for example:
tsup src src/index.ts --watch --ignore-watch folder1 --ignore-watch folder2
You can specify command to be executed after a successful build, specially useful for Watch mode
You should not use shell scripts, if you need to specify shell scripts you can add it in your "scripts" field and set for example
tsup src/index.ts --watch --onSuccess \"npm run dev\"
tsup src/index.ts --watch --onSuccess "node dist/index.js"
You can also minify the output, resulting into lower bundle sizes by using the --minify
flag.
tsup src/index.ts --minify
esbuild is fast because it doesn't perform any type checking, you already get type checking from your IDE like VS Code or WebStorm.
Additionally, if you want type checking at build time, you can enable --dts
, which will run a real TypeScript compiler to generate declaration file so you get type checking as well.
esbuild has experimental CSS support, and tsup allows you to use PostCSS plugins on top of native CSS support.
To use PostCSS, you need to install PostCSS:
yarn add postcss --dev
..and populate a postcss.config.js
in your project
module.exports = {
plugins: [require('tailwindcss')(), require('autoprefixer')()],
}
For more details:
tsup --help
MIT © EGOIST