A VSCode extension for Riverpod + riverpod_generator projects. Click on a provider usage — viewFreshnessProvider, counterProvider, whatever — and jump to the class or function you actually hand-wrote, even in files with several providers mixed together.
Why this exists
With code generation, fooProvider isn't really defined where you wrote your @riverpod code — it's defined in the generated foo.g.dart file. VSCode's own navigation naturally lands you there, not in your source. That's a small but constant tax on every Riverpod codebase: dozens of little detours per day, through a file you're not supposed to touch.
Riverpod Wayfinder removes that detour. It reads the .g.dart file for you, figures out exactly which provider you clicked (even when the file groups several of them), and takes you to the real declaration.
Features
Ctrl+F12 / Cmd+F12 (Go to Implementation) — the main gesture. Jumps directly to the hand-written source, every time, no picker.
Ctrl+Click / Cmd+Click (Go to Definition) — also offers the hand-written source as a candidate, alongside the Dart extension's own answer (the generated file). See Why a picker? below.
Ctrl+Alt+D / Cmd+Alt+D — manual command fallback, works from anywhere in the file.
- Correctly handles files with multiple providers, mixing class-based and function-based styles, in any order.
- Supports both
@riverpod class Foo extends _$Foo and @riverpod ReturnType foo(Ref ref).
- No filename convention required — matches by content, so
foo.providers.dart / foo.providers.g.dart and plain foo.dart / foo.g.dart both work.
- No provider naming convention required either — works whether your generated identifiers end in
Provider, Controller, or anything else your team uses, wherever @riverpod codegen itself works.
Shift+F12 (Find All References) on a hand-written @riverpod declaration — lists every usage of the generated provider it produces elsewhere in the workspace (.g.dart locations are never shown). Prefers the Dart analyzer's own references when available, falling back to a text scan otherwise.
- Step-by-step resolution tracing in the "Riverpod Wayfinder" Output channel for troubleshooting - see Troubleshooting below.
Install
Not yet published to a marketplace — grab the .vsix from the Releases page (or build it yourself, see Development) and install it manually:
- Open VSCode → Extensions view →
··· menu → Install from VSIX...
- Pick the downloaded
riverpod-wayfinder-*.vsix file
Or from the command line:
code --install-extension riverpod-wayfinder-0.3.0.vsix
Usage
- Place your cursor on (or select) a provider usage, e.g.
viewFreshnessProvider
- Jump to its declaration with any of:
Ctrl+F12 (Windows/Linux) / Cmd+F12 (Mac) — "Go to Implementation" — always lands directly on the source, no picker
Ctrl+Click / Cmd+Click (or F12) — "Go to Definition" — usually opens a picker with both the generated .g.dart location and the hand-written source; choose the one you want
Ctrl+Alt+D (Windows/Linux) / Cmd+Alt+D (Mac), or run "Riverpod Wayfinder: Go to Provider Source" from the Command Palette
Example
A single grouped file with multiple providers, mixing styles — the exact case this extension exists for:
// In view_freshness.providers.dart
@riverpod
class ViewFreshness extends _$ViewFreshness { /* ... */ }
@riverpod
int viewFreshnessScore(Ref ref) { /* ... */ } // Ctrl+F12 on viewFreshnessScoreProvider jumps HERE, not to ViewFreshness
@riverpod
class ViewFreshnessHistory extends _$ViewFreshnessHistory { /* ... */ } // and viewFreshnessHistoryProvider jumps HERE
Why does Ctrl+Click / Cmd+Click show a picker instead of jumping directly?
Ctrl+Click triggers VSCode's Go to Definition, which is aggregated across every extension that registers a DefinitionProvider for the dart language — including the official Dart extension, which resolves provider usages to the generated .g.dart file (that's genuinely where the symbol is defined). VSCode does not let one provider's result "win" by priority, order, or speed; when more than one location comes back, it shows a picker/peek list of all of them. Riverpod Wayfinder registers a DefinitionProvider too, so its answer (the hand-written source) shows up in that list next to Dart's — it does not, and cannot, override or suppress Dart's own contribution.
If you don't want to pick every time, use Go to Implementation (Ctrl+F12 / Cmd+F12) instead — a separate gesture the Dart extension doesn't contribute to, so it's uncontested and always jumps straight to the hand-written source.
Why does Shift+F12 ("Find All References") sometimes still show a .g.dart location?
Same root cause as the Ctrl+Click picker above: VSCode aggregates every registered ReferenceProvider, and Riverpod Wayfinder's own contribution never includes a .g.dart location — but the official Dart extension's contribution can. If your generated code genuinely calls back into your hand-written symbol (which it usually does at least once, e.g. PackageMetrics create() => PackageMetrics(); in a class-based provider's generated file), that's a real reference from Dart's point of view, and Dart's ReferenceProvider reports it correctly. There's no supported way to filter another extension's contribution out of the merged list.
How it works
- Finds the
.g.dart file that contains the clicked provider
- Reads its
part of statement to locate the hand-written .dart file
- Identifies which
@ProviderFor(...) annotation belongs to the specific provider you clicked (not just the first one in the file)
- Jumps to the matching
class or @riverpod-annotated function declaration
Requirements
- VSCode 1.74.0+ (also works in VSCode-based editors like Cursor)
- The Dart extension (for
.g.dart generation and everyday Dart support)
Troubleshooting
Riverpod Wayfinder logs every resolution decision (candidate .g.dart files checked, inferred class/function name, resolved target line, and any errors) to its own "Riverpod Wayfinder" channel in the Output panel:
- View → Output, then pick "Riverpod Wayfinder" from the channel dropdown.
- Step-by-step tracing is hidden by default. To see it, click the gear icon in that channel's toolbar (or run "Developer: Set Log Level..." → "Riverpod Wayfinder") and set the level to Debug or Trace.
- Errors (a file that couldn't be read, a failed analyzer call, ...) always show, regardless of that level.
Known issues
- Relies on the
.g.dart file's part of statement to find the source file — unusual codegen setups may not resolve.
- Class/function name inference uses a casing heuristic (uppercase first letter → class, lowercase → function); hand-written code that breaks Dart naming conventions may not resolve correctly.
Shift+F12 can still show a .g.dart location contributed by the Dart extension itself — see the FAQ above, not something this extension can suppress.
- The
Shift+F12 text-scan fallback (used when the Dart analyzer returns no results) is a plain word-boundary match — it can't tell a real usage from an identical name inside a comment or string literal.
Roadmap
This extension focuses on one thing — reliable navigation — but there's a lot more Riverpod friction that no existing extension addresses well yet: a workspace health-check command, dependency graphs, codegen-migration helpers, and more. See ROADMAP.md for the running list of ideas — contributions and votes welcome.
Development
npm install
npm run test:unit # pure resolver unit tests, no editor required
npm run compile # type-check, lint, bundle
npx @vscode/vsce package # build an installable .vsix
For the full integration check (does Ctrl+F12 actually jump correctly inside a real editor), open this folder in VSCode and press F5 to launch an Extension Development Host, open a .dart file with generated providers, and try it — this step needs a human at the keyboard.
The resolution logic lives entirely in src/resolver.ts, with zero vscode imports — it's a pure function tested against realistic multi-provider fixtures in test/fixtures/. src/extension.ts is a thin VSCode-facing wrapper.
Contributing
Issues and pull requests are welcome — this is meant to be a genuinely community-owned tool. If you hit a case that doesn't resolve correctly, please include a minimal .dart + .g.dart pair that reproduces it; that's usually enough to turn into a regression test.
Credits
This is a fork of shinriyo/riverpod-jump-to-provider — all credit for the original idea goes to @shinriyo. This fork fixes the multi-provider resolution bugs, switches the primary gesture to Go to Implementation so it actually works reliably, and adds a DefinitionProvider alongside Dart's own so Ctrl+Click offers a choice instead of only ever going to the generated file.
License
MIT — 100% free and open source, no strings attached. See LICENSE.