Skip to content

Bug: tRPC dependencies are bundled instead of using peerDependencies, causing type conflicts. #21

Open

Description

@aleksolutions

Hello ToolsPlus team,

First of all, thank you for creating and maintaining this very useful library for the Forge ecosystem.

After a long debugging session, we've identified a fundamental issue in how @toolsplus/forge-trpc-link handles its tRPC dependencies, which leads to unexpected behavior and very subtle type errors.


The Problem

The @toolsplus/forge-trpc-link library (and likely other packages in the monorepo) includes the @trpc/* libraries as direct dependencies in its package.json instead of as peerDependencies.

Consequences

This causes several critical problems in a project consuming the library:

  1. Version Conflict and Duplication: This causes two versions of @trpc/client to be installed in the final project. For context, our project uses the latest version of tRPC (v11.4.3), while the version bundled with forge-trpc-link appears to be an older, fixed version. This unnecessarily increases the final bundle size.

  2. instanceof Checks Fail: This is the most critical issue. The TRPCClientError imported in my application is not the same class as the TRPCClientError handled by the link internally. As a result, any type check like error instanceof TRPCClientError will always return false.

  3. Unexpected Behavior: We believe this type conflict is the root cause of why @trpc/react-query fails to recognize the error coming from the link as a valid instance of "its" TRPCClientError. As a safety mechanism, it wraps the original error in a new one, assigning the original to the .cause property. This forces developers to implement complex workarounds in the application layer to normalize errors.


Expected Behavior

The library should use the same instance and version of the @trpc/* libraries as the host project. This is achieved by declaring them as peerDependencies.

Proposed Solution

The solution is to move all @trpc/* dependencies from the dependencies object to the peerDependencies object in the package.json for the @toolsplus/forge-trpc-link package.

This change would resolve the type conflicts, reduce the final bundle size, and make the library behave predictably and consistently with the tRPC ecosystem.

Thank you for your time and for your excellent work on this library!

Activity

  1. aleksolutions commented on Jul 15, 2025

    @aleksolutions
    Author

    For additional context and to validate the proposed solution:

    I copied the customUiBridgeLink source code directly into our local project. By doing this, the link was compiled using our project's tRPC dependencies (v11.4.3) instead of its own bundled ones.

    With this local version of the link, the problem completely disappeared. All instanceof TRPCClientError checks now pass as expected, and the error object is received "flat" (with .data at the root level), exactly as the official tRPC documentation describes.

    This further confirms that the bundled dependencies are the root cause of the issue.

  2. ppasler commented on Jul 17, 2026

    @ppasler
    Contributor

    Hi @aleksolutions ,

    not a maintainer, but I ran into related dependency issues and contributed #22, so here's a status update that may help.

    v2.0.0 was released yesterday and improves the situation, although it doesn't fully implement your proposed fix yet:

    • @forge/bridge is now a peer dependency of forge-trpc-link (and @forge/resolver of forge-trpc-adapter), so those are no longer bundled twice.
    • The @trpc/* packages are still regular dependencies, but they are now declared as the range ^11.0.0, and compatibility with @trpc/server >= 11.18 was restored.

    In practice, the range means your package manager can dedupe @trpc/client/@trpc/server to your app's version. I verified this in our project: after upgrading to 2.0.0, the link resolves to the exact same @trpc/client instance as the app, so instanceof TRPCClientError checks work again and @trpc/react-query no longer wraps the errors.

    The clean fix you proposed (moving @trpc/* to peerDependencies) is still open and would be another breaking change, so I'd keep this issue open for that. Until then, upgrading to 2.0.0 and making sure your app's tRPC version satisfies ^11.0.0 should resolve the symptoms without the copy-the-link-source workaround.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions