import.meta.resolve()

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since March 2023.

import.meta.resolve() is a built-in function defined on the import.meta object of a JavaScript module that resolves a module specifier to a URL using the current module's URL as base.

Syntax

js
import.meta.resolve(moduleName)

Parameters

moduleName

A string that specifies a potentially importable module. This may be a relative path (such as "./lib/helper.js"), a bare name (such as "my-module"), or an absolute URL (such as "https://example.com/lib/helper.js").

Return value

Returns a string corresponding to the path that would be imported if the argument were passed to import().

Description

import.meta.resolve() allows a script to access the module specifier resolution algorithm for a name, like this:

js
// Script at https://example.com/main.js

const helperPath = import.meta.resolve("./lib/helper.js");
console.log(helperPath); // "https://example.com/lib/helper.js"

Note that import.meta.resolve() only performs resolution and does not attempt to load or import the resulting path. Therefore, its return value is the same regardless of whether the returned path corresponds to a file that exists, and regardless of whether that file contains valid code for a module. This allows import.meta.resolve() to be a synchronous operation.

It is different from dynamic import, because although both accept a module specifier as the first argument, import.meta.resolve() returns the path that would be imported without making any attempt to access that path. Therefore, the following two are effectively the same code:

js
// Approach 1
console.log(await import("./lib/helper.js"));

// Approach 2
const helperPath = import.meta.resolve("./lib/helper.js");
console.log(await import(helperPath));

However, even if "./lib/helper.js" cannot be successfully imported, the second snippet will not encounter an error until it attempts to perform the import on line 2.

Bare module names

You can pass a bare module name (also known as a bare module specifier) to import.meta.resolve(), as long as module resolution is defined for the name. For example, you can define this using an import map inside a browser:

html
<!-- index.html -->
<script type="importmap">
  {
    "imports": {
      "my-module": "./modules/my-module/index.js"
    }
  }
</script>

<script type="module">
  const moduleEntryPath = import.meta.resolve("my-module");
  console.log(moduleEntryPath);
</script>

Again, since this snippet does not try to import moduleEntryPath — neither does the import map — it prints the resolved URL regardless of whether ./modules/my-module/index.js actually exists.

Comparison with new URL()

The URL() constructor accepts a second base URL argument. When the first argument is a relative path and the base URL is import.meta.url, the effect is similar to import.meta.resolve().

js
const helperPath = new URL("./lib/helper.js", import.meta.url).href;
console.log(helperPath);

This is also a useful replacement syntax when targeting older browsers. However, there are some differences:

  • import.meta.resolve() returns a string, while new URL() returns a URL object. It is possible to use href or toString() on the constructed URL, but this may still not produce the exact same result in some JavaScript environments or when using tools like bundlers to statically analyze the code.
  • import.meta.resolve() is aware of additional resolution configurations, such as resolving bare module names using import maps, as described above. new URL() is not aware of import maps and treats bare module names as relative paths (i.e., new URL("my-module", import.meta.url) means new URL("./my-module", import.meta.url)).

Some tools recognize new URL("./lib/helper.js", import.meta.url).href as a dependency on "./lib/helper.js" (similar to an import), and take this into account for features like bundling, rewriting imports for moved files, "go to source" functionality, etc. However, since import.meta.resolve() is less ambiguous and specifically designed to indicate a module path resolution dependency, you should use import.meta.resolve(moduleName) instead of new URL(moduleName, import.meta.url) for these use cases wherever possible.

Not an ECMAScript feature

import.meta.resolve() is not specified or documented as part of the ECMAScript specification for JavaScript modules. Instead, the specification defines the import.meta object but leaves all its properties as "host-defined". The WHATWG HTML standard picks up where the ECMAScript standard leaves off, and defines import.meta.resolve using its module specifier resolution.

This means that import.meta.resolve() is not required to be implemented by all conformant JavaScript implementations. However, import.meta.resolve() may also be available in non-browser environments:

Examples

Resolve a path for the Worker() constructor

import.meta.resolve() is particularly valuable for APIs that take a path to a script file as an argument, such as the Worker() constructor:

js
// main.js
const workerPath = import.meta.resolve("./worker.js");
const worker = new Worker(workerPath, { type: "module" });
worker.addEventListener("message", console.log);
js
// worker.js
self.postMessage("hello!");

This is also useful to calculate paths for other workers, such as service workers and shared workers. However, if you are using a relative path to calculate the URL of a service worker, keep in mind that the directory of the resolved path determines its registration scope by default (although a different scope can be specified during registration).

Specifications

Specification
HTML
# import-meta-resolve

Browser compatibility

desktop mobile server
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Bun
Deno
Node.js
import.meta.resolve
Chrome – Full support
Chrome 105 (Release date: 2022-09-02)
footnote Full support
Edge – Full support
Edge 105 (Release date: 2022-09-01)
footnote Full support
Firefox – Full support
Firefox 106 (Release date: 2022-10-18)
footnote Full support
Opera – Full support
Opera 91 (Release date: 2022-09-14)
footnote Full support
Safari – Full support
Safari 16.4 (Release date: 2023-03-27)
footnote Full support
Chrome Android – Full support
Chrome Android 105 (Release date: 2022-09-02)
footnote Full support
Firefox for Android – Full support
Firefox for Android 106 (Release date: 2022-10-18)
footnote Full support
Opera Android – Full support
Opera Android 72 (Release date: 2022-10-21)
footnote Full support
Safari on iOS – Full support
Safari on iOS 16.4 (Release date: 2023-03-27)
footnote Full support
Samsung Internet – Full support
Samsung Internet 20 (Release date: 2023-02-10)
footnote Full support
WebView Android – Full support
WebView Android 105 (Release date: 2022-09-02)
footnote Full support
WebView on iOS – Full support
WebView on iOS 16.4 (Release date: 2023-03-27)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Full support
Deno 1.24 (Release date: 2022-07-20)
footnote Full support
Node.js – No support
Node.js 18.19 – 18.20 (Release date: 2023-11-29)
footnote Removed in 19 and later
Node.js – Partial support
Node.js 20.6 – 20.6 (Release date: 2023-09-04)
footnote Partial support
footnote Returns a URL object instead of a string.
Node.js – Full support
Node.js 20.8 (Release date: 2023-09-29)
footnote Full support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
Has more compatibility info.

See also