Skip to content

Conversation

@GGomez99
Copy link
Owner

@GGomez99 GGomez99 commented Aug 19, 2025

Motivation

This PR adds Plug'n'Play support natively to Typescript Go, following this issue:
It has been reviewed and supported by @arcanis, the lead maintainer of Yarn, and the original author of Yarn PnP.

Datadog has a frontend monorepo using yarn with over 6k packages, and seeing how TS Strada struggles with our current scaling, we decided to invest time in adding a native Yarn PnP support for Typescript Go.
This PnP implementation has been actively used in the IDE of more than 230 engineers at Datadog, and we're committed to fixing all issues reported to us.

Challenges

We did not integrate it in our CI yet as we still have several packages failing on build mode (most errors seem to be reported in the issues section of TS Corsa). Because the TS Corsa API is not available yet, we also couldn't integrate it properly with a fast lage setup unlike with the TS Strada API.

Changes

It's based on the main changes from the original yarn patch (microsoft/TypeScript@99f3e13) that the community has been maintaining for years throughout Typescript Strada updates, except that we implemented the official PnP specification so it doesn't depend on third-party code.

Implemented features:

  • PnP VFS that handles virtual folders and zip files seamlessly, with caching and fallback to the original vfs if pnp is not available
  • Initialize the PnP API and VFS for both the CLI and LSP
  • Add PnP API and manifest handling, following the yarn PnP specification
  • Add PnP support when resolving modules in internal/module/resolver.go
  • Add PnP support for auto-imports and completion at internal/modulespecifiers/specifiers.go
  • Add PnP support for root types at internal/core/compileroptions.go
  • Handle zip paths when going to implementation in the IDE
  • Update the baseline testing framework to handle PnP when needed

Missing features:

  • Bubbling up unresolved modules errors from pnpApi.ResolveToUnqualified
  • PnP manifest auto-refresh by watching .pnp.cjs changes

Tests

  • Basic PnP setup
  • Types from transitive dependencies
  • Root types loading from PnP dependencies
  • Completion and autoimports (test framework needs tinkering for internal/fourslash)

@GGomez99 GGomez99 force-pushed the guyllian.gomez/yarn-pnp-support branch from 13aa2a3 to 1e204b1 Compare August 19, 2025 11:23
@GGomez99 GGomez99 marked this pull request as draft August 19, 2025 11:27
func (r *resolutionState) loadModuleFromNearestNodeModulesDirectoryWorker(ext extensions, mode core.ResolutionMode, typesScopeOnly bool) *resolved {
pnpApi := pnp.GetPnpApi(r.containingDirectory)
if pnpApi != nil {
// TODO: stop at global cache too?
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have details?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At L927, they have a comment saying they should stop at global cache, but it looks like it's not implemented yet
So I added a comment for the pnp resolver too

}

if pathObj.IsRedirect && !isPackageRootPath {
return ""
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are those empty strings also used by stock TS-go? Feels like it should at least be a constant declared somewhere.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it's the exact same implementation as tryGetModuleNameAsNodeModule from L815 to L901, with minor changes to make pnp work (L803 is also defined at L886)

Copy link
Owner Author

@GGomez99 GGomez99 Oct 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However this means I had to duplicate some code (see this comment), so I'm not sure if it should stay like this

@GGomez99 GGomez99 force-pushed the guyllian.gomez/yarn-pnp-support branch 2 times, most recently from 40159a2 to b681451 Compare October 21, 2025 12:59
@GGomez99 GGomez99 force-pushed the guyllian.gomez/yarn-pnp-support branch 2 times, most recently from e17c10f to ee62041 Compare October 22, 2025 15:45
@GGomez99 GGomez99 force-pushed the guyllian.gomez/yarn-pnp-support branch from ee62041 to c13f422 Compare October 23, 2025 08:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants