diff --git a/src/esmockArgs.js b/src/esmockArgs.js
index 5be05cc..141bd75 100644
--- a/src/esmockArgs.js
+++ b/src/esmockArgs.js
@@ -1,4 +1,5 @@
-import resolver from 'resolvewithplus'
+import resolvewithplus from 'resolvewithplus'
+import pnpResolver from './pnpResolver.js'
 
 // extracts path or fileurl from stack,
 // '  at <anonymous> (/root/test.js:11:31)' -> /root/test.js
@@ -7,6 +8,8 @@ import resolver from 'resolvewithplus'
 // '  at file:///D:/a/test.js:7:9' -> file:///D:/a/test.js
 const stackpathre = /^.*(\(|at )(.*):[\d]*:[\d]*.*$/
 
+const resolver = pnpResolver || resolvewithplus
+
 // this function normalizes "overloaded" args signatures, returning
 // one predictable args list. ex,
 //   [moduleId, defs, gdefs, opts]
diff --git a/src/pnpResolver.js b/src/pnpResolver.js
new file mode 100644
index 0000000..26edf29
--- /dev/null
+++ b/src/pnpResolver.js
@@ -0,0 +1,18 @@
+import { isBuiltin } from 'node:module'
+import { pathToFileURL } from 'node:url'
+
+const pnpapi = process.versions.pnp && (await import('pnpapi')).default
+
+export default pnpapi && ((id, parent) => {
+  if (isBuiltin(id)) {
+    return id.startsWith('node:') ? id : `node:${id}`
+  }
+
+  if (id === 'import') {
+    return null
+  }
+
+  const path = pnpapi.resolveRequest(id, parent)
+
+  return path !== null ? pathToFileURL(path).href : null
+})
diff --git a/tests/local/pnp/api.js b/tests/local/pnp/api.js
new file mode 100644
index 0000000..b1c6ea4
--- /dev/null
+++ b/tests/local/pnp/api.js
@@ -0,0 +1 @@
+export default {}
diff --git a/tests/local/pnp/disable.js b/tests/local/pnp/disable.js
new file mode 100644
index 0000000..5d0632d
--- /dev/null
+++ b/tests/local/pnp/disable.js
@@ -0,0 +1 @@
+delete process.versions.pnp
diff --git a/tests/local/pnp/enable.js b/tests/local/pnp/enable.js
new file mode 100644
index 0000000..bbbbd68
--- /dev/null
+++ b/tests/local/pnp/enable.js
@@ -0,0 +1,12 @@
+import module from 'node:module'
+
+async function resolve (specifier, context, next) {
+  return next(
+    specifier === 'pnpapi'
+      ? '../tests/local/pnp/api.js'
+      : specifier, context)
+}
+  
+module.register && (process.versions.pnp = '3') && module.register(`
+data:text/javascript,
+export ${encodeURIComponent(resolve)}`.slice(1))
diff --git a/tests/package.json b/tests/package.json
index 63c715f..dc23784 100644
--- a/tests/package.json
+++ b/tests/package.json
@@ -26,7 +26,7 @@
     "sinon": "^12.0.1"
   },
   "scripts": {
-    "mini:esmock": "cd .. && cd src && npx esbuild esmock.js --minify --bundle --allow-overwrite --platform=node --format=esm --outfile=esmock.js",
+    "mini:esmock": "cd .. && cd src && npx esbuild esmock.js --minify --bundle --allow-overwrite --platform=node --format=esm --external:pnpapi --outfile=esmock.js",
     "mini:esmockLoader": "cd .. && cd src && npx esbuild esmockLoader.js --minify --bundle --allow-overwrite --platform=node --format=esm --outfile=esmockLoader.js",
     "mini": "npm run mini:esmock && npm run mini:esmockLoader",
     "isnodelt18": "node -e \"+process.versions.node.split('.')[0] < 18 || process.exit(1)\"",
diff --git a/tests/tests-node/esmock.node.resolver-pnp.test.js b/tests/tests-node/esmock.node.resolver-pnp.test.js
new file mode 100644
index 0000000..02825ce
--- /dev/null
+++ b/tests/tests-node/esmock.node.resolver-pnp.test.js
@@ -0,0 +1,35 @@
+import test from 'node:test'
+import assert from 'node:assert/strict'
+import module from 'node:module'
+import { fileURLToPath } from 'node:url'
+import resolvewithplus from 'resolvewithplus'
+import '../local/pnp/enable.js'
+import esmock from 'esmock'
+import '../local/pnp/disable.js'
+import pnpapi from '../local/pnp/api.js'
+
+const resolver = (id, parent) => {
+  const url = resolvewithplus(id, parent)
+  return url !== null ? fileURLToPath(url) : null
+}
+
+test.beforeEach(() => {
+  delete pnpapi.resolveRequest
+})
+
+test('should work with pnp resolver', async ({ mock }) => {
+  if (!module.register)
+    return assert.ok('skip test')
+  
+  pnpapi.resolveRequest = mock.fn(resolver)
+
+  const main = await esmock('../local/main.js', {
+    '../local/mainUtil.js': {
+      createString: () => 'test string'
+    }
+  })
+
+  assert.equal(typeof main, 'function')
+  assert.strictEqual(main(), 'main string, test string')
+  assert.equal(pnpapi.resolveRequest.mock.callCount(), 2)
+})