Skip to main content
On this page

deno pack

The deno pack command builds an npm-compatible tarball (.tgz) from a Deno project, so you can publish a Deno-authored library straight to the npm registry. It transpiles TypeScript to JavaScript, generates .d.ts declaration files, rewrites import specifiers, and synthesizes a package.json that npm-only consumers can understand.

deno pack is not equivalent to npm pack. It's a build step that converts a Deno/JSR project into an npm-publishable package — closer to deno transpile plus npm pack combined. It does not read an existing package.json, does not honor .npmignore, and does not run prepublishOnly / prepare lifecycle scripts.

Quick start Jump to heading

>_
deno pack

deno pack reads the package metadata from deno.json (the name, version, and exports you'd use to publish to JSR) and writes a gzipped tarball to the current directory.

Given a deno.json like:

deno.json
{
  "name": "@scope/my-lib",
  "version": "1.0.0",
  "exports": "./mod.ts"
}

deno pack produces scope-my-lib-1.0.0.tgz (the @ is stripped and / becomes -, matching npm pack's naming convention).

What's in the tarball Jump to heading

Contents
A generated package.json with name, version, type: "module", conditional exports (types / import / default), and a dependencies field derived from your jsr: / npm: imports.
Transpiled .js files (with inline source maps by default; pass --no-source-maps to omit).
Generated .d.ts declaration files (produced via the same fast-check pipeline as deno publish).
README and LICENSE files from the project root, if present.

Only files reachable through the module graph from exports are included. Non-JS assets such as data files or WASM are only included if they're imported from JS/TS. If you need to ship arbitrary files, list them as positional arguments:

>_
deno pack assets/icon.svg locales/*.json

Specifier rewriting Jump to heading

For the generated package to work on Node and other npm consumers, deno pack rewrites imports as it transpiles:

In your source In the tarball Notes
jsr:@std/path @jsr/std__path Consumers need the JSR npm registry configured.
npm:express@4 express Version moves into dependencies in package.json.
./utils.ts ./utils.js Extension only — no path restructuring.
node:fs node:fs Unchanged.

Because JSR imports turn into @jsr/... specifiers, anyone installing the published tarball needs the JSR npm registry configured. The simplest way is to run npx jsr add once in the consumer project; that sets up the .npmrc entries for the @jsr scope.

Deno API shimming Jump to heading

If your code uses the Deno.* global, deno pack adds @deno/shim-deno as a runtime dependency and injects the shim so the package can run under Node.js. The shim covers the subset of Deno.* that maps cleanly onto Node APIs — review the shim's docs to see what's polyfilled.

Pass --no-deno-shim to opt out, e.g. if you've already provided your own abstraction or only intend the package to run under Deno-on-npm.

Publishing to npm Jump to heading

>_
deno pack
npm publish ./scope-my-lib-1.0.0.tgz

A typical release flow:

>_
# 1. Bump the version
deno bump-version patch

# 2. Build the tarball
deno pack

# 3. Verify the contents (extracted view)
tar -tzf scope-my-lib-1.0.0.tgz

# 4. Push to npm
npm publish ./scope-my-lib-1.0.0.tgz

For JSR releases, use deno publish instead — deno pack is specifically for the npm registry.

Workspace support Jump to heading

In a workspace, deno pack runs against the current working directory's member. To pack a specific member from the root:

>_
cd packages/my-lib
deno pack

Cross-workspace npm: / jsr: dependencies are rewritten in the generated package.json to point at their published versions, not to other workspace members — make sure those dependencies have been released independently before publishing your tarball.

Examples Jump to heading

Override the version Jump to heading

Useful when releasing a one-off prerelease without editing deno.json:

>_
deno pack --set-version 2.0.0-rc.1

Pick the output path Jump to heading

>_
deno pack --output dist/my-package.tgz

Preview without writing Jump to heading

>_
deno pack --dry-run

--dry-run prints what would be in the tarball without producing one — handy in CI to verify file inclusion rules.

Allow slow types Jump to heading

Slow types prevent .d.ts generation. Pass --allow-slow-types to pack anyway; the tarball will not include declaration files.

>_
deno pack --allow-slow-types

Skip the Deno shim Jump to heading

>_
deno pack --no-deno-shim

Pack despite a dirty working tree Jump to heading

>_
deno pack --allow-dirty

By default deno pack refuses to pack when the git working tree has uncommitted changes, to make releases reproducible from the commit hash.

Exclude files Jump to heading

>_
deno pack --ignore=tests/ --ignore='**/*.test.ts'

--ignore accepts glob patterns. Combine multiple --ignore flags to add patterns.

Omit source maps Jump to heading

>_
deno pack --no-source-maps

By default, source maps are inlined in the emitted .js files. Use --no-source-maps to strip them — smaller tarballs, but harder to debug upstream.

Limitations Jump to heading

  • No bin entries. deno pack does not synthesize the package.json bin field. Library publishing is supported; CLI tools that need a node-shebanged executable still need a hand-rolled npm package.
  • No native addons. Packages that link against native code or ship a node-gyp build step are out of scope.
  • No .npmignore. Use --ignore for excludes; .gitignore is honored for what's considered part of the project.
  • No lifecycle scripts. prepublishOnly / prepare / postinstall hooks from a hand-written package.json are not run because the package.json is generated, not read.

When to use deno pack vs deno publish Jump to heading

Need Use
Release to JSR deno publish
Release the same library to npm deno packnpm publish ./*.tgz
Reach Node-only consumers without forcing JSR setup deno pack (rewrites JSR imports for them)

A library can ship to both — release to JSR with deno publish, then build and push a tarball to npm with deno pack for users who haven't adopted JSR yet.

See also Jump to heading

Command line usage:
deno pack [OPTIONS] [files]...

Create an npm-compatible tarball from a Deno project

Options Jump to heading

--allow-dirty
Jump to heading

Allow packing if the repository has uncommitted changes.

--allow-slow-types
Jump to heading

Skip fast-check type extraction; .d.ts files are omitted from the output.

Configure different aspects of deno including TypeScript, linting, and code formatting. Typically the configuration file will be called deno.json or deno.jsonc and automatically detected; in that case this flag is not necessary.

Show what would be packed without creating the tarball.

--ignore<ignore>
Jump to heading

Ignore files matching these patterns.

--no-config
Jump to heading

Disable automatic loading of the configuration file.

--no-deno-shim
Jump to heading

Don't automatically add @deno/shim-deno dependency.

--no-source-maps
Jump to heading

Don't include source maps in the output.

--output, -o<FILE>
Jump to heading

Output file path (defaults to -.tgz).

--set-version<VERSION>
Jump to heading

Override the version in the tarball.

Last updated on

Did you find what you needed?

Privacy policy