npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

trpc-navigation-plugin

v0.3.4

Published

TypeScript Language Service Plugin that fixes broken 'go to definition' for tRPC when using declaration emit

Downloads

2,097

Readme

tRPC Navigation Plugin

A TypeScript Language Service Plugin that fixes broken "go to definition" navigation for tRPC procedures when using TypeScript's declaration emit.

🚀 View Demo Repository - See the plugin in action with a T3 Turbo monorepo

Problem

When using tRPC with TypeScript's declaration emit (declaration: true), there's a TypeScript bug that completely breaks "go to definition" functionality. When you try to Cmd+Click on a tRPC procedure call like api.users.getUser.useQuery(), TypeScript only takes you to the root router definition - it can't navigate any deeper into nested routers or the actual procedure implementations.

This is caused by how TypeScript handles the complex type inference in tRPC's router chains when generating .d.ts files.

Solution

This plugin bypasses TypeScript's broken type-based navigation by using a configured router location. When you Cmd+Click on a tRPC procedure, the plugin intercepts the navigation request and takes you directly to the procedure implementation in your source code.

Features

  • Fixes Broken Navigation: Restores "go to definition" functionality that TypeScript's declaration emit breaks
  • Direct Source Navigation: Takes you to the actual implementation code, not type definitions
  • Simple Configuration: Just specify your router location - no complex setup
  • Intelligent Client Detection: Automatically detects any tRPC client variable (api, trpc, client, etc.)
  • useUtils Support: Full navigation support for useUtils() variables
  • Cross-Package Support: Works seamlessly in monorepos
  • Fast Performance: Direct navigation without complex type resolution

When You Need This Plugin

You need this plugin if:

  • Your project uses tRPC
  • You have declaration: true in your tsconfig.json (for generating .d.ts files)
  • "Go to definition" on tRPC procedures doesn't work or takes you to the wrong place

You DON'T need this plugin if:

  • You're not using TypeScript's declaration emit
  • Your "go to definition" already works correctly

Installation

⚠️ IMPORTANT: VS Code & Editor Setup

You MUST use the workspace TypeScript version, not the built-in version!

In VS Code, Cursor, or other VS Code-based editors:

  1. Open any TypeScript file in your project
  2. Click the TypeScript version number or {} in the bottom status bar
  3. Select "Select TypeScript Version..."
  4. Choose "Use Workspace Version" (NOT "Use VS Code's Version")

Without this step, the plugin will not be detected or loaded!

Setup Steps

  1. Install the plugin:

    npm install --save-dev trpc-navigation-plugin
    # or
    yarn add -D trpc-navigation-plugin
    # or
    bun add -D trpc-navigation-plugin
  2. Configure in your tsconfig.json with your router location:

    {
      "compilerOptions": {
        "plugins": [
          {
            "name": "trpc-navigation-plugin",
            "router": {
              "filePath": "./src/server/api/root.ts",
              "variableName": "appRouter"
            }
          }
        ]
      }
    }
  3. Switch to workspace TypeScript (see important note above)

  4. Restart the TypeScript server: Cmd+Shift+P → "TypeScript: Restart TS Server"

Configuration

The plugin requires you to specify where your tRPC router is defined:

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "trpc-navigation-plugin",
        "router": {
          "filePath": "./src/server/api/root.ts",  // Path to your router file
          "variableName": "appRouter"              // Name of your router variable
        }
      }
    ]
  }
}

Configuration Options

  • router.filePath (required): Path to the file containing your main tRPC router

    • Can be relative (resolved from project root) or absolute
    • Example: "./src/server/api/root.ts"
  • router.variableName (required): Name of your router variable in that file

    • Example: "appRouter", "router", "mainRouter"
  • patterns (optional): Customize pattern detection

    • procedureTypes: Procedure types to detect (default: ['query', 'mutation', 'subscription'])
    • routerFunctions: Router function names (default: ['router', 'createTRPCRouter', 'createRouter', 't.router'])
    • clientInitializers: Client initialization patterns (default: ['createTRPC', 'initTRPC', 'createTRPCClient'])
    • utilsMethod: Name of the utils method (default: 'useUtils')
  • fileExtensions (optional): File extensions to process

    • Default: ['.ts', '.tsx', '.js', '.jsx', '.mts', '.cts', '.mjs', '.cjs']
    • Add custom extensions if needed

Monorepo Setup

In monorepos, add the plugin to each package that uses tRPC:

// packages/api/tsconfig.json - where router is defined
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "trpc-navigation-plugin",
        "router": {
          "filePath": "./src/router/index.ts",
          "variableName": "appRouter"
        }
      }
    ]
  }
}

// packages/web/tsconfig.json - uses tRPC through @my/api package
{
  "compilerOptions": {
    "plugins": [
      {
        "name": "trpc-navigation-plugin",
        "router": {
          "filePath": "../api/src/router/index.ts",
          "variableName": "appRouter"
        }
      }
    ]
  }
}

Optional: Enable Verbose Logging

For debugging, you can enable verbose logging:

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "trpc-navigation-plugin",
        "router": {
          "filePath": "./src/server/api/root.ts",
          "variableName": "appRouter"
        },
        "verbose": true  // Enable detailed logging
      }
    ]
  }
}

Advanced Configuration

Customize detection patterns for non-standard tRPC setups:

{
  "compilerOptions": {
    "plugins": [
      {
        "name": "trpc-navigation-plugin",
        "router": {
          "filePath": "./src/server/api/root.ts",
          "variableName": "appRouter"
        },
        "patterns": {
          "procedureTypes": ["query", "mutation", "subscription", "action"],
          "routerFunctions": ["router", "createTRPCRouter", "myCustomRouter"],
          "clientInitializers": ["createTRPC", "initTRPC", "setupTRPC"],
          "utilsMethod": "useUtils"  // or "useContext" for older tRPC versions
        },
        "fileExtensions": [".ts", ".tsx", ".mts", ".cts"]
      }
    ]
  }
}

Automatic tRPC Client Detection

The plugin intelligently detects any tRPC client variable, regardless of naming:

// All of these work automatically:
export const api = createTRPCReact<AppRouter>();
export const trpc = createTRPCNext<AppRouter>();
export const client = createTRPCProxyClient<AppRouter>();
export const myCustomName = initTRPC.create();

// In your components:
api.users.getUser.useQuery();      // ✓ Works
trpc.users.getUser.useQuery();     // ✓ Works
client.users.getUser.query();       // ✓ Works
myCustomName.users.getUser.query(); // ✓ Works

// useUtils variables also work:
const utils = api.useUtils();
const apiCtx = trpc.useUtils();
utils.users.getUser.fetch();       // ✓ Works
apiCtx.users.getUser.invalidate();  // ✓ Works

How It Works

  1. Router Configuration: You specify where your tRPC router is defined
  2. Client Detection: The plugin detects when you click on a tRPC client call
  3. Direct Navigation: Uses the configured router location to navigate directly to procedures
  4. Path Resolution: Follows the navigation path through nested routers to find the target
  5. Contextual Navigation: Click on different parts for different results:
    • api.billing.claims - clicking "billing" goes to billing router
    • api.billing.claims - clicking "claims" goes to claims procedure/router

Troubleshooting

If navigation isn't working:

  1. Verify TypeScript Version: Make sure you're using the workspace TypeScript version! (See installation section)
  2. Check Configuration: Ensure your router config points to the correct file and variable name
  3. Verify Router Export: Make sure your router is exported or declared in the specified file
  4. Check TS Server Logs: Look for [TRPC-Nav] entries in the TypeScript Server logs
  5. Enable Verbose Logging: Add "verbose": true to see detailed debug information
  6. Restart TS Server: After configuration changes: Cmd+Shift+P → "TypeScript: Restart TS Server"

Common issues:

  • Plugin not loading: You're using VS Code's built-in TypeScript instead of workspace version
  • Wrong file path: Paths are resolved from the project root (where tsconfig.json is)
  • Wrong variable name: The variable name must match exactly (case-sensitive)
  • Router not found: Make sure the router is a top-level export or variable declaration

Technical Details

  • Uses TypeScript's Language Service API for navigation interception
  • Directly navigates to configured router location without complex type resolution
  • Works around TypeScript's navigation bug without modifying your build process
  • Compatible with tRPC v10+ and v11 that use the standard router pattern
  • Supports monorepo setups with relative or absolute paths
  • Does not interfere with TypeScript's type checking or declaration emit