Susee

Overview
susee is a TypeScript bundler that processes a package’s local dependency tree and emits compiled artifacts in multiple module formats. Unlike general-purpose bundlers that target browser environments or bundle node_modules, susee focuses on library authorship: it collates local TypeScript files, merges them into cohesive bundles, compiles them through the TypeScript compiler, and generates properly formatted outputs for consumption as npm packages.
Key Features
-
Dependency Tree Resolution : automatically resolves and collects local TypeScript dependencies starting from specified entry points.
-
Dual-Format Module Output : generates outputs for both ESM and CommonJS module systems from a single TypeScript source.
-
File Extension Conventions : dual-emit conventions for unambiguous module format identification.
Module Format JavaScript Extension Type Definition Extension ESM .mjs.d.mtsCommonJS .cjs.d.cts -
Automatic package.json Management : conditionally updates package.json fields based on compilation outputs, this feature is controlled by the
allowUpdatePackageJsonboolean inSuSeeConfig.
Installation
Install as a development dependency :
npm install susee --save-dev
Global install:
npm install -g susee
Quick Start
The susee CLI binary is exposed through the bin field and becomes available immediately after installation.
Creating a Minimal Configuration
Create a file named susee.config.ts in your project root:
import type { SuSeeConfig } from "susee";
const config: SuSeeConfig = {
entryPoints: [
{
entry: "src/index.ts",
exportPath: ".",
format: "both",
},
],
};
export default config;
Running Your First Build
Execute the bundler using one of these methods:
CLI Execution
with npx :
npx susee
via package.json :
{
"scripts": {
"build": "susee"
}
}
npm run build
for global :
susee
Programmatic Execution
import { susee } from "susee";
await susee();
The susee() function is an asynchronous operation that:
- Loads configuration from
susee.config.ts - Resolves the dependency tree
- Bundles local dependencies
- Compiles to target formats
- Optionally updates
package.json
Configuration summary
Top-Level Configuration Fields
entryPoints
An array of EntryPoint objects defining the files to bundle. Each entry point represents a separate bundling operation with its own entry file, export path, and output configuration. The array must contain at least one entry point.
plugins (optional)
An optional array of plugin instances that provide transformation hooks. Plugins can be objects or factory functions and execute at different stages of the bundling pipeline (dependency, pre-process, post-process). Defaults to [] if not specified.
allowUpdatePackageJson (optional)
Controls whether susee automatically updates the package.json file with generated exports, main fields, and module fields. When true, susee modifies the package.json to reflect the bundled outputs. When false, package.json remains unchanged.
Defaults to true if not specified.
outDir (optional)
Specifies the base output directory where compiled files are written. This can be overridden per entry point if needed (though the current implementation uses a global outDir). Defaults to "dist" if not specified.
EntryPoint Structure
Each entry point in the entryPoints array defines a separate bundling target. The EntryPoint interface specifies the following fields:
entry: The file path to the TypeScript entry file. This path is validated during configuration loading to ensure the file exists
exportPath: The package export path where this bundle will be exposed. Use “.” for the main package export, or subpath like “./config” for additional exports. Duplicate export paths across entry points are not allowed and will cause validation failure.
format (optional): Determines which module format(s), commonjs,esm or both esmand commonjs to generate.
Defaults to esm if not specified.
tsconfigFilePath (optional): Optional path to a custom TypeScript configuration file for this specific entry point. If not specified, susee will resolve for TypesScript compiler options as follow :
Priority -
-
this custom
tsconfig.json -
tsconfig.jsonat root directory -
default compiler options of
susee
Notes: You can control TypesScript compiler options from tsconfig.json except , rootDir , outDir,module.
renameDuplicates (optional): Controls whether susee automatically renames duplicate identifiers during the bundling process to avoid naming conflicts when merging files.(default to true).If you want to rename your self set to false, process will exit with code-1 and print where duplicate found.
Plugins
Plugins in the ecosystem have three common types:
dependency— transform dependency list before bundlingpre-process— modify the joined bundle text before compilationpost-process— modify emitted output files
Plugins may be provided as objects or factories (functions returning the plugin). They may be synchronous or async — the bundler handles both.
package.json updates
When allowUpdatePackageJson is enabled, susee will:
- set
typetomodule(to ensure ESM compatibility) - add/update
main,module,typesandexportsfor the main export when building the package root - merge subpath exports for non-root
exportPaths without overwriting unrelated exports
Output file name hints (produced by the compiler):
- ESM JS ->
.mjs - ESM types ->
.d.mts - CJS JS ->
.cjs - CJS types ->
.d.cts
Limitations & notes
- The bundler only processes local TypeScript files and does not bundle
node_modulespackages. - The entry file should be an ESM-compatible TypeScript file.
- Exports from the entry file are not removed — only dependency exports may be stripped during bundling.
Roadmap
Current environment support:
- Node.js only.
Planned work:
- Add first-class support for Deno environments.
- Add browser-oriented library build support.
- Improve workflows for building React-related libraries.
Contributing and tests
See CONTRIBUTING.md for contribution workflow, pull request checklist, and development guidelines.
- Build and run tests with the repo scripts (see
package.json):
npm run build
npm test