{"id":12781,"library":"ts-pnp","title":"TypeScript Plug'n'Play Resolver","description":"ts-pnp provides a low-level module resolver specifically designed to integrate Yarn's Plug'n'Play (PnP) resolution strategy with the TypeScript compiler API. It is primarily intended for developers building custom TypeScript compiler hosts, tools, or plugins, rather than for direct application usage. The current stable version is 1.2.0, indicating a mature and stable API, and its release cadence is generally tied to updates in Yarn PnP or TypeScript APIs. Its key differentiator is enabling seamless PnP support for TypeScript's module resolution, allowing TypeScript projects to leverage the benefits of PnP without complex manual configuration, particularly when used in conjunction with companion plugins for build tools like Webpack, Jest, and Rollup.","status":"maintenance","version":"1.2.0","language":"javascript","source_language":"en","source_url":"https://github.com/arcanis/ts-pnp","tags":["javascript","typescript","yarn","plugnplay","pnp"],"install":[{"cmd":"npm install ts-pnp","lang":"bash","label":"npm"},{"cmd":"yarn add ts-pnp","lang":"bash","label":"yarn"},{"cmd":"pnpm add ts-pnp","lang":"bash","label":"pnpm"}],"dependencies":[{"reason":"Required as a peer dependency for its intended use within a TypeScript CompilerHost context, specifically for `ts.CompilerHost` and `ts.resolveModuleName` functions.","package":"typescript","optional":false}],"imports":[{"note":"The primary export is a named function, `resolveModuleName`, used to implement the `resolveModuleName` hook for TypeScript's `CompilerHost`.","wrong":"import resolveModuleName from 'ts-pnp'; // Incorrect, it's a named export.\nconst { resolveModuleName } = require('ts-pnp'); // CommonJS is typically not preferred for this library's use case with TypeScript.","symbol":"resolveModuleName","correct":"import { resolveModuleName } from 'ts-pnp';"},{"note":"While `resolveTypeReferenceDirectives` is an expected hook for `CompilerHost`, `ts-pnp` itself provides `resolveModuleName` which is then used to implement both module and type reference resolution, often by calling `resolveModuleName` from `ts-pnp` with appropriate arguments.","symbol":"resolveTypeReferenceDirectives","correct":"import { resolveModuleName } from 'ts-pnp'; // Used indirectly via resolveModuleName for type directives."},{"note":"This library is designed to be integrated into a custom `ts.CompilerHost` implementation. You will almost always need to import `typescript` itself alongside `ts-pnp`.","symbol":"CompilerHost integration","correct":"import * as ts from 'typescript';\nimport { resolveModuleName } from 'ts-pnp';"}],"quickstart":{"code":"import { resolveModuleName as resolvePnpModuleName } from 'ts-pnp';\nimport * as ts from 'typescript';\n\ninterface CustomCompilerHost extends ts.CompilerHost {\n  resolveModuleNames: (moduleNames: string[], containingFile: string) => (ts.ResolvedModule | undefined)[];\n  resolveTypeReferenceDirectives: (typeDirectiveNames: string[], containingFile: string) => (ts.ResolvedTypeReferenceDirective | undefined)[];\n}\n\nfunction createPnPCompilerHost(\n  compilerOptions: ts.CompilerOptions,\n  host?: ts.CompilerHost, // Optional base host for fallback\n): CustomCompilerHost {\n  // Provide a default host if none is given\n  const baseHost = host || ts.createCompilerHost(compilerOptions, true);\n\n  const customHost: CustomCompilerHost = {\n    ...baseHost,\n    resolveModuleNames,\n    resolveTypeReferenceDirectives,\n  };\n\n  return customHost;\n\n  function resolveModuleNames(moduleNames: string[], containingFile: string) {\n    return moduleNames.map(moduleName => {\n      // ts-pnp resolver with a fallback to TypeScript's default resolver\n      const resolved = resolvePnpModuleName(\n        moduleName,\n        containingFile,\n        compilerOptions,\n        customHost,\n        ts.resolveModuleName // Essential fallback to TypeScript's internal resolver\n      );\n      return resolved.resolvedModule;\n    });\n  }\n\n  function resolveTypeReferenceDirectives(typeDirectiveNames: string[], containingFile: string) {\n    return typeDirectiveNames.map(typeDirectiveName => {\n      // ts-pnp resolver for type directives, with fallback\n      const resolved = resolvePnpModuleName(\n        typeDirectiveName,\n        containingFile,\n        compilerOptions,\n        customHost,\n        ts.resolveTypeReferenceDirective // Essential fallback for type reference directives\n      );\n      return resolved.resolvedTypeReferenceDirective;\n    });\n  }\n}\n\n// Example usage (conceptual, actual compilation would involve more setup):\nconst compilerOptions: ts.CompilerOptions = {\n  target: ts.ScriptTarget.ESNext,\n  module: ts.ModuleKind.ESNext,\n  strict: true,\n  // ... other options\n};\n\nconst pnpHost = createPnPCompilerHost(compilerOptions);\nconsole.log('PnP-enabled TypeScript CompilerHost created.');\n// To compile, you would typically use ts.createProgram with this host:\n// const program = ts.createProgram(['./src/index.ts'], compilerOptions, pnpHost);\n// program.emit();","lang":"typescript","description":"This quickstart demonstrates how to create a custom TypeScript `CompilerHost` that integrates `ts-pnp` for module and type reference resolution, providing Yarn Plug'n'Play support within a TypeScript compilation pipeline. It shows the core `resolveModuleName` hook implementation with a crucial fallback to TypeScript's default resolvers."},"warnings":[{"fix":"Unless you are writing a custom TypeScript compiler host or tool, consider using a dedicated PnP plugin for your build system (e.g., `pnp-webpack-plugin` for Webpack).","message":"This package is a low-level utility for integrating Yarn PnP with the TypeScript Compiler API. It is not intended for direct application usage. Most users should look for higher-level integrations like `pnp-webpack-plugin`, `jest-pnp-resolver`, or `rollup-plugin-pnp-resolve` instead.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always pass `ts.resolveModuleName` for module resolution and `ts.resolveTypeReferenceDirective` for type reference directive resolution as the fifth argument to `ts-pnp`'s `resolveModuleName` function.","message":"Incorrectly providing the `ts.resolveModuleName` or `ts.resolveTypeReferenceDirective` fallback function as the fifth argument to `ts-pnp`'s `resolveModuleName` will lead to incorrect module resolution behavior, potentially causing modules to not be found or resolved in unexpected ways.","severity":"gotcha","affected_versions":">=1.0.0"},{"fix":"Always test `ts-pnp` integration thoroughly when upgrading major versions of Yarn or TypeScript. Refer to the `ts-pnp` GitHub repository for release notes regarding compatibility updates.","message":"Significant changes to Yarn's Plug'n'Play specification or the TypeScript Compiler API's module resolution hooks might require updates to `ts-pnp`. While the library strives for compatibility, fundamental shifts could impact its functionality.","severity":"breaking","affected_versions":">=1.0.0"},{"fix":"Ensure your project has `yarn install --enable-pnp` or equivalent configured to generate the `.pnp.cjs` file, and that your development environment is set up to use Yarn PnP.","message":"While `ts-pnp` enables PnP resolution, it does not manage the installation or activation of PnP itself. Your project must be configured to use Yarn PnP for `ts-pnp` to function effectively.","severity":"gotcha","affected_versions":">=1.0.0"}],"env_vars":null,"last_verified":"2026-04-19T00:00:00.000Z","next_check":"2026-07-18T00:00:00.000Z","problems":[{"fix":"Run `yarn add -D ts-pnp` or `npm install --save-dev ts-pnp` in your project directory.","cause":"The `ts-pnp` package has not been installed or is not accessible in the current environment.","error":"Cannot find module 'ts-pnp'"},{"fix":"Verify that the module being resolved actually exists and is properly installed via Yarn PnP. Double-check the `moduleName` and `containingFile` arguments passed to `resolvePnpModuleName` and ensure the `ts.resolveModuleName` fallback is correctly provided.","cause":"This typically occurs if the `resolveModuleName` function returns `undefined` (or a similar falsy value) when it was expected to resolve a module, indicating a failure in the resolution process, possibly due to an incorrect path or a missing package in the PnP cache.","error":"TypeError: Cannot read properties of undefined (reading 'resolvedModule')"},{"fix":"Ensure the module is correctly listed in `package.json` and `yarn install` has been run. Verify that `ts-pnp`'s `resolveModuleName` is correctly wired into the `CompilerHost` and that the fallback to `ts.resolveModuleName` is present for non-PnP resolved modules or edge cases.","cause":"Despite `ts-pnp` being integrated, TypeScript is still unable to locate a module or its type definitions. This could mean PnP resolution failed, or a module is missing from the Yarn cache/`.pnp.cjs` file.","error":"TS2307: Cannot find module '...' or its corresponding type declarations."}],"ecosystem":"npm"}