NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #273 most downloaded on npm
Offers a async require.resolve function. It's highly configurable.
Last release 5 days ago
29 Sep 2026
Ships fairly regularly
a new release about every 2 weeks
Nearly every release is documented
notes for 59 of the last 60 stable releases
Nothing withdrawn
no release was ever pulled
14 years old
158 releases · first in 2012
Add experimental support for Node.js package maps through a new packageMap option, which takes the path of the configuration file (or a file: URL ) or
Add experimental support for Node.js package maps through a new packageMap option, which takes the path of the configuration file (or a file: URL) or an already-parsed packages object. When it is set, a bare specifier is resolved through the importing package's dependencies table and the target package's location is handed to the regular pipeline, instead of walking node_modules; relative and absolute requests and node: builtins are unaffected. Because several package entries may share one url, the package a request resolved into is exposed as packageId on the result and can be passed back in as context.packageId to resolve from that package unambiguously. Package maps are stability 1 (experimental) in Node.js, and this option tracks that specification and may change with it. (by @alexander-akait in #667)
Explain an exports/imports field whose conditions wrap subpaths, instead of failing with a message that points at the request. A field shaped like { "import": { ".": "./esm/index.js", "./*": "./esm/*.js" }, "require": "./build/bundle.js" } is not supported by Node.js: the subpaths inside a condition are read as condition names, so they match nothing, and every request into the package failed as "./foo" is not exported under the conditions [...] — which reads as though the package forgot to export ./foo. Such a failure now names the offending keys and shows the arrangement that works, with the subpaths at the top level and the conditions nested inside them. Resolution itself is unchanged: the diagnosis runs only on a request that has already failed, so nothing that resolves today starts failing, and a successful resolve does no extra work. Errors raised while processing either field also name the package.json they came from, which previously only appeared in the resolver log. (by @alexander-akait in #676)
Generate the published type declarations with TypeScript instead of webpack/tooling, which is no longer a dependency. Every name the package exported before is still exported, and types.d.ts is still the entry point, but the declarations themselves now live in types/ and are emitted by tsc from the JSDoc in lib/. Two shapes follow the sources more closely than the previous generator did: the object form of Plugin no longer declares this: Resolver on apply (it is called as plugin.apply(resolver), so this is the plugin), and the entries of ResolveContext.stack declare name: string | undefined rather than an optional name. Class fields that the old generator dropped, such as the cache backends on CachedInputFileSystem, are now part of the declarations. (by @alexander-akait in #675)
getPathsCached keeps to what they actually hold: a push-built store keeps room for 17 entries while a path has a handful, and the cache holds these for the filesystem's lifetime. (by @alexander-akait in #681)One column per quarter.
Read a file: URL the way Node does when parsing a request. (by @alexander-akait in #670 )
file: URL the way Node does when parsing a request. (by @alexander-akait in #670)Accept file: URL strings wherever an option or the context path takes a path. (by @alexander-akait in #668 )
file: URL strings wherever an option or the context path takes a path. (by @alexander-akait in #668)Soft-fail when auto tsconfig discovery loads a broken config, and keep relative extends paths relative. (by @xiaoxiaojx in #645 )
extends paths relative. (by @xiaoxiaojx in #645)Keep the original request resolvable when extensionAlias lists its own extension. (by @alexander-akait in #641 )
Keep the original request resolvable when extensionAlias lists its own extension. (by @alexander-akait in #641)
Fix string restrictions boundary checks: a restriction ending with a separator no longer rejects everything inside it, restrictions are normalized before they are compared, and a Windows path now matches the way path.win32 does, treating / and \ as interchangeable and comparing case-insensitively, while \ stays a filename character in a posix path. The same comparison backs tsconfig path matching. (by @alexander-akait in #643)
Treat a UNC path (\\server\share\…) as a Windows path, so it normalizes, joins and walks up with path.win32 semantics instead of being taken for a bare module request. (by @alexander-akait in #644)
Resolve tsconfig extends package specifiers from ancestor node_modules directories (workspace hoisting). (by @alexander-akait in #631 )
extends package specifiers from ancestor node_modules directories (workspace hoisting). (by @alexander-akait in #631)Batch cached filesystem callbacks from one synchronous burst into a single tick. (by @alexander-akait in #623 )
Reduce hot-path allocations in the resolve pipeline. (by @xiaoxiaojx in #615 )
Allow the context path and request arguments of resolve (and resolveSync / resolvePromise ) to accept file: URL instances, converting them to filesyst
context path and request arguments of resolve (and resolveSync/resolvePromise) to accept file: URL instances, converting them to filesystem paths. Plain strings stay literal paths, matching Node's fs. (by @alexander-akait in #607)Make the resolver runtime-agnostic so it works in browsers, Deno and Bun as well as Node. File contents are decoded without assuming a Node Buffer, and browser shims are provided for the path, url and graceful-fs builtins (Node, Deno and Bun keep using the native ones) so the package bundles for the browser — supply your own fileSystem there. (by @alexander-akait in #606)
Rename the positional resolve/resolveSync/resolvePromise parameters to parent/specifier (from path/request) for ESM-aligned naming and document them in the README. Purely cosmetic — arguments are positional, so there is no behavior or API change. (by @alexander-akait in #611)
Allow the path-like resolve options roots , modules , alias / fallback targets, restrictions , and tsconfig (the config file, configFile , baseUrl , a
roots, modules, alias/fallback targets, restrictions, and tsconfig (the config file, configFile, baseUrl, and references) to accept file URL instances (such as new URL("./dir/", import.meta.url)), converting them to filesystem paths. Plain strings are still treated as literal paths, matching Node's fs. (by @alexander-akait in #604)Fall back to the next modules entry when a package exports target is filtered out by restrictions , instead of throwing. (by @alexander-akait in #600
modules entry when a package exports target is filtered out by restrictions, instead of throwing. (by @alexander-akait in #600)Fix restrictions bypass via an in-root symlink pointing outside the root. (by @alexander-akait in #595 )
restrictions bypass via an in-root symlink pointing outside the root. (by @alexander-akait in #595)CachedInputFileSystem#purge accepts a second { exact?: boolean } argument; exact: true removes only entries whose key matches what exactly instead of
CachedInputFileSystem#purge accepts a second { exact?: boolean } argument; exact: true removes only entries whose key matches what exactly instead of any entry whose key starts with what. (by @alexander-akait in #591)Speed up alias resolution on the hot path. (by @alexander-akait in #589)
Speed up alias resolution on the hot path. (by @alexander-akait in #589)
AliasPlugin / TsconfigPathsPlugin: bucket compiled alias options by the first char code of name, so resolves skip options whose name can't possibly match the request's first char. Gated to cases with 2+ distinct first chars so degenerate single-bucket lists (e.g. long alias chains) don't pay for the Map.get.TsconfigPathsPlugin: memoize _selectPathsDataForContext(map, requestPath) per map so the per-source-file contextList scan only runs once per directory. Gated to maps with 2+ contexts so single-context tsconfigs aren't penalized by the cache lookup.Biggest wins on alias-heavy configs (300+ entries): huge-alias-miss +151%, huge-alias-list +126%, alias-first-char-miss +120%.
Don't add configDir to modules when tsconfig has no baseUrl. (by @alexander-akait in `61f36fd`)
61f36fd)When tsconfig: true is used, walk up parent directories to find tsconfig.json, matching TypeScript's own findConfigFile behavior. (by @xiaoxiaojx in #
tsconfig: true is used, walk up parent directories to find tsconfig.json, matching TypeScript's own findConfigFile behavior. (by @xiaoxiaojx in #585)TsconfigPathsPlugin now falls through to normal module resolution when a paths pattern matches but the mapped path does not exist, matching TypeScript
paths pattern matches but the mapped path does not exist, matching TypeScript's native resolution behavior. Previously, patterns like "@*" would block scoped npm packages (e.g. @sentry/react) from resolving via node_modules. (by @xiaoxiaojx in #579)Fix TsconfigPathsPlugin circular project references causing stack overflow, add support for extending from unscoped npm packages, and use stat instead
Fix TsconfigPathsPlugin circular project references causing stack overflow, add support for extending from unscoped npm packages, and use stat instead of readFile for existence checks in extends resolution. (by @xiaoxiaojx in #575)
perf: dedupe miss paths in DirectoryExistsPlugin/FileExistsPlugin and prune the per-resolve TsconfigPathsPlugin context scan. (by @alexander-akait in #574)
perf: drop a dead Map lookup in findMatch and flatten AliasFieldPlugin's cache check. (by @alexander-akait in #574)
perf: hot-path tweaks in ImportsFieldPlugin, AliasUtils, and util/entrypoints. (by @alexander-akait in #574)
perf: cut per-resolve allocations in Resolver.parse, loadDescriptionFile, and TsconfigPathsPlugin._selectPathsDataForContext. (by @alexander-akait in #574)
…(no match-array allocation); drop the dead deprecatedInvalidSegmentRegEx.test(…) !== null clause in ImportsFieldPlugin (.test returns boolean; true !=…
Allocation-free reductions on hot-path code: hoist /#/g, /\$/g and /\\/g to module-level constants and gate the corresponding .replace calls behind includes(…) so paths/queries/requests without the match char skip the regex state machine entirely (the common case); share a single EMPTY_NO_MATCH tuple instead of allocating [[], null] per "no match" / "no condition matched" return; switch directMapping's for...of over mappingTarget and inner results to indexed loops to avoid iterator-object allocation per call; inline isConditionalMapping at its two hot-path call sites and merge the duplicate default / conditionNames.has(condition) branches in computeConditionalMapping; replace invalidSegmentRegEx.exec(…) !== null with .test(…) (no match-array allocation); drop the dead deprecatedInvalidSegmentRegEx.test(…) !== null clause in ImportsFieldPlugin (.test returns boolean; true !== null and false !== null are both true, so it was && true); drop the redundant relativePath.length === 0 guard before !startsWith("./") in ExportsFieldPlugin (the empty-string case is already covered). (by @alexander-akait in #558)
restore plugin compatibility for [...resolveContext.stack] iteration (by @alexander-akait in #569)
fix TsconfigPathsPlugin to support resolveSync with useSyncFileSystemCalls (by @alexander-akait in #572)
Added promise API and support to resolve without context and resolveContext. (by @alexander-akait in #520)
Added promise API and support to resolve without context and resolveContext. (by @alexander-akait in #520)
Add extensionAliasForExports option. When true, extensionAlias also applies to paths resolved through the package.json exports field. Off by default to match Node.js; opt in for full TypeScript-resolver parity with packages that ship .ts sources alongside the compiled .js they declare in exports. (by @alexander-akait in #554)
Properly handle DOS device paths (\\?\… and \\.\…). (by @alexander-akait in #551)
Prevent fallback to parent node_modules when the exports field target file is not found. (by @xiaoxiaojx in #495)
Imports field spec deviation: non-relative targets (e.g. "#a": "#b") no longer re-enter imports resolution, aligning with the Node.js ESM spec where PACKAGE_IMPORTS_RESOLVE does not recursively resolve # specifiers. (by @xiaoxiaojx in #503)
Previously { "#a": "#b", "#b": "./the.js" } would chain-resolve #a to ./the.js; now it correctly fails, matching Node.js behavior.
Move cachedJoin/cachedDirname/createCachedBasename caches from module-level globals to per-Resolver instances. This prevents unbounded memory growth in long-running processes — when a Resolver is garbage collected, its join/dirname/basename caches are released with it. (by @xiaoxiaojx in #507)
Fixed when tsconfig: true is used (default config file) and no tsconfig.json exists. (by @xiaoxiaojx in #502)
Apply the extensionAlias option to the imports field to be align with typescript resolution. (by @alexander-akait in #549)
Improved performance of the many plugins. (by @alexander-akait in #529)
Replace the Set<string>-based resolver stack with a singly-linked StackEntry class that exposes a Set-compatible API. (by @xiaoxiaojx in #526)
Each doResolve call now prepends a single linked-list node instead of cloning the entire Set, making stack push O(1) in time and memory. Recursion detection walks the linked list (O(n)), but because the stack is typically shallow this is much cheaper than cloning a Set per call.
Cache the result of stripJsonComments + JSON.parse in readJson using a WeakMap keyed by the raw file buffer. This avoids redundant comment-stripping and JSON parsing on every resolve call that reads tsconfig.json files (via stripComments: true), improving TsconfigPathsPlugin warm performance by ~20-35% depending on the depth of the extends chain. (by @xiaoxiaojx in #524)
Avoid OOM in CachedInputFileSystem when duration is Infinity. (by @alexander-akait in #527)
Optimize TsconfigPathsPlugin and fix extends resolution bugs. (by @alexander-akait in #492)
Optimize TsconfigPathsPlugin and fix extends resolution bugs. (by @alexander-akait in #492)
Improve resolver cache hit rate. (by @alexander-akait in #492)
Added the baseUrl option to override the tsconfig.json's baseUrl
baseUrl option to override the tsconfig.json's baseUrltsconfig.jsontsconfig.jsonAdded TsconfigPathsPlugin (replacement for tsconfig-paths-webpack-plugin) .
tsconfig-paths-webpack-plugin) .Allow subpath imports that start with #/
#/file: schemaFixed nonsensible intersection in types
### Fixes - [Types] FileSystem type
Fast path for parsing requests without \0
\0Added wildcards support for aliases
fix: exports and imports array target resolving
exports and imports array target resolvingAllow default condition to be anywhere
default condition to be anywhereuse cache for exports and imports plugins
cache realpath and realpathSync methods
find the pnpapi the issuer belongs to
pnpapi the issuer belongs toIgnore false/null/undefined plugins by @alexander-akait in https://github.com/webpack/enhanced-resolve/pull/389
false/null/undefined plugins by @alexander-akait in https://github.com/webpack/enhanced-resolve/pull/389Full Changelog: https://github.com/webpack/enhanced-resolve/compare/v5.14.1...v5.15.0
TypeScript strict mode is now enabled for enhanced-resolve by @alexander-akait in https://github.com/webpack/enhanced-resolve/pull/381
strict mode is now enabled for enhanced-resolve by @alexander-akait in https://github.com/webpack/enhanced-resolve/pull/381Full Changelog: https://github.com/webpack/enhanced-resolve/compare/v5.14.0...v5.14.1
Replace deprecated String.prototype.substr() by @CommanderRoot in https://github.com/webpack/enhanced-resolve/pull/336
resolve by @43081j in https://github.com/webpack/enhanced-resolve/pull/357aliasFields was not being applied to package exports field by @alexander-akait in https://github.com/webpack/enhanced-resolve/pull/380checkout, setup-node, and codecov github actions by @snitin315 in https://github.com/webpack/enhanced-resolve/pull/378Full Changelog: https://github.com/webpack/enhanced-resolve/compare/v5.13.0...v5.14.0
Add withFileTypes options from FileSystem API by @fu1996 in https://github.com/webpack/enhanced-resolve/pull/374
withFileTypes options from FileSystem API by @fu1996 in https://github.com/webpack/enhanced-resolve/pull/374conditionNames default by @43081j in https://github.com/webpack/enhanced-resolve/pull/359Full Changelog: https://github.com/webpack/enhanced-resolve/compare/v5.12.0...v5.13.0
reverts "utilize throwIfNoEntry in sync mode"
utilize throwIfNoEntry in sync mode
fix validation of imports field
extensionAlias optionimports fieldfix alias fields when using names that are equal to method on the object prototype
alias when #fix absolute path aliasing on windows
Nothing published for this version
add yield option to allow reporting multiple results
yield option to allow reporting multiple resultsfix bug when aliasing . in a browser field
. in a browser fieldallow to resolve imports from a subpath (imports field)
imports field)correctly call fs.statSync when there are no options
fix problem with bundling for browser usage
enforceExtension to true when extensions includes an empty string (to specify the exact order)# Contribution * typescript 4.2
add support for wildcard exports/imports mapping
add preferAbsolute option to prefer absolute paths over roots
preferAbsolute option to prefer absolute paths over rootsadd browser fallbacks when using this library in browsers
exports field in packageshandle PnP requests with fullySpecified correctly
fix problem where callback is called twice, resulting in crashes elsewhere
validate arguments to resolve and use callback for errors
exports and imports field continue resolving extensions, directories and aliases if fullySpecified is not specified
add optional lstat to filesystem interface and CachedFileSystem
lstat to filesystem interface and CachedFileSystem# in requests# in paths# will be escaped in the resulting pathoptions argument in filesystem methods when using the SyncAsyncFileSystem decoratorfix stack overflow crash in cached filesystem
preferRelative optionremove deprecated tapable compat layer
join expected from filesystemalias: { something: false }exports field support
exportsFields optionconditionNames optionexports field is presentrestrictions option, which allows to restrict the allowed paths to resolve tooroots optionfullySpecified option for better node.js esm compatoptions argument for all methodsimports field in package.jsonfallback option, which is like alias but is only activated when normal resolving fails"main": "." crashmodule/ now correctly resolves to directory and not to module.js as filealiasFields, descriptionFiles, extensions, modules, mainFields and mainFiles@scope/nameRevert for: Directories starting with # are no longer treated as fragment
# are no longer treated as fragmentYour coding agent can read these notes before it upgrades. Set up the MCP server →