zachleat/import-module-string
import-module-string
Use import('data:') and import(Blob) to execute arbitrary JavaScript strings. A simpler alternative to node-retrieve-globals that works in more runtimes.
Installation
Available on npm as import-module-string.
npm install import-module-string
Features
- Multi-runtime: tested with Node (22.18+), Deno (limited), Chromium, Firefox, and WebKit.
- Defers to
exportwhen used, otherwise implicitlyexportall globals (viavar,let,const,function,ArrayorObjectdestructuring assignment,importspecifiers, etc) - Supports top-level async/await (as expected for ES modules)
- Emulates
import.meta.urlwhenfilePathoption is supplied addRequireoption adds support forrequire()(in Node)- Extremely limited dependency footprint (
acornfor JS parsing only) - Supports data object to pass in data (must be JSON.stringify friendly, more serialization options may be added later)
- Subject to URL content size maximums: Chrome
512MB, Safari2048MB, Firefox512MB, Firefox prior to v13732MB
| Feature | Server | Browser |
|---|---|---|
import('./file.js') | ✅ | ✅ (Import Map-friendly) |
import('bare') | ✅ | ✅ (Import Map-friendly) |
import('built-in') | ✅ | N/A |
require() | ✅ with addRequire option | ❌ |
import.meta.url | ✅ with filePath option | ✅ with filePath option |
Notes:
- built-in modules are provided by the JavaScript runtime.
node:fsis one example. barespecifiers are packages referenced by their bare name. In Node this might be a package installed from npm.
Usage
Import the script first!
import { importFromString } from "import-module-string";
View the test suite file for more examples.
TypeScript
Type declarations are included. Pass a type argument to describe the returned exports:
import { importFromString, type ImportFromStringOptions } from "import-module-string";
const options: ImportFromStringOptions = { data: { b: 2 } };
const { a } = await importFromString<{ a: number }>("const a = b;", options);
Export
await importFromString(`export var a = 1;
export const c = 3;
export let b = 2;`);
// Returns
{ a: 1, c: 3, b: 2 }
No export
import { importFromString } from "import-module-string";
await importFromString(`var a = 1;
const c = 3;
let b = 2;`);
// Returns
{ a: 1, c: 3, b: 2 }
Pass in data
await importFromString("const a = b;", { data: { b: 2 } });
// Returns
{ a: 2 }
Pass in filePath
await importFromString("const a = import.meta.url;", { filePath: import.meta.url });
// Returns value for import.meta.url, example shown
{ a: `file:///…` }
Compile as a function
compileAsFunction returns a default-exported async function instead of executing the code, so you can pass live values (functions, class instances) without serialization. Undeclared identifiers become its arguments and it resolves with the exports (or implicit exports), so names the code declares itself always win.
let mod = await importFromString("const a = await fn(b);", { compileAsFunction: true });
await mod.default({ fn: async n => n * 2, b: 2 });
// Returns
{ a: 4 }
Imports (experimental feature)
Relative references
// `dependency.js` has the content `export default 2;`
await importFromString("import dep from './dependency.js';");
// Returns
{ dep: 2 }
Bare references
Uses import.meta.resolve to resolve paths, which will also resolve using Import Maps (where available).
// maps with `import.meta.resolve("@zachleat/noop"))` in-browser (Import Map friendly)
await importFromString("import {noop} from '@zachleat/noop';");
// Returns
{ noop: function() {} }
Builtins
await importFromString("import fs from 'node:fs';");
// Returns (where available: `node:fs` is not typically available in browser)
{ fs: { /* … */ } }
As a side note, you can shim fs into the browser with memfs.
Changelog
v4.0.0compileAsFunctionreturns anasyncfunction (supports top-levelawait) and respectsimplicitExportswhen the code has noexport. Adds support forexportaliases,export … fromandexport *(#3).v3.0.0bump Node support minimum to 22.18+v2.0.0removesadapter(no longer necessary!)v1.0.5bug fixesv1.0.4addadapteroption (addadapter: "fs"oradapter: "fetch") to resolve imports in various environments.