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
      }
    }
  }
})

  • Output Directory - Configure where files are written
  • Entry - Configure entry points for different formats
  • Package Exports - Automatic package.json exports
  • Target - JavaScript compilation targets
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