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:
{
"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
binentries.deno packdoes not synthesize thepackage.jsonbinfield. Library publishing is supported; CLI tools that need anode-shebanged executable still need a hand-rolled npm package. - No native addons. Packages that link against native code or ship a
node-gypbuild step are out of scope. - No
.npmignore. Use--ignorefor excludes;.gitignoreis honored for what's considered part of the project. - No lifecycle scripts.
prepublishOnly/prepare/postinstallhooks from a hand-writtenpackage.jsonare not run because thepackage.jsonis 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 pack → npm 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
deno publish— release to JSRdeno transpile— the emit step thatdeno packuses internallydeno bump-version— bumpversionindeno.json/package.jsonbefore packing- Publishing modules — overview of where Deno-authored libraries can be published
deno pack [OPTIONS] [files]...Create an npm-compatible tarball from a Deno project
Options Jump to heading
--allow-dirtyAllow packing if the repository has uncommitted changes.
--allow-slow-typesSkip 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.
--dry-runShow what would be packed without creating the tarball.
--ignore<ignore>Ignore files matching these patterns.
--no-configDisable automatic loading of the configuration file.
--no-deno-shimDon't automatically add @deno/shim-deno dependency.
--no-source-mapsDon't include source maps in the output.
--output, -o<FILE>Output file path (defaults to
--set-version<VERSION>Override the version in the tarball.