Getting Started

Install Packem and create your first bundle in under five minutes

Getting Started

This guide takes you from zero to a published-ready bundle. You will install Packem, configure your package.json, and run your first build.

Install Packem

Add Packem as a dev dependency:

npm install --save-dev @visulima/packem

Scaffold your project

The quickest way to set up is the interactive init command:

npx packem init

It will analyze your project, ask about your preferences (transformer, CSS preprocessor, etc.), generate a packem.config.ts, and update your package.json with recommended settings.

The init command detects existing configurations and suggests optimal settings for your project.

Add optional features

After init, you can enable additional presets:

npx packem add react     # React preset and dependencies
npx packem add solid     # SolidJS preset and dependencies
npx packem add css       # CSS loaders (PostCSS, Sass, Less, etc.)
npx packem add typedoc   # TypeDoc documentation generation

Each command updates your config and installs the necessary dependencies.

Project structure

Packem expects a conventional layout:

my-package/
├── src/
│   ├── index.ts          # Main entry point
│   ├── cli.ts            # CLI entry (optional)
│   └── utils/
│       └── helper.ts
├── package.json
├── packem.config.ts
└── tsconfig.json

Configure package.json

Packem reads your package.json to decide what to build and how. Pick the pattern that matches your use case:

{
  "name": "my-package",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/index.js",
  "module": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "scripts": {
    "build": "packem build",
    "dev": "packem build --watch"
  }
}
{
  "name": "my-package",
  "files": ["dist"],
  "main": "./dist/index.cjs",
  "module": "./dist/index.mjs",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.mts",
        "default": "./dist/index.mjs"
      },
      "require": {
        "types": "./dist/index.d.cts",
        "default": "./dist/index.cjs"
      }
    }
  },
  "scripts": {
    "build": "packem build",
    "dev": "packem build --watch"
  }
}
{
  "name": "my-cli",
  "type": "module",
  "files": ["dist"],
  "bin": "./dist/cli.js",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "scripts": {
    "build": "packem build",
    "dev": "packem build --watch"
  }
}

Packem detects entry points from the exports, main, module, and bin fields automatically — no duplicate configuration needed.

Write your config

Create packem.config.ts in the project root:

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

export default defineConfig({
  transformer,
  sourcemap: true,
})

Run the build

npm run build

Packem will find your source files in src/, transform them with esbuild, and write the output to dist/:

my-package/
├── dist/
│   ├── index.js       # Bundled JavaScript
│   └── index.d.ts     # TypeScript declarations
└── ...

For development, use watch mode so Packem rebuilds on every save:

npm run dev

Full example

Here is a minimal library from scratch:

src/index.ts

export function greet(name: string): string {
  return `Hello, ${name}!`
}

export function add(a: number, b: number): number {
  return a + b
}

package.json

{
  "name": "my-utils",
  "type": "module",
  "files": ["dist"],
  "main": "./dist/index.js",
  "types": "./dist/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/index.d.ts",
      "default": "./dist/index.js"
    }
  },
  "scripts": {
    "build": "packem build"
  }
}

packem.config.ts

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

export default defineConfig({
  transformer,
  sourcemap: true,
})

Run npm run build and you are done.

Troubleshooting

Entry points not found — Make sure your package.json has exports, main, or module fields and that the matching source files exist in src/.

TypeScript errors — Verify you have a valid tsconfig.json and TypeScript installed.

Build failing — Run packem build --verbose for detailed error output.

Need more help? Open an issue on GitHub.

Next steps

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