npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

unrs-resolver

v1.11.1

Published

UnRS Resolver Node API with PNP support

Readme

[!NOTE]

This is a fork of oxc-resolver and rspack-resolver, and will be used in eslint-plugin-import-x and eslint-import-resolver-typescript cause 100% compatible with enhanced-resolve is the non-goal of oxc-resolver itself, we add enhanced-resolve specific features like pnp support.

We also fix several bugs reported by eslint-plugin-import-x and eslint-import-resolver-typescript users:

The list could be longer in the future, but we don't want to make it too long here.

We also sync with oxc-resolver and rspack-resolver regularly to keep up with the latest changes:

Last but not least, we prepare some bug fix PRs first on our side and PR back into upstream projects, and we will keep doing this in the future:

Crates.io npmjs.com

Docs.rs Build Status Code Coverage CodSpeed Badge Sponsors MIT licensed

UnRS Resolver

Rust port of enhanced-resolve.

Usage

npm package

See index.d.ts for resolveSync and ResolverFactory API.

Quick example:

import assert from 'node:assert';
import path from 'node:path';

import resolve, { ResolverFactory } from 'unrs-resolver';

// `resolve`
assert(resolve.sync(process.cwd(), './index.js').path, path.resolve('index.js'));

// `ResolverFactory`
const resolver = new ResolverFactory();
assert(resolver.sync(process.cwd(), './index.js').path, path.resolve('index.js'));

Supports WASM

See https://stackblitz.com/edit/unrs-resolver for usage example.

Rust

See docs.rs/unrs_resolver.

Yarn Plug'n'Play

  • For node.js, yarn pnp should work without any configuration, given the following conditions:
    • the program is called with the yarn command, where the value process.versions.pnp is set.
    • .pnp.cjs manifest file exists in the closest directory, searched from the current working directory,
    • no multi-project setup, per second bullet point in FIND_PNP_MANIFEST

Terminology

directory

An absolute path to a directory where the specifier is resolved against.

For CommonJS modules, it is the __dirname variable that contains the absolute path to the folder containing current module.

For ECMAScript modules, it is the value of import.meta.dirname.

Behavior is undefined when given a path to a file.

specifier

The string passed to require or import, i.e. require("specifier") or import "specifier"

Errors and Trouble Shooting

  • Error: Package subpath '.' is not defined by "exports" in - occurs when resolving without conditionNames.

Configuration

The following usages apply to both Rust and Node.js; the code snippets are written in JavaScript.

To handle the exports field in package.json, ESM and CJS need to be differentiated.

ESM

Per ESM Resolution algorithm

defaultConditions is the conditional environment name array, ["node", "import"].

This means when the caller is an ESM import (import "module"), resolve options should be

{
  "conditionNames": ["node", "import"]
}

CJS

Per CJS Resolution algorithm

LOAD_PACKAGE_EXPORTS(X, DIR)

  1. let MATCH = PACKAGE_EXPORTS_RESOLVE(pathToFileURL(DIR/NAME), "." + SUBPATH, package.json "exports", ["node", "require"]) defined in the ESM resolver.

This means when the caller is a CJS require (require("module")), resolve options should be

{
  "conditionNames": ["node", "require"]
}

Cache

To support both CJS and ESM with the same cache:

const esmResolver = new ResolverFactory({
  conditionNames: ['node', 'import'],
});

const cjsResolver = esmResolver.cloneWithOptions({
  conditionNames: ['node', 'require'],
});

Browser Field

From this non-standard spec:

The browser field is provided to JavaScript bundlers or component tools when packaging modules for client side use.

The option is

{
  "aliasFields": ["browser"]
}

Main Field

{
  "mainFields": ["module", "main"]
}

Quoting esbuild's documentation:

  • main - This is the standard field for all packages that are meant to be used with node. The name main is hard-coded in to node's module resolution logic itself. Because it's intended for use with node, it's reasonable to expect that the file path in this field is a CommonJS-style module.
  • module - This field came from a proposal for how to integrate ECMAScript modules into node. Because of this, it's reasonable to expect that the file path in this field is an ECMAScript-style module. This proposal wasn't adopted by node (node uses "type": "module" instead) but it was adopted by major bundlers because ECMAScript-style modules lead to better tree shaking, or dead code removal.
  • browser - This field came from a proposal that allows bundlers to replace node-specific files or modules with their browser-friendly versions. It lets you specify an alternate browser-specific entry point. Note that it is possible for a package to use both the browser and module field together (see the note below).

Options

The following options are aligned with enhanced-resolve, and is implemented for Rust crate usage.

See index.d.ts for Node.js usage.

| Field | Default | Description | | ------------------------------------- | ------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | | alias | {} | A hash map of module alias configurations | | aliasFields | [] | A list of alias fields in description files | | extensionAlias | {} | An object which maps extension to extension aliases | | conditionNames | [] | A list of exports field condition names | | descriptionFiles | ["package.json"] | A list of description files to read from | | enforceExtension | false | Enforce that a extension from extensions must be used | | exportsFields | ["exports"] | A list of exports fields in description files | | extensions | [".js", ".json", ".node"] | A list of extensions which should be tried for files | | fallback | {} | Same as alias, but only used if default resolving fails | | fileSystem | | The file system which should be used | | fullySpecified | false | Request passed to resolve is already fully specified and extensions or main files are not resolved for it (they are still resolved for internal requests) | | mainFields | ["main"] | A list of main fields in description files | | mainFiles | ["index"] | A list of main files in directories | | modules | ["node_modules"] | A list of directories to resolve modules from, can be absolute path or folder name | | resolveToContext | false | Resolve to a context instead of a file | | preferRelative | false | Prefer to resolve module requests as relative request and fallback to resolving as module | | preferAbsolute | false | Prefer to resolve server-relative urls as absolute paths before falling back to resolve in roots | | restrictions | [] | A list of resolve restrictions | | roots | [] | A list of root paths | | symlinks | true | Whether to resolve symlinks to their symlinked location | | allowPackageExportsInDirectoryResolve | false | Allow exports field in require('../directory'). Not part of enhanced-resolve. |

TypeScript Configuration

| Field | Default | Description | | ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | tsconfig | None | TypeScript related config for resolver | | tsconfig.configFile | | A relative path to the tsconfig file based on cwd, or an absolute path of tsconfig file. | | tsconfig.references | [] | - 'auto': inherits from TypeScript config - string []: relative path (based on directory of the referencing tsconfig file) or absolute path of referenced project's tsconfig |

Unimplemented Options

| Field | Default | Description | | ---------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- | | cachePredicate | function() { return true }; | A function which decides whether a request should be cached or not. An object is passed to the function with path and request properties. | | cacheWithContext | true | If unsafe cache is enabled, includes request.context in the cache key | | plugins | [] | A list of additional resolve plugins which should be applied | | resolver | undefined | A prepared Resolver to which the plugins are attached | | unsafeCache | false | Use this cache object to unsafely cache the successful requests |

Debugging

The following environment variable emits tracing information for the unrs_resolver::resolve function.

e.g.

2024-06-11T07:12:20.003537Z DEBUG unrs_resolver: options: ResolveOptions { ... }, path: "...", specifier: "...", ret: "..."
    at /path/to/unrs_resolver-1.8.1/src/lib.rs:212
    in unrs_resolver::resolve with path: "...", specifier: "..."

The input values are options, path and specifier, the returned value is ret.

NAPI

UNRS_LOG=DEBUG your_program

Test

Tests are ported from

Test cases are located in ./src/tests, fixtures are located in ./tests

  • [x] alias.test.js
  • [x] browserField.test.js
  • [x] dependencies.test.js
  • [x] exportsField.test.js
  • [x] extension-alias.test.js
  • [x] extensions.test.js
  • [x] fallback.test.js
  • [x] fullSpecified.test.js
  • [x] identifier.test.js (see unit test in crates/unrs_resolver/src/request.rs)
  • [x] importsField.test.js
  • [x] incorrect-description-file.test.js (need to add ctx.fileDependencies)
  • [x] missing.test.js
  • [x] path.test.js (see unit test in crates/unrs_resolver/src/path.rs)
  • [ ] plugins.test.js
  • [ ] pnp.test.js
  • [x] resolve.test.js
  • [x] restrictions.test.js (partially done, regex is not supported yet)
  • [x] roots.test.js
  • [x] scoped-packages.test.js
  • [x] simple.test.js
  • [x] symlink.test.js

Irrelevant tests

  • CachedInputFileSystem.test.js
  • SyncAsyncFileSystemDecorator.test.js
  • forEachBail.test.js
  • getPaths.test.js
  • pr-53.test.js
  • unsafe-cache.test.js
  • yield.test.js

Sponsored By

Sponsors

Sponsors

| 1stG | UnRs | UnTS | | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- | | 1stG Open Collective backers and sponsors | UnRs Open Collective backers and sponsors | UnTS Open Collective backers and sponsors |

Backers

| 1stG | UnRs | UnTS | | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | 1stG Open Collective backers and sponsors | UnRs Open Collective backers and sponsors | UnTS Open Collective backers and sponsors |

📖 License

unrs_resolver is free and open-source software licensed under the MIT License.

UnRS partially copies code from the following projects.

| Project | License | | --------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- | | webpack/enhanced-resolve | MIT | | dividab/tsconfig-paths | MIT | | parcel-bundler/parcel | MIT | | tmccombs/json-comments-rs | Apache 2.0 | | oxc-project/oxc-resolver | MIT | | web-infra-dev/rspack-resolver | MIT |