Skip to main content
On this page

Add and remove dependencies

Deno manages dependencies through your project's deno.json import map, or through package.json when you have one. The deno add and deno remove commands edit those files for you, and deno install with a package argument does the same.

Adding packages Jump to heading

Unprefixed package names are treated as npm packages. Use the jsr: prefix for JSR packages:

>_
$ deno add express jsr:@std/path
Add npm:express@5.2.1
Add jsr:@std/path@1.1.5

deno install express is equivalent: it records the dependency the same way and installs everything in one step.

Both end up in the imports map of deno.json, with a semver-compatible caret range:

deno.json
{
  "imports": {
    "@std/path": "jsr:@std/path@^1.1.5",
    "express": "npm:express@^5.2.1"
  }
}

Import them by their bare name anywhere in the project:

import express from "express";
import { join } from "@std/path";

To pin an exact version instead of a caret range, pass --save-exact. To request a specific version or tag, spell it out:

>_
deno add --save-exact npm:express@4.21.2
deno add npm:typescript@next

Where dependencies are written Jump to heading

If the project contains a package.json, npm packages are added to its dependencies instead of deno.json, which is handy in projects shared with Node.js tooling. You can force this with --package-json.

Dev dependencies only exist in the package.json world:

>_
deno add --dev npm:typescript

Note

Without a package.json, the --dev flag has no effect: deno.json has a single imports map, so the package is added as a regular import.

Aliasing a package Jump to heading

The import map maps any name you like to any specifier. This installs a fork under the name of the original, so existing imports keep working:

deno.json
{
  "imports": {
    "lodash": "npm:lodash-es@^4.17.21"
  }
}

Aliases are also the way to use two versions of one package side by side:

deno.json
{
  "imports": {
    "preact": "npm:preact@^10.27.2",
    "preact-canary": "npm:preact@11.0.0-experimental.4"
  }
}

Overriding transitive dependencies Jump to heading

The import map only names your direct dependencies. To force a specific version of a package somewhere deeper in the tree, use the overrides field in package.json, the same way npm does:

package.json
{
  "dependencies": {
    "debug": "4.4.3"
  },
  "overrides": {
    "ms": "2.1.2"
  }
}

deno install resolves ms to 2.1.2 everywhere it appears, and records that in the lockfile.

Removing packages Jump to heading

deno remove deletes the entry by its import-map name (not the package name, if they differ):

>_
$ deno remove express
Removed express

The lockfile keeps records of removed packages until you run deno install again; see the lockfile documentation for how deno.lock tracks all of this.

Did you find what you needed?

Edit this page
Privacy policy