How to Create a Single File Bundle of a Large Typescript Project in 2023

Matthew Joseph Taylor
2 min readJun 23, 2023

--

MJT + ML = ❤

I’ve been struggling with how to package a large ‘monorepo’ typescript project with several sub-projects inside an npm workspace.

Ideally I want a single file (two if you count the typedef file) to act as the distributable.

This is a very simple ask, yet though many packaging tools semi-claim to do something like this, I’ve only found one that works reliably.

Use esbuild to compile entire TypeScript monorepo to a single large JavaScript file.

Create a file called build.js

const { build } = require("esbuild");
const { dependencies, peerDependencies } = require('./package.json');

const sharedConfig = {
entryPoints: ["src/index.ts"],
bundle: true,
minify: false,
// only needed if you have dependencies
// external: Object.keys(dependencies).concat(Object.keys(peerDependencies)),
};

build({
...sharedConfig,
platform: 'browser',
format: 'esm',
outfile: "dist/index.js",
});

And run it like:

$ node ./build.js

Use dts-bundle-generator to build as single TypeScript defintion (.d.ts) file.

NOTE: this is a slow process on a large project, can take a few minutes.

$ npx dts-bundle-generator -o dist/index.d.ts src/index.ts

What this accomplishes

  • A single javascript file with NO weird workspace-sub-project import dependencies (that tools like npm pack deal poorly with)
  • A single typescript definition file with NO weird workspace-sub-project import dependencies.

--

--