Output Format
Configure output formats (ESM, CJS, IIFE) for your Packem builds
Output Format
Packem supports multiple output formats to ensure your library works across different JavaScript environments. The output format determines how your bundled code is structured and how it can be consumed by other applications.
Supported Formats
ESM (ES Modules)
Modern standard for JavaScript modules with import/export syntax.
export default defineConfig({
rollup: {
output: {
format: 'esm',
file: 'dist/index.mjs'
}
}
})CJS (CommonJS)
Traditional Node.js module format with require/module.exports.
export default defineConfig({
rollup: {
output: {
format: 'cjs',
file: 'dist/index.cjs'
}
}
})IIFE (Immediately Invoked Function Expression)
Browser-compatible format that creates a global variable.
export default defineConfig({
rollup: {
output: {
format: 'iife',
file: 'dist/index.global.js',
name: 'MyLibrary' // Global variable name
}
}
})UMD (Universal Module Definition)
Works in both browser and Node.js environments.
export default defineConfig({
rollup: {
output: {
format: 'umd',
file: 'dist/index.umd.js',
name: 'MyLibrary'
}
}
})Automatic Format Detection
Packem automatically determines output formats based on your package.json:
From Package Type
{
"type": "module",
"main": "./dist/index.js"
}→ Generates ESM format
{
"type": "commonjs",
"main": "./dist/index.js"
}→ Generates CJS format
From Export Conditions
{
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
}
}→ Generates both ESM and CJS formats
Multiple Output Formats
Generate multiple formats in a single build:
export default defineConfig({
rollup: {
output: [
// ESM build
{
format: 'esm',
file: 'dist/index.mjs'
},
// CJS build
{
format: 'cjs',
file: 'dist/index.cjs'
},
// Browser build
{
format: 'iife',
file: 'dist/index.global.js',
name: 'MyLibrary'
}
]
}
})Format-Specific Configuration
ESM Configuration
export default defineConfig({
rollup: {
output: {
format: 'esm',
file: 'dist/index.mjs',
// ESM-specific options
exports: 'named', // or 'default', 'auto'
generatedCode: {
preset: 'es2015'
}
}
}
})CJS Configuration
export default defineConfig({
rollup: {
output: {
format: 'cjs',
file: 'dist/index.cjs',
// CJS-specific options
exports: 'auto',
esModule: false,
interop: 'auto'
}
}
})IIFE Configuration
export default defineConfig({
rollup: {
output: {
format: 'iife',
file: 'dist/index.global.js',
name: 'MyLibrary',
// IIFE-specific options
globals: {
'react': 'React',
'react-dom': 'ReactDOM'
},
extend: true // Extend existing global
}
}
})File Extensions
Packem uses appropriate file extensions based on format:
Automatic Extensions
export default defineConfig({
rollup: {
output: [
{ format: 'esm', dir: 'dist' }, // → .mjs
{ format: 'cjs', dir: 'dist' }, // → .cjs
{ format: 'iife', dir: 'dist' } // → .js
]
}
})Custom Extensions
export default defineConfig({
rollup: {
output: {
format: 'esm',
dir: 'dist',
entryFileNames: '[name].esm.js' // Custom extension
}
}
})Package.json Integration
Dual Package Setup
{
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.mjs",
"exports": {
".": {
"import": "./dist/index.mjs",
"require": "./dist/index.cjs"
}
}
}export default defineConfig({
rollup: {
output: [
{ format: 'esm', file: 'dist/index.mjs' },
{ format: 'cjs', file: 'dist/index.cjs' }
]
}
})Conditional Exports
{
"exports": {
".": {
"development": "./dist/index.development.js",
"production": "./dist/index.production.js",
"import": "./dist/index.mjs",
"require": "./dist/index.cjs",
"default": "./dist/index.js"
}
}
}Runtime-Specific Formats
Node.js Optimized
export default defineConfig({
rollup: {
output: {
format: 'cjs',
file: 'dist/index.node.js',
// Node.js optimizations
preferConst: true,
compact: true
}
}
})Browser Optimized
export default defineConfig({
rollup: {
output: {
format: 'iife',
file: 'dist/index.browser.js',
name: 'MyLibrary',
// Browser optimizations
sourcemap: true,
compact: true
}
}
})Edge Runtime
export default defineConfig({
rollup: {
output: {
format: 'esm',
file: 'dist/index.edge.mjs',
// Edge runtime optimizations
generatedCode: {
preset: 'es2022'
}
}
}
})Advanced Configuration
Code Splitting
export default defineConfig({
rollup: {
output: {
format: 'esm',
dir: 'dist',
// Enable code splitting
manualChunks: {
vendor: ['react', 'react-dom'],
utils: ['lodash', 'date-fns']
}
}
}
})Dynamic Imports
export default defineConfig({
rollup: {
output: {
format: 'esm',
dir: 'dist',
// Configure dynamic import format
chunkFileNames: 'chunks/[name]-[hash].js',
dynamicImportFunction: 'import'
}
}
})Tree Shaking
export default defineConfig({
rollup: {
output: {
format: 'esm',
file: 'dist/index.mjs',
// Preserve modules for better tree shaking
preserveModules: true,
preserveModulesRoot: 'src'
}
}
})Format Validation
Validate your output formats:
export default defineConfig({
rollup: {
output: [
{ format: 'esm', file: 'dist/index.mjs' },
{ format: 'cjs', file: 'dist/index.cjs' }
]
},
hooks: {
'build:after': async () => {
// Validate package.json exports
const { validatePackage } = await import('@visulima/packem/validator')
await validatePackage('./package.json')
}
}
})Interoperability
ESM/CJS Interop
export default defineConfig({
cjsInterop: true, // Enable automatic interop
rollup: {
output: [
{
format: 'esm',
file: 'dist/index.mjs',
exports: 'named'
},
{
format: 'cjs',
file: 'dist/index.cjs',
exports: 'auto',
interop: 'auto'
}
]
}
})Default Export Handling
// For libraries with default exports
export default defineConfig({
rollup: {
output: [
{
format: 'esm',
file: 'dist/index.mjs',
exports: 'default'
},
{
format: 'cjs',
file: 'dist/index.cjs',
exports: 'default'
}
]
}
})Framework-Specific Formats
React Library
export default defineConfig({
rollup: {
external: ['react', 'react-dom'],
output: [
{
format: 'esm',
file: 'dist/index.mjs',
globals: {
'react': 'React',
'react-dom': 'ReactDOM'
}
},
{
format: 'cjs',
file: 'dist/index.cjs'
}
]
}
})Vue Library
export default defineConfig({
rollup: {
external: ['vue'],
output: [
{
format: 'esm',
file: 'dist/index.mjs'
},
{
format: 'umd',
file: 'dist/index.umd.js',
name: 'MyVueLibrary',
globals: {
'vue': 'Vue'
}
}
]
}
})Troubleshooting
Format Mismatch
Ensure your package.json exports match your actual output formats.
{
"exports": {
".": {
"import": "./dist/index.mjs", // Must be ESM
"require": "./dist/index.cjs" // Must be CJS
}
}
}Global Name Conflicts
For IIFE/UMD builds, ensure unique global names:
export default defineConfig({
rollup: {
output: {
format: 'iife',
name: 'MyUniqueLibraryName', // Avoid conflicts
extend: false // Don't extend existing globals
}
}
})External Dependencies
Configure externals appropriately for each format:
export default defineConfig({
rollup: {
external: (id) => {
// Different externals for different formats
if (format === 'iife') {
return ['react', 'react-dom'].includes(id)
}
return !id.startsWith('.') && !id.startsWith('/')
}
}
})Performance Considerations
Format-Specific Optimizations
export default defineConfig({
rollup: {
output: [
// Development build
{
format: 'esm',
file: 'dist/index.development.mjs',
sourcemap: true,
compact: false
},
// Production build
{
format: 'esm',
file: 'dist/index.production.mjs',
sourcemap: false,
compact: true
}
]
}
})Bundle Size Optimization
export default defineConfig({
rollup: {
output: {
format: 'esm',
file: 'dist/index.mjs',
// Optimize for size
compact: true,
generatedCode: {
preset: 'es2015',
arrowFunctions: true,
constBindings: true,
objectShorthand: true
}
}
}
})Related Options
- Output Directory - Configure where files are written
- Entry - Configure entry points for different formats
- Package Exports - Automatic package.json exports
- Target - JavaScript compilation targets