tsup: tsup build failing with ERR_WORKER_OUT_OF_MEMORY

tsup build is failing on me when dts is enabled

cli output

> shadcn-fe-components@0.0.1 build C:\Users\denni\Desktop\code\workspace\shadcn-ui-fanedition\packages\ui
> tsup

CLI Building entry: src/index.ts, src/components/alert/index.ts, src/components/alert-dialog/index.ts, src/components/accordion/index.ts, src/components/aspect-ratio/index.ts, src/components/avatar/index.ts, src/components/badge/index.ts, src/components/button/index.ts, src/components/calendar/index.ts, src/components/card/index.ts, src/components/checkbox/index.ts, src/components/collapsible/index.ts, src/components/command/index.ts, src/components/context-menu/index.ts, src/components/dialog/index.ts, src/components/dropdown-menu/index.ts, src/components/hover-card/index.ts, src/components/input/index.ts, src/components/label/index.ts, src/components/menubar/index.ts, src/components/popover/index.ts, src/components/navigation-menu/index.ts, src/components/progress/index.ts, src/components/radio-group/index.ts, src/components/scroll-area/index.ts, src/components/select/index.ts, src/components/separator/index.ts, src/components/sheet/index.ts, src/components/skeleton/index.ts, src/components/slider/index.ts, src/components/switch/index.ts, src/components/table/index.ts, src/components/tabs/index.ts, src/components/textarea/index.ts, src/components/toast/index.ts, src/components/toggle/index.ts, src/components/tooltip/index.ts
CLI Using tsconfig: tsconfig.json
CLI tsup v6.7.0
CLI Using tsup config: C:\Users\denni\Desktop\code\workspace\shadcn-ui-fanedition\packages\ui\tsup.config.ts
CLI Target: esnext
CLI Cleaning output folder
ESM Build start
DTS Build start
"useCallback" is imported from external module "react" but never used in "dist/chunk-DNB5WMWA.js".
ESM dist\components\textarea\index.js            617.00 B
ESM dist\components\tabs\index.js                1.27 KB
ESM dist\components\toggle\index.js              1.08 KB
ESM dist\components\separator\index.js           516.00 B
ESM dist\components\skeleton\index.js            287.00 B
ESM dist\components\tooltip\index.js             786.00 B
ESM dist\components\select\index.js              2.30 KB
ESM dist\components\sheet\index.js               3.41 KB
ESM dist\components\scroll-area\index.js         1001.00 B
ESM dist\components\slider\index.js              884.00 B
ESM dist\components\table\index.js               1.64 KB
ESM dist\components\input\index.js               678.00 B
ESM dist\components\label\index.js               513.00 B
ESM dist\components\popover\index.js             776.00 B
ESM dist\components\navigation-menu\index.js     3.03 KB
ESM dist\components\progress\index.js            579.00 B
ESM dist\components\calendar\index.js            1.81 KB
ESM dist\components\radio-group\index.js         960.00 B
ESM dist\components\card\index.js                1.14 KB
ESM dist\components\checkbox\index.js            853.00 B
ESM dist\components\collapsible\index.js         256.00 B
ESM dist\components\menubar\index.js             4.21 KB
ESM dist\components\hover-card\index.js          615.00 B
ESM dist\components\command\index.js             2.92 KB
ESM dist\components\context-menu\index.js        3.57 KB
ESM dist\chunk-Q37AVSUX.js                       2.28 KB
ESM dist\components\dialog\index.js              308.00 B
ESM dist\components\dropdown-menu\index.js       3.85 KB
ESM dist\components\alert\index.js               1.10 KB
ESM dist\index.js                                356.00 B
ESM dist\components\alert-dialog\index.js        2.22 KB
ESM dist\components\accordion\index.js           257.00 B
ESM dist\chunk-B2EBCAU5.js                       1.13 KB
ESM dist\chunk-4Y755WKG.js                       1.39 KB
ESM dist\components\avatar\index.js              816.00 B
ESM dist\chunk-DNB5WMWA.js                       1.73 KB
ESM dist\components\button\index.js              222.00 B
ESM dist\components\badge\index.js               877.00 B
ESM dist\chunk-GUWPUQGY.js                       980.00 B
ESM dist\chunk-MVYCDPAD.js                       778.00 B
ESM dist\components\aspect-ratio\index.js        161.00 B
ESM dist\chunk-72SGZM6M.js                       20.12 KB
ESM dist\components\switch\index.js              960.00 B
ESM dist\components\toast\index.js               3.04 KB
ESM dist\components\textarea\index.js.map        1.14 KB
ESM dist\components\toggle\index.js.map          2.45 KB
ESM dist\components\separator\index.js.map       1.32 KB
ESM dist\components\skeleton\index.js.map        612.00 B
ESM dist\components\tooltip\index.js.map         1.60 KB
ESM dist\components\select\index.js.map          5.64 KB
ESM dist\components\sheet\index.js.map           9.47 KB
ESM dist\components\table\index.js.map           4.32 KB
ESM dist\components\label\index.js.map           1.30 KB
ESM dist\components\navigation-menu\index.js.map 6.94 KB
ESM dist\components\progress\index.js.map        1.32 KB
ESM dist\components\calendar\index.js.map        3.51 KB
ESM dist\components\tabs\index.js.map            2.67 KB
ESM dist\components\card\index.js.map            3.09 KB
ESM dist\components\checkbox\index.js.map        1.59 KB
ESM dist\components\radio-group\index.js.map     2.22 KB
ESM dist\components\collapsible\index.js.map     610.00 B
ESM dist\components\menubar\index.js.map         10.54 KB
ESM dist\components\hover-card\index.js.map      1.45 KB
ESM dist\components\command\index.js.map         7.19 KB
ESM dist\components\slider\index.js.map          1.65 KB
ESM dist\chunk-Q37AVSUX.js.map                   5.56 KB
ESM dist\components\alert\index.js.map           2.55 KB
ESM dist\components\dropdown-menu\index.js.map   9.62 KB
ESM dist\components\dialog\index.js.map          51.00 B
ESM dist\index.js.map                            51.00 B
ESM dist\components\accordion\index.js.map       51.00 B
ESM dist\components\scroll-area\index.js.map     2.53 KB
ESM dist\chunk-4Y755WKG.js.map                   5.73 KB
ESM dist\chunk-DNB5WMWA.js.map                   9.64 KB
ESM dist\components\avatar\index.js.map          2.20 KB
ESM dist\components\input\index.js.map           1.21 KB
ESM dist\components\button\index.js.map          51.00 B
ESM dist\components\badge\index.js.map           1.91 KB
ESM dist\components\aspect-ratio\index.js.map    364.00 B
ESM dist\chunk-GUWPUQGY.js.map                   1.88 KB
ESM dist\chunk-MVYCDPAD.js.map                   3.94 KB
ESM dist\chunk-72SGZM6M.js.map                   117.68 KB
ESM dist\components\switch\index.js.map          1.62 KB
ESM dist\components\toast\index.js.map           6.63 KB
ESM dist\components\popover\index.js.map         1.65 KB
ESM dist\components\context-menu\index.js.map    9.22 KB
ESM dist\components\alert-dialog\index.js.map    6.79 KB
ESM dist\chunk-B2EBCAU5.js.map                   3.01 KB
ESM ⚡️ Build success in 17910ms
node:events:489
      throw er; // Unhandled 'error' event
      ^

Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
    at new NodeError (node:internal/errors:399:5)
    at [kOnExit] (node:internal/worker:310:26)
    at Worker.<computed>.onexit (node:internal/worker:226:20)
Emitted 'error' event on Worker instance at:
    at [kOnExit] (node:internal/worker:310:12)
    at Worker.<computed>.onexit (node:internal/worker:226:20) {
  code: 'ERR_WORKER_OUT_OF_MEMORY'
}

Node.js v20.1.0
 ELIFECYCLE  Command failed with exit code 1.
import { defineConfig } from 'tsup'

export default defineConfig({
    dts: true,
    minify: true,
    sourcemap: true,
    treeshake: true,
    splitting: true,
    clean: true,
    external: ['react', 'react-dom'],
    entry: [
        "src/index.ts",
        "src/components/**/index.ts",
    ],
    format: ['esm'],
})

Upvote & Fund

  • We’re using Polar.sh so you can upvote and help fund this issue.
  • We receive the funding once the issue is completed & confirmed by you.
  • Thank you in advance for helping prioritize & fund our backlog.
<picture> <source media="(prefers-color-scheme: dark)" srcset="https://polar.sh/api/github/egoist/tsup/issues/920/pledge.svg?darkmode=1"> Fund with Polar </picture>

About this issue

  • Original URL
  • State: open
  • Created a year ago
  • Reactions: 16
  • Comments: 23

Commits related to this issue

Most upvoted comments

My config if helpful

import { defineConfig, Options } from 'tsup';

export default defineConfig((options: Options) => ({
  entry: {
    'Button/index': 'src/components/atoms/Button/Button.tsx',
    // lots more components
  },
  splitting: false,
  format: ['esm', 'cjs'],
  dts: true,
  minify: true,
  external: ['react'],
  ...options,
}));

On tsup ^7.2.0, completely blocked by this

Getting the same issue on a library with ~100 entrypoints. Running locally I have no problems but in CI seeing the OOM error.

Splitting the config into chunks of 2,4,6 basically grinds the whole process to a halt locally. Interestingly experimentalDts has no memory problems at all, however does generate slightly incorrect declaration files for us, so not an option.

I’m using 7.2.0. My temporary solution was putting NODE_OPTIONS='--max-old-space-size=16384' before tsup. it’s a workaround, I know… but 😬

package.json

{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=16384' tsup",
    "dev": "NODE_OPTIONS='--max-old-space-size=16384' tsup --watch",
  }
}

Rolling back to version 6.6.0 seems to be working.

Same with Tsup version 7.0.0 (Using pnpm, turbo) It happens only on DTS part. I also tried without turbo but same error. For really small library, it can complete without error but DTS build takes a really long time. (for example 500ms for esm build then 20+ s for DTS)

I have to rollback to Tsup 6.5.0 to make it work

Context: React library Tsup conf:

import { defineConfig } from 'tsup'

export default defineConfig((options) => {
  return {
    entry: ['src'],
    sourcemap: true,
    minify: !options.watch,
    dts: false,
    clean: true,
    format: ['esm'],
    external: ['react', 'react-hook-form'],
    // https://github.com/shuding/react-wrap-balancer/blob/main/tsup.config.ts#L10-L13
    esbuildOptions(options) {
      options.banner = {
        js: '"use client"',
      }
    },
  }
})

Terminal output on build script:

ESM ⚡️ Build success in 504ms
build: DTS Build start
build: node:events:491
build:       throw er; // Unhandled 'error' event
build:       ^
build: 
build: Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory
build:     at new NodeError (node:internal/errors:393:5)
build:     at [kOnExit] (node:internal/worker:277:26)
build:     at Worker.<computed>.onexit (node:internal/worker:199:20)
build: Emitted 'error' event on Worker instance at:
build:     at [kOnExit] (node:internal/worker:277:12)
build:     at Worker.<computed>.onexit (node:internal/worker:199:20) {
build:   code: 'ERR_WORKER_OUT_OF_MEMORY'
build: }
build: 
build: Node.js v18.10.0
build:  ELIFECYCLE  Command failed with exit code 1.
build: ERROR: command finished with error: command (/srv/projects/unic/unics/customers-sites/customers-sites/packages/molecules) pnpm run build exited (1)
command (/srv/projects/customers-sites/packages/molecules) pnpm run build exited (1)

Just faced the same issue. Would love if someone from the tsup team can look into patching this

Any news @egoist on this point ? it’s preventing us from upgrading to the latest tsup version 😞 (we are stuck on 6.x)

NODE_OPTIONS='--max-old-space-size=16384'

Thanks, worked magically in my case.

It works for you now but wait a bit while your project grows and it will start to fail. Also while it doesn’t fail, it takes significant amount of time that will also cost via your CI.

Unable to migrate back because I need 7.0.0 for this feature https://github.com/egoist/tsup/pull/925 (keep 'use client'; directive in my components.

Same error

Error [ERR_WORKER_OUT_OF_MEMORY]: Worker terminated due to reaching memory limit: JS heap out of memory

Thanks @tigawanna your workaround worked. I was able to build up to 6 files at a time without issues. However, I grouped my files according to their categories

import { defineConfig } from 'tsup'

export const fonts = defineConfig({
    entry: {
        fonts: 'src/styles/fonts.ts',
        commonTypes: 'src/CommonTypes/index.ts'

    }
})
export const maps = defineConfig({
    entry: {
        lib: 'src/lib/index.ts',
        charts: 'src/PgCharts/index.ts',
        error: 'src/ErrorComponent/index.ts'
    }
})
export const forms = defineConfig({
    entry: {
        pgForm: 'src/pgForm/index.ts',
        pgForm2: 'src/pgForm2/index.ts'
    }
})

export const icons = defineConfig({
    entry: {
        icons: 'src/PgIcon/index.ts'
    }
})

export const tables = defineConfig({
    entry: {
        pgTable: 'src/PgTable/index.ts'
    }
})
export const map = defineConfig({
    entry: {
        pgMap: 'src/PgMap/index.ts'
    }
})
export const dialogs = defineConfig({
    entry: {
        alert: 'src/PgAlert/index.ts',
        popOver: 'src/pgPopOver/index.ts',
        card: 'src/PgCard/index.ts'
    }
})
export const jsonToCsv = defineConfig({
    entry: {
        jsonToCsv: 'src/JsonToCsv/index.ts'
    }
})
export const translations = defineConfig({
    entry: {
        translations: 'src/translations/index.ts'
    }
})
export const heatmap = defineConfig({
    entry: {
        heatmap: 'src/PgHeatmap/index.ts'
    }
})
export const utils = defineConfig({
    entry: {
        utils: 'src/CommonUtils/index.ts',
        formattedNumberInput: 'src/FormattedNumberInput/index.ts'
    }
})
export const styles = defineConfig({
    entry: {
        styles: 'src/styles/index.ts'
    }
})

export default [styles, utils, translations, heatmap, jsonToCsv, dialogs, map, tables, icons, forms, maps, fonts]

Such grouping reduced the number of files built in a set and also made the code look a bit organised. It does rids us of this ERR_WORKER_OUT_OF_MEMORY error until a permanent fix is issued from @egoist

Try only building 3 files at a time

That actually worked! thanks so much @tigawanna

Try only building 3 files at a time

My team is having the same issue here

Our tsup.config.ts here

and it seems the issue only happens when we run tsup with --dts flag

Is there any work around for this?