node-url-import
v0.0.2
Published
Node.js hook to import modules from HTTP(S) URLs
Maintainers
Readme
node-url-import
Node.js hook that lets you import modules directly from HTTP(S) URLs like Deno.
import { add } from "https://esm.sh/lodash-es";
console.log(add(1, 2)); // 3Works with static imports, dynamic import(), and relative imports inside remote modules. Fetched modules are cached on disk so subsequent runs are instant.
Usage
CLI
Like ts-node — a drop-in wrapper around node with the hook pre-loaded:
node-url-import [options] [node-flags] <script-or-url> [script-args...]Flags before the script are split into node-url-import options and Node.js flags. Flags after the script are forwarded to the remote script as-is.
# Run a local file that imports from URLs
node-url-import ./app.mjs
# Run a remote URL directly
node-url-import https://raw.esm.sh/armor64/dist/cli.js
# Re-fetch all remote modules (bypass cache)
node-url-import -r ./app.mjs
# Pass Node.js flags (e.g. --inspect)
node-url-import --inspect ./app.mjs
# Forward flags to the remote script
node-url-import https://raw.esm.sh/nrm-lite/cli.mjs -h
# Write a lock file (Deno-compatible format)
node-url-import --lock ./app.mjs
# Error if lock file is out of date
node-url-import --lock --frozen ./app.mjs
# Clear the disk cache
node-url-import --clear-cacheLoader hook
Register the hook yourself with --import:
node --import node-url-import/register ./app.mjsOr the legacy --loader flag:
node --loader node-url-import/loader ./app.mjsnpm: specifiers
Modules can use Deno-style npm: specifiers to import from node_modules. The version is stripped and the module is resolved by Node's default resolver:
import ms from "npm:ms";
import ms from "npm:[email protected]"; // version stripped → "ms"
import add from "npm:lodash-es@4/add"; // → "lodash-es/add"
import node from "npm:@types/node@22"; // → "@types/node"Programmatic API
import { fetchModule, clearCache } from "node-url-import";
const { source, contentType } = await fetchModule(
"https://esm.sh/lodash-es/add",
);
console.log(source);
await clearCache();How it works
- The ESM loader hooks (
resolve+load) intercept any specifier starting withhttp://orhttps://. - Relative imports inside remote modules (e.g.
import "./util.js"fromhttps://esm.sh/...) resolve back to the same origin. Bare specifiers like"node:fs"fall through to Node's default resolver. - Fetched sources are cached at
~/.cache/node-url-import/keyed by SHA-256 of the URL. - Cached modules are used forever until
--reloadis passed or--clear-cacheis used (same as Deno). - Module format is inferred from the
Content-Typeheader and URL extension, defaulting to ESM. - A Deno-style progress bar is shown on stderr during downloads (only on TTY).
Options
| Flag | Description |
| -------------------- | -------------------------------------------------------------------------- |
| -r, --reload | Bypass cache, re-fetch all remote modules |
| --lock | Check/write a lock file (default: ./deno.lock) |
| --lock-file <path> | Lock file path (implies --lock) |
| --frozen | Error if lock file is out of date (use with --lock) |
| --local-meta | Rewrite import.meta.url to a local file:// URL (fixes createRequire) |
| --clear-cache | Purge the disk cache |
Any unrecognized flags before the script are forwarded to Node.js (e.g. --inspect, --env-file).
Lock file
When --lock is passed, node-url-import writes a lock file recording the SHA-256 hash of every fetched remote module. The format is compatible with Deno's deno.lock:
{
"version": "5",
"redirects": {
"https://raw.esm.sh/armor64/dist/cli.js": "https://raw.esm.sh/[email protected]/dist/cli.js"
},
"remote": {
"https://raw.esm.sh/[email protected]/dist/cli.js": "8513c973713ea38737552521eb52529ac880555fbb6fbba8ff8571cec27872c5"
}
}redirects: maps original URLs to their final redirected URLsremote: maps final URLs to SHA-256 hashes of the source
On subsequent runs with --lock, fetched content is verified against the recorded hashes. Use --frozen to error on any mismatch instead of updating.
Environment variables
| Variable | Description | Default |
| ------------------------- | ----------------------- | -------------------------- |
| URL_IMPORT_CACHE_DIR | Custom cache directory | ~/.cache/node-url-import |
| URL_IMPORT_RELOAD=1 | Same as --reload | |
| URL_IMPORT_LOCK=<path> | Same as --lock <file> | |
| URL_IMPORT_FROZEN=1 | Same as --frozen | |
| URL_IMPORT_LOCAL_META=1 | Same as --local-meta | |
