Modules and import maps

Manage clear module boundaries with ESM, JSR, npm, and deno.json imports

Deno-first code uses standard ESM, and local imports include their real extension:

import { add } from "./math.ts";
import { join } from "jsr:@std/path";
import React from "npm:react";

Do not scatter versions through every source file. Use deno add to write project aliases to deno.json:

deno add jsr:@std/path npm:react
{
  "imports": {
    "@std/path": "jsr:@std/path@^1.1.2",
    "react": "npm:react@^19.2.0",
    "@/": "./src/"
  }
}

Then import stable names:

import { join } from "@std/path";
import { loadConfig } from "@/config.ts";

Selection order

  1. Web standards or built-in Deno APIs;
  2. TypeScript-first JSR packages, especially @std/*;
  3. npm packages through npm: or deno add;
  4. direct HTTPS imports only when necessary, with a trusted pinned source.

A computed dynamic import is outside the static module graph: a local path needs --allow-read, while a remote URL needs --allow-import. Static imports behave differently.

Official references: Modules and Import maps example.

Type to search all documentation.