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
- Web standards or built-in Deno APIs;
- TypeScript-first JSR packages, especially
@std/*; - npm packages through
npm:ordeno add; - 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.