Target

Configure JavaScript compilation targets and runtime environments

Target

The compilation target determines which JavaScript features and runtime environments your code should support. Packem does not expose a single top-level target option. Instead, the target is driven by three real mechanisms:

  • runtime - the target runtime environment (node, browser, edge-light, react-server, bun, deno, workerd, electron, react-native).
  • browserTargets - an array of browserslist queries used for transpilation.
  • The transformer's own target - e.g. rollup.esbuild.target or rollup.swc.jsc.target, and your tsconfig.json compilerOptions.target.

There is no top-level target: 'es2020' option. Set the ECMAScript target through the active transformer (for example rollup.esbuild.target) or your tsconfig.json.

ECMAScript Target

The ECMAScript syntax level is controlled by the active transformer. Configure it under the matching transformer key inside rollup.

esbuild

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
    },
  },
})

SWC

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/swc'

export default defineConfig({
  transformer,
  rollup: {
    swc: {
      jsc: {
        target: 'es2020',
        parser: {
          syntax: 'typescript',
          tsx: true,
        },
      },
    },
  },
})

TypeScript / tsconfig

When using the TypeScript transformer (or to influence type-aware behavior), the ECMAScript target comes from your tsconfig.json:

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2020",
    "module": "ESNext",
    "lib": ["ES2020", "DOM"]
  }
}

Available ECMAScript Levels

These are the values accepted by transformer target options (e.g. rollup.esbuild.target):

  • es5 - ES5 (2009) - Maximum compatibility
  • es2015 / es6 - ES2015 (2015) - Classes, arrow functions, let/const
  • es2016 - ES2016 (2016) - Exponentiation operator
  • es2017 - ES2017 (2017) - Async/await, Object.entries/values
  • es2018 - ES2018 (2018) - Rest/spread, async iteration
  • es2019 - ES2019 (2019) - Optional catch binding, flat/flatMap
  • es2020 - ES2020 (2020) - Optional chaining, nullish coalescing
  • es2021 - ES2021 (2021) - Logical assignment, numeric separators
  • es2022 - ES2022 (2022) - Top-level await, private fields
  • esnext - Latest features

Browser Targets

Use the top-level browserTargets option to drive transpilation with browserslist queries.

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  browserTargets: [
    'chrome 90',
    'firefox 88',
    'safari 14',
    'edge 90',
  ],
})

Browserslist Integration

browserTargets accepts the same query syntax as a .browserslistrc file or the browserslist field in package.json. You may also configure browserslist in package.json directly:

// package.json
{
  "browserslist": [
    "> 1%",
    "last 2 versions",
    "not dead"
  ]
}

Runtime Targets

The runtime option selects the target runtime environment. This affects defaults such as externalization, conditions, and whether browserTargets apply.

Node.js

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  runtime: 'node',
})

Browser

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  runtime: 'browser',
  browserTargets: ['> 1%', 'last 2 versions'],
})

Edge Runtime

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  runtime: 'edge-light', // Vercel Edge Runtime
  rollup: {
    output: {
      format: 'esm',
    },
  },
})

React Server Components

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  runtime: 'react-server',
  rollup: {
    external: ['react', 'react-dom'],
    output: {
      format: 'esm',
    },
  },
})

Available Runtimes

runtime accepts: browser, bun, deno, edge-light, electron, node, react-native, react-server, workerd.

Feature Support (esbuild)

esbuild lets you toggle individual language features via its supported map. These live under rollup.esbuild:

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
      supported: {
        'optional-chaining': true,
        'nullish-coalescing': true,
        'bigint': false, // Disable if not supported
        'top-level-await': true,
      },
    },
  },
})

Output Code Generation

Rollup can downlevel some generated glue code via output.generatedCode. This is independent of the transformer target.

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
    },
    output: {
      generatedCode: {
        preset: 'es2015',
        arrowFunctions: true,
        constBindings: true,
        objectShorthand: true,
      },
    },
  },
})

Multiple Output Formats

To produce several output formats, provide an array of outputs. Rollup outputs do not have a per-output target; the syntax level is set once via the transformer.

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
    },
    output: [
      {
        format: 'esm',
        file: 'dist/index.mjs',
      },
      {
        format: 'cjs',
        file: 'dist/index.cjs',
      },
    ],
  },
})

Library Targets

Modern Library

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
    },
    output: {
      format: 'esm',
      file: 'dist/index.mjs',
    },
  },
})

Node.js Library

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  runtime: 'node',
  rollup: {
    esbuild: {
      target: 'es2020',
    },
    output: {
      format: 'cjs',
      file: 'dist/index.cjs',
    },
    external: ['fs', 'path', 'url'], // Node.js built-ins
  },
})

Framework Targets

React Library

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
    },
    external: ['react', 'react-dom'],
    output: {
      format: 'esm',
      file: 'dist/index.mjs',
    },
  },
})

Vue Library

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  preset: 'vue',
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
    },
    external: ['vue'],
    output: {
      format: 'esm',
      file: 'dist/index.mjs',
    },
  },
})

Environment-Specific Configuration

Because defineConfig accepts a plain object (or a function), you can compute the target from environment variables:

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: process.env.NODE_ENV === 'production' ? 'es2020' : 'esnext',
    },
  },
})

Troubleshooting

Syntax Errors

If you encounter syntax errors, your transformer target might be too old for the features you're using. Raise rollup.esbuild.target (or the equivalent for your transformer) or your tsconfig.json compilerOptions.target.

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  rollup: {
    esbuild: {
      target: 'es2020',
      supported: {
        'optional-chaining': true,
      },
    },
  },
})

Browser Compatibility

import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'

export default defineConfig({
  transformer,
  browserTargets: [
    'chrome 60',
    'firefox 55',
    'safari 12',
    'edge 79',
  ],
})

Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues