Configuration
Complete guide to configuring Packem for your project needs
Configuration
Learn how to configure Packem to meet your specific project requirements with detailed examples and best practices.
Configuration File
Packem uses a packem.config.ts file for configuration. This file should be placed in your project root.
Basic Configuration
import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
transformer,
sourcemap: true,
declaration: true
})Configuration Options
Core Options
transformer
Specify which transformer to use for code compilation:
// esbuild (default, fastest)
import esbuild from '@visulima/packem/transformer/esbuild'
// swc (Rust-powered)
import swc from '@visulima/packem/transformer/swc'
// OXC (experimental)
import oxc from '@visulima/packem/transformer/oxc'
// sucrase (lightweight)
import sucrase from '@visulima/packem/transformer/sucrase'
export default defineConfig({
transformer: esbuild // or swc, oxc, sucrase
})sourcemap
Control source map generation:
export default defineConfig({
sourcemap: true, // Generate source maps
sourcemap: false, // No source maps
sourcemap: 'inline', // Inline source maps
sourcemap: 'hidden' // Hidden source maps
})declaration
Generate TypeScript declaration files:
export default defineConfig({
declaration: true, // Generate .d.ts files
declaration: false, // Skip declaration generation
declaration: 'compatible', // Generate compatible declarations
declaration: 'node16' // Generate node16 declarations
})minify
Control code minification:
export default defineConfig({
minify: true, // Enable minification
minify: false, // Disable minification
})Entry Points
Automatic Detection
Packem automatically detects entry points from your package.json:
{
"exports": {
".": "./src/index.ts",
"./utils": "./src/utils.ts"
}
}Manual Configuration
Override automatic detection:
export default defineConfig({
entries: [
'src/index.ts',
'src/cli.ts',
'src/utils.ts'
]
})Entry Objects
Use objects for more control:
export default defineConfig({
entries: [
{
input: 'src/index.ts',
outDir: 'dist'
},
{
input: 'src/cli.ts',
outDir: 'dist/bin'
}
]
})Rollup Configuration
Packem is built on Rollup, so you can use any Rollup options:
export default defineConfig({
rollup: {
external: ['react', 'react-dom'],
output: {
banner: '/* My Library v1.0.0 */',
footer: '/* End of bundle */'
},
plugins: [
// Additional Rollup plugins
],
watch: {
include: 'src/**',
exclude: 'node_modules/**'
}
}
})CSS Configuration
Quick Setup:
Use the add command to interactively configure CSS loaders:
npx packem add cssThis will:
- Prompt you to select a main CSS loader (PostCSS, Lightning CSS, or Tailwind CSS)
- Ask about additional loaders (Sass, Less, Stylus)
- Optionally configure CSS minification
- Install all necessary dependencies
- Update your
packem.config.tsautomatically
Manual Configuration:
import postcssLoader from '@visulima/packem/css/loader/postcss'
import sassLoader from '@visulima/packem/css/loader/sass'
import lessLoader from '@visulima/packem/css/loader/less'
import stylusLoader from '@visulima/packem/css/loader/stylus'
import sourceMapLoader from '@visulima/packem/css/loader/sourcemap'
import cssnanoMinifier from '@visulima/packem/css/minifier/cssnano'
import lightningcssMinifier from '@visulima/packem/css/minifier/lightningcss'
export default defineConfig({
rollup: {
css: {
mode: 'extract', // or 'inject'
loaders: [postcssLoader, sassLoader, lessLoader, stylusLoader, sourceMapLoader],
minifier: cssnanoMinifier
}
}
})Native Modules Configuration
Configure native Node.js addon (.node files) handling:
import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
transformer,
rollup: {
nativeModules: {
nativesDirectory: 'natives' // Custom directory name
}
}
})The native modules plugin automatically:
- Detects
.nodefile imports - Copies native modules to the output directory
- Generates appropriate
require()statements - Handles name collisions and platform-specific files
Options:
nativesDirectory: Directory name for native modules (default:'natives')
After bundling, the .node file will be copied to dist/natives/ and the import will be automatically rewritten to load from the correct location at runtime.
[!NOTE]
- Native modules are platform and architecture-specific. Make sure to distribute the correct
.nodefiles for your target platforms.- This only works with direct
.nodeimports. If you're using packages that dynamically load native modules viabindingsornode-pre-gyp, you'll need to handle them separately.
Handling dependencies with native modules
If you're using packages with native modules (like chokidar which depends on fsevents):
- If in
dependencies/peerDependencies: ✅ Works automatically - these are externalized (not bundled) - If in
devDependencies: ⚠️ Will be bundled. If they usebindings()ornode-pre-gyppatterns, move them todependenciesinstead, or useoptionalDependenciesif they're optional.
Example - if you have chokidar in devDependencies and get build errors, move it to dependencies:
{
"dependencies": {
"chokidar": "^3.0.0"
}
}This externalizes it (users will need to install it), avoiding the need to bundle its native modules.
Advanced Configurations
Multi-Format Builds
Build multiple output formats by configuring package.json properly:
{
"type": "module",
"main": "./dist/index.cjs",
"module": "./dist/index.js",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js",
"require": "./dist/index.cjs"
}
}
}Environment-Specific Config
const isDev = process.env.NODE_ENV === 'development'
export default defineConfig({
sourcemap: isDev,
minify: !isDev,
declaration: !isDev,
rollup: {
watch: isDev ? {
include: 'src/**'
} : undefined
}
})Conditional Configuration
import esbuildTransformer from '@visulima/packem/transformer/esbuild'
import swcTransformer from '@visulima/packem/transformer/swc'
export default defineConfig({
transformer: process.env.TRANSFORMER === 'swc'
? swcTransformer
: esbuildTransformer,
externals: process.env.BUNDLE_DEPS
? []
: ['react', 'react-dom']
})Library-Specific Configurations
React Library
Quick Setup (Recommended):
Use the add command to automatically configure React:
npx packem add reactThis will:
- Add
preset: 'react'to your config - Install React, React DOM, and Babel dependencies
- Automatically detect TypeScript and add
@types/reactand@types/react-domif TypeScript is installed - Prompt you to add TypeScript if not already installed
Manual Configuration:
import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
preset: 'react', // Automatically configures Babel for React
transformer,
sourcemap: true,
declaration: true,
externals: ['react', 'react-dom'],
rollup: {
css: {
mode: 'extract'
}
}
})With React Compiler:
import { defineConfig } from '@visulima/packem/config'
import { createReactPreset } from '@visulima/packem/config/preset/react'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
preset: createReactPreset({
compiler: true // Enable React Compiler optimization
}),
transformer,
sourcemap: true,
declaration: true,
externals: ['react', 'react-dom'],
rollup: {
css: {
mode: 'extract'
}
}
})Manual Configuration:
import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
transformer,
sourcemap: true,
declaration: true,
externals: ['react', 'react-dom'],
rollup: {
babel: {
presets: [
['@babel/preset-react', { runtime: 'automatic' }],
['@babel/preset-typescript', { allExtensions: true, isTSX: true }]
]
},
css: {
mode: 'extract'
}
}
})SolidJS Library
Quick Setup (Recommended):
Use the add command to automatically configure SolidJS:
npx packem add solidThis will:
- Add
preset: 'solid'to your config - Install SolidJS and Babel dependencies
Manual Configuration:
import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
preset: 'solid', // Automatically configures Babel for SolidJS
transformer,
sourcemap: true,
declaration: true,
externals: ['solid-js', 'solid-js/web', 'solid-js/store'],
rollup: {
css: {
mode: 'extract'
}
}
})With SSR Support:
import { defineConfig } from '@visulima/packem/config'
import { createSolidPreset } from '@visulima/packem/config/preset/solid'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
preset: createSolidPreset({
solidOptions: {
generate: 'ssr',
hydratable: true
}
}),
transformer,
sourcemap: true,
declaration: true,
externals: ['solid-js', 'solid-js/web', 'solid-js/store'],
rollup: {
css: {
mode: 'extract'
}
}
})Manual Configuration:
import { defineConfig } from '@visulima/packem/config'
import transformer from '@visulima/packem/transformer/esbuild'
export default defineConfig({
transformer,
sourcemap: true,
declaration: true,
externals: ['solid-js', 'solid-js/web', 'solid-js/store'],
rollup: {
babel: {
presets: [
['babel-preset-solid', { generate: 'dom' }],
['@babel/preset-typescript', { allExtensions: true, isTSX: true }],
['@babel/preset-env', { bugfixes: true, targets: 'last 2 years' }]
]
},
css: {
mode: 'extract'
}
}
})Node.js Library
export default defineConfig({
transformer,
runtime: 'node',
externals: (id) => !id.startsWith('.') && !id.startsWith('/')
})CLI Tool
export default defineConfig({
entries: [
{
input: 'src/cli.ts',
executable: true
}
],
externals: ['fs', 'path', 'process']
})Browser Library
export default defineConfig({
transformer,
runtime: 'browser',
minify: true
})Configuration Patterns
Shared Configuration
Create reusable configuration:
// config/base.ts
export const baseConfig = {
transformer,
sourcemap: true,
declaration: true
}
// packem.config.ts
import { baseConfig } from './config/base'
export default defineConfig({
...baseConfig,
// Project-specific overrides
})Factory Functions
// config/factory.ts
export function createConfig(options: {
target: 'node' | 'browser'
format: string[]
}) {
return defineConfig({
transformer,
format: options.format,
target: options.target,
rollup: {
external: options.target === 'node'
? (id) => !id.startsWith('.')
: []
}
})
}
// packem.config.ts
import { createConfig } from './config/factory'
export default createConfig({
target: 'node',
format: ['cjs', 'esm']
})Plugin System
// plugins/banner.ts
export function bannerPlugin(text: string) {
return {
rollup: {
output: {
banner: text
}
}
}
}
// packem.config.ts
export default defineConfig({
transformer,
...bannerPlugin('/* My Library */'),
})TypeScript Integration
Type Checking
Enable type checking during build:
export default defineConfig({
transformer: typescript, // Use TypeScript compiler
declaration: true,
rollup: {
typescript: {
check: true, // Enable type checking
verbosity: 2, // Detailed output
clean: true // Clean previous declarations
}
}
})Path Mapping
Support TypeScript path mapping:
// tsconfig.json
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"],
"@utils/*": ["./src/utils/*"]
}
}
}
// packem.config.ts
export default defineConfig({
transformer,
rollup: {
typescript: {
tsconfig: './tsconfig.json'
}
}
})Debugging Configuration
Verbose Output
export default defineConfig({
transformer,
rollup: {
verbose: true,
logLevel: 'debug'
}
})Bundle Analysis
import { visualizer } from 'rollup-plugin-visualizer'
export default defineConfig({
transformer,
rollup: {
plugins: [
visualizer({
filename: 'dist/stats.html',
open: true
})
]
}
})Best Practices
Performance Optimization
export default defineConfig({
transformer: esbuild, // Fastest transformer
sourcemap: false, // Disable in production
declaration: {
isolated: true // Faster declarations
},
rollup: {
treeshake: true, // Enable tree shaking
external: [ // Externalize dependencies
'react',
'react-dom'
]
}
})Development Experience
const isDev = process.env.NODE_ENV === 'development'
export default defineConfig({
sourcemap: isDev ? true : false,
declaration: !isDev,
rollup: {
watch: isDev ? {
include: 'src/**',
clearScreen: false
} : undefined
}
})Always test your configuration with both development and production builds to ensure everything works correctly.
Common Issues
External Dependencies
Make sure to externalize peer dependencies:
export default defineConfig({
rollup: {
external: ['react', 'react-dom', 'lodash']
}
})CSS Processing
Configure CSS loaders properly:
export default defineConfig({
rollup: {
css: {
extract: true, // Extract CSS to separate files
modules: true // Enable CSS modules
}
}
})Declaration Generation
Ensure TypeScript configuration is correct:
// tsconfig.json
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"outDir": "dist"
}
}This configuration guide provides a comprehensive foundation for setting up Packem in any project scenario.