Using Lodash with Deno's Strict Module Resolution
Deno enforces strict, browser-compatible module resolution that
requires explicit file extensions, full URLs, and standard ECMAScript
Modules (ESM). Because Lodash was originally designed for Node.js’s
implicit CommonJS module system, running it in Deno requires bridging
these architectural differences. This guide explains how Lodash
integrates with Deno using modern ESM CDNs, native npm:
specifiers, and import maps to satisfy Deno’s resolution engine.
The Compatibility Challenge
Node.js allows implicit module resolution—such as resolving
require('lodash') to a local node_modules
directory and automatically locating an index.js file. In
contrast, Deno does not look into a local node_modules
folder by default, nor does it automatically infer file extensions or
directory indexes. Deno requires fully qualified URLs or explicit
relative file paths terminating with an extension (such as
.js or .ts). Because the standard
lodash package relies on CommonJS, integrating it requires
formats that Deno can statically parse.
Method 1: Using the
Native npm: Specifier
The most modern and straightforward method to integrate Lodash into
Deno is via the native npm: protocol. Deno includes
built-in compatibility for npm packages, handling module resolution and
CommonJS-to-ESM translation automatically in a managed cache.
To import the standard CommonJS version:
import _ from "npm:lodash@^4.17.21";
const numbers = [1, 2, 3, 4, 5];
console.log(_.chunk(numbers, 2));For better tree-shaking and native ESM execution, use
lodash-es:
import { chunk, compact } from "npm:lodash-es@^4.17.21";
console.log(chunk([1, 2, 3, 4], 2));Using npm: bypasses the need for external CDNs while
strictly adhering to Deno's resolution syntax. Deno downloads the
package to a global cache, resolves dependencies, and exposes the module
interface.
Method 2: Using ESM CDNs
Before native npm resolution was introduced, ESM CDNs emerged as the
standard way to load third-party libraries in Deno. CDNs such as
esm.sh rewrite CommonJS packages into standard ES modules
on the fly, adding necessary file extensions to satisfy Deno's strict
URL loading rules.
import _ from "https://esm.sh/lodash-es@4.17.21";
const data = [0, 1, false, 2, "", 3];
console.log(_.compact(data));You can also import individual utilities to reduce bundle overhead:
import debounce from "https://esm.sh/lodash-es@4.17.21/debounce";CDNs inspect the incoming request headers from Deno and serve an ESM
wrapper alongside appropriate X-TypeScript-Types headers,
ensuring both runtime compatibility and static type checking without
manual configuration.
Method 3: Simplifying Imports with Import Maps
Repeating npm: specifiers or full CDN URLs throughout a
project makes refactoring tedious. Deno allows you to normalize these
imports using an import map defined inside deno.json or
deno.jsonc.
Configure your deno.json:
{
"imports": {
"lodash": "npm:lodash-es@^4.17.21",
"lodash/": "npm:lodash-es@^4.17.21/"
}
}Once configured, your application files can use standard bare specifiers:
import { shuffle } from "lodash";
import sortBy from "lodash/sortBy.js";
const items = [3, 1, 2];
console.log(shuffle(items));
console.log(sortBy(items));This approach combines the clean syntax of traditional JavaScript ecosystems with the strict resolution requirements enforced by Deno's runtime.