JavaScript Package

Modern JavaScript package with zero configuration

JavaScript Package

Build a modern, ESM-only JavaScript package with Packem. There is no entry list to maintain: Packem infers the build entries from your package.json, and packem init scaffolds the transformer and config for you, so the setup is effectively zero-config.

Overview

This example demonstrates:

  • A plain JavaScript (no TypeScript) package
  • ESM-only output
  • Entry inference from package.json#exports
  • Generating the config with packem init

Project Setup

Directory Structure

my-package/
├── src/
│   └── index.js
├── package.json
└── packem.config.ts

Source File

src/index.js

/**
 * Slugify a string into a URL-friendly form.
 */
export function slugify(input) {
  return input
    .toLowerCase()
    .trim()
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '')
}

/**
 * Truncate a string to a maximum length.
 */
export function truncate(input, max = 80) {
  return input.length > max ? `${input.slice(0, max - 1)}…` : input
}

Configuration

package.json

With "type": "module" and a single exports entry, Packem builds one ESM bundle. No main/require condition means no CommonJS output is produced.

{
  "name": "@myorg/my-package",
  "version": "1.0.0",
  "description": "A modern JavaScript package",
  "type": "module",
  "files": [
    "dist"
  ],
  "module": "./dist/index.mjs",
  "exports": {
    ".": "./dist/index.mjs"
  },
  "scripts": {
    "build": "packem build",
    "dev": "packem build --watch"
  },
  "devDependencies": {
    "@visulima/packem": "^2",
    "esbuild": "^0.25.0"
  }
}

Generating the config

Run the interactive setup to pick a bundler and transformer and write the config file:

npx packem init

This scaffolds a minimal packem.config.ts:

packem.config.ts

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

export default defineConfig({
  transformer,
})

Packem reads the entries straight from package.json. Add another subpath to exports and it is picked up automatically — no config change required.

Building

npm run build

Output Structure

dist/
└── index.mjs        # ESM entry

Usage

import { slugify, truncate } from '@myorg/my-package'

slugify('Hello World!')          // "hello-world"
truncate('a very long sentence', 10) // "a very lo…"

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