Navigate between Convex backend functions and their frontend usages. Find all references from backend to frontend code.
When working with Convex, VS Code's native "Find All References" doesn't work for Convex functions because:
- Backend functions are exported like:
export const createContact = mutation({...}) - Frontend code accesses them via:
useMutation(api.domains.contacts.createContact)
The frontend doesn't directly import createContact from your backend file. Instead, it imports from the auto-generated _generated/api module, which re-exports all your functions. TypeScript sees api.domains.contacts.createContact as a completely different symbol than your export const createContact - there's no direct reference between them.
This means when you're in your backend code and want to find where createContact is used in the frontend, "Find All References" returns nothing.
Convex Navigator solves this problem.
When your cursor is on a Convex function definition, use Find Convex Usages to discover all places in your frontend code where this function is called.
- Keyboard shortcut:
Ctrl+Shift+U(Windows/Linux) orCmd+Shift+U(Mac) - Context menu: Right-click and select "Find Convex Usages"
- Command palette:
Ctrl+Shift+P/Cmd+Shift+P-> "Find Convex Usages"
Results appear in VS Code's native references panel, just like regular "Find All References".
Hover over any api.X.Y.Z pattern in your frontend code to see:
- Function name and type (query, mutation, action)
- The wrapper function used (e.g.,
authedMutation,query) - Args schema preview
- Clickable link to jump directly to the implementation
- Open VS Code
- Go to Extensions (
Ctrl+Shift+X/Cmd+Shift+X) - Search for "Convex Navigator"
- Click Install
- Download the
.vsixfile from the releases page - In VS Code, go to Extensions >
...(menu) > "Install from VSIX..." - Select the downloaded file
git clone https://github.com/your-username/convex-navigator.git
cd convex-navigator
npm install
npm run package
code --install-extension convex-navigator-0.1.0.vsix- Install the extension
- Open a workspace containing a Convex project (must have
convex.config.ts) - Open a backend file (e.g.,
convex/domains/contacts.ts) - Place your cursor on a function name like
createContact - Press
Cmd+Shift+U(orCtrl+Shift+Uon Windows/Linux) - See all usages in the references panel!
Configure the extension in your VS Code settings. Open settings with Cmd+, (Mac) or Ctrl+, (Windows/Linux), then search for "Convex Navigator".
Or add to your .vscode/settings.json:
{
"convexNavigator.convexPath": "",
"convexNavigator.frontendPaths": [],
"convexNavigator.customWrappers": [],
"convexNavigator.excludePatterns": [
"**/node_modules/**",
"**/_generated/**",
"**/dist/**",
"**/out/**",
"**/.git/**"
]
}| Setting | Type | Default | Description |
|---|---|---|---|
convexNavigator.convexPath |
string |
"" |
Path to Convex directory relative to workspace root. Leave empty for auto-detection. |
convexNavigator.frontendPaths |
string[] |
[] |
Directories to search for usages. Empty = search entire workspace. |
convexNavigator.customWrappers |
string[] |
[] |
Custom wrapper function names to detect as Convex functions. |
convexNavigator.excludePatterns |
string[] |
(see above) | Glob patterns to exclude from search. |
The following wrappers are detected automatically (built into Convex):
querymutationactioninternalQueryinternalMutationinternalAction
If you use custom wrapper functions (common in authenticated Convex setups), add them to settings:
{
"convexNavigator.customWrappers": [
"authedQuery",
"authedMutation",
"authedAction",
"authedZodQuery",
"authedZodMutation",
"authedZodAction",
"publicQuery",
"publicMutation"
]
}The extension will then detect exports like:
export const createContact = authedZodMutation({...});
export const getUser = authedQuery({...});Backend file: convex/domains/contacts.ts
import { authedZodMutation } from "../utils/authedFunctions";
import { z } from "zod";
export const createContact = authedZodMutation({
args: z.object({
contact: contactFormSchema,
}),
handler: async (ctx, args) => {
const { user } = ctx;
// ... implementation
return { contactId };
},
});
export const updateContact = authedZodMutation({
args: z.object({
contactId: z.string(),
contact: contactFormSchema,
}),
handler: async (ctx, args) => {
// ... implementation
},
});Frontend file: src/routes/contacts/new.tsx
import { api } from "@backend/_generated/api";
import { useMutation } from "convex/react";
function NewContactPage() {
const createContact = useMutation(api.domains.contacts.createContact);
const handleSubmit = async (data) => {
await createContact({ contact: data });
};
// ...
}To find usages:
- Open
convex/domains/contacts.ts - Click on
createContact(the function name) - Press
Cmd+Shift+U - The references panel shows
src/routes/contacts/new.tsx:6
When you hover over api.domains.contacts.createContact in your frontend code, you'll see:
createContact (mutation)
Wrapper: authedZodMutation
Args: z.object({ contact: contactFormSchema })
convex/domains/contacts.ts:5
Click the file path to jump directly to the implementation.
For monorepos with the Convex backend in a separate package:
Project structure:
my-monorepo/
├── apps/
│ ├── web/src/ # Frontend app 1
│ └── admin/src/ # Frontend app 2
├── packages/
│ └── backend/
│ └── convex/ # Convex functions here
│ ├── convex.config.ts
│ ├── _generated/
│ └── domains/
│ └── contacts.ts
Configuration:
{
"convexNavigator.convexPath": "packages/backend/convex",
"convexNavigator.frontendPaths": ["apps/web/src", "apps/admin/src"]
}If search is slow, limit the search scope:
{
"convexNavigator.frontendPaths": [
"src/components",
"src/routes",
"src/hooks"
],
"convexNavigator.excludePatterns": [
"**/node_modules/**",
"**/_generated/**",
"**/dist/**",
"**/build/**",
"**/coverage/**",
"**/*.test.ts",
"**/*.spec.ts",
"**/__tests__/**"
]
}On activation, the extension searches for:
convex.config.ts- The Convex configuration fileconvex/_generated/api.ts- The auto-generated API file
This determines your Convex directory location.
When you invoke "Find Convex Usages", the extension:
- Checks if your cursor is on a Convex function export
- Parses the pattern:
export const <name> = <wrapper>({...}) - Builds the API path:
api.<relative-path>.<function-name>
For example:
- File:
convex/domains/contacts.ts - Export:
createContact - API path:
api.domains.contacts.createContact
The extension searches for the API path pattern using:
- ripgrep (if available) - Extremely fast, searches entire codebase in milliseconds
- VS Code's built-in search - Fallback if ripgrep is not installed
Results appear in VS Code's native references panel, showing:
- File path
- Line number
- Code preview
- Click to navigate
Symptoms: No "Find Convex Usages" in context menu, hover not working.
Solutions:
- Ensure your workspace contains
convex.config.tsorconvex/_generated/api.ts - Check the Output panel: View > Output > Select "Convex Navigator"
- Try reloading VS Code:
Cmd+Shift+P> "Developer: Reload Window"
Symptoms: "Cursor is not on a Convex function definition" when it clearly is.
Solutions:
- Add your wrapper to settings:
{ "convexNavigator.customWrappers": ["yourCustomWrapper"] } - Ensure the export follows the pattern:
export const functionName = wrapper({...});
- The wrapper name must match exactly (case-sensitive)
Symptoms: Search completes but shows 0 usages.
Solutions:
- Verify the API path is correct (check how it's imported in frontend)
- Check if the file is excluded by
convexNavigator.excludePatterns - If using
frontendPaths, ensure the usage file is in one of those paths - Check for typos in the import path
Symptoms: Search takes several seconds or times out.
Solutions:
-
Install ripgrep for faster searching:
# macOS brew install ripgrep # Ubuntu/Debian sudo apt install ripgrep # Windows choco install ripgrep
-
Configure
frontendPathsto limit search scope -
Add large directories to
excludePatterns
Symptoms: Extension found wrong convex.config.ts (e.g., in node_modules).
Solutions:
- Explicitly set the path:
{ "convexNavigator.convexPath": "packages/backend/convex" }
| Command | Windows/Linux | Mac | Description |
|---|---|---|---|
| Find Convex Usages | Ctrl+Shift+U |
Cmd+Shift+U |
Find all frontend usages of the function under cursor |
To change the keyboard shortcut:
- Open Keyboard Shortcuts:
Cmd+K Cmd+S(Mac) orCtrl+K Ctrl+S(Windows/Linux) - Search for "Find Convex Usages"
- Click the pencil icon and enter your preferred shortcut
my-project/
├── convex/
│ ├── convex.config.ts
│ ├── _generated/
│ └── functions.ts
└── src/
└── App.tsx
No configuration needed - auto-detected.
monorepo/
├── packages/
│ └── backend/
│ └── convex/
│ ├── convex.config.ts
│ └── domains/
└── apps/
└── web/
└── src/
Configure:
{
"convexNavigator.convexPath": "packages/backend/convex",
"convexNavigator.frontendPaths": ["apps/web/src"]
}monorepo/
├── convex/
└── apps/
├── web/src/
├── mobile/src/
└── admin/src/
Configure:
{
"convexNavigator.frontendPaths": [
"apps/web/src",
"apps/mobile/src",
"apps/admin/src"
]
}Contributions are welcome! Please feel free to submit issues and pull requests.
- VS Code: Version 1.85.0 or higher
- Convex Project: Must have
convex.config.tsorconvex/_generated/api.ts - Optional: ripgrep for faster searching
MIT License - see LICENSE for details.
- Convex for the excellent backend platform
- The VS Code Extension API documentation
- The ripgrep project for blazing-fast search
Disclaimer: This extension is not officially affiliated with Convex. It is a community-built tool to improve the developer experience.