Before you change a component's props, see every call site and exactly which props each one passes -> so a prop rename, removal, or type change never silently breaks half the app.
PropDiff scans your workspace for every usage of a React (JSX/TSX), Vue SFC, or Svelte component, parses the actual props passed at each site, compares them against the component's declared props, and turns the result into a clickable report.
Features
Usage finder
- Finds every
<ComponentName ...>tag across the workspace, including multi-line tags and self-closing tags - Parses each usage site into prop name, raw value text, and a value kind:
- string literal (
variant="primary") - number (
size={2}) - boolean shorthand (
disabled) - expression (
variant={dynamicVariant}) - spread (
{...rest}) - event handler (
onClick={save},@close="onClose",on:click={handle})
- string literal (
- Vue support: scans only the
<template>section and matches both PascalCase and kebab-case tags, including:propbindings and@eventhandlers - Svelte support:
on:handlers,{value}shorthand, and{...spread} - Respects the
propDiff.excludeGlobssetting (node_modules, dist, build, and similar are excluded by default)
Component definition analysis
Locates the component's own definition and parses its declared props, best-effort, from:
- TypeScript: props interface/type or destructured props parameter (defaults detected from
= value) - PropTypes:
Component.propTypesplusComponent.defaultProps - Vue:
defineProps<{...}>(),defineProps({...}), options APIprops: {...}orprops: [...] - Svelte:
export let name(with or without a default)
Analysis and warnings
- Prop usage matrix: for each prop, how many sites pass it, like
variant -> 12/15 usages - Per-site warnings:
- Unknown prop: passed at a site but not in the declared prop set
- Missing prop: declared without a default and passed at most other sites, but absent here
- Inconsistent value kind: the same prop is passed as a string at some sites and as a number or expression at others
Report panel
The PropDiff activity bar view shows:
- Summary header: component name, clickable definition location, total usages, files, warnings, and scan time
- Declared props with required/optional/default markers
- The prop usage matrix as frequency chips
- Per-file groups listing every usage with its props, value kinds, and warnings
- Every row is clickable -> jumps to that exact usage location
- Refresh button re-runs the analysis
- Copy report button puts a markdown report (matrix table plus per-usage table) on the clipboard
CodeLens
Exported PascalCase components in JSX/TSX files, and Vue/Svelte single-file components, get a CodeLens above the definition:
5 usages -> PropDiff
Click it to analyze that component immediately.
Status bar
While a report is open, the status bar shows PropDiff: <Component> | N usages; click it to focus the report panel.
Commands
| Command | What it does |
|---|---|
| PropDiff: Analyze Component | Analyze the component under the cursor, or pick from recently analyzed components |
| PropDiff: Re-run Last Analysis | Repeat the previous analysis after editing |
| PropDiff: Refresh Report Panel | Refresh the report currently shown in the panel |
| PropDiff: Copy Report as Markdown | Copy the full markdown report to the clipboard |
Usage
- Open a JSX/TSX, Vue, or Svelte file and place the cursor on a component name
- Run PropDiff: Analyze Component (command palette or editor context menu), or click the
N usages -> PropDiffCodeLens above a component definition - Read the report in the PropDiff panel: matrix, per-file usages, warnings
- Click any usage row to jump to it; use Copy Report as Markdown to share the findings in a PR
A walkthrough is available under Help -> Get Started -> Get Started with PropDiff.
Example
Component definition in Button.tsx:
interface ButtonProps {
variant: 'primary' | 'secondary';
size?: number;
onClick?: () => void;
}
export function Button({ variant, size = 2, onClick }: ButtonProps) {
return <button className={variant}>...</button>;
}
PropDiff report:
<Button> Definition: src/Button.tsx:6 (typescript)
15 usages | 6 files | 2 warnings
variant -> 14/15 size -> 9/15 onClick -> 12/15
src/pages/Dashboard.tsx
:42 <Button variant="primary" onClick={onSave} />
:77 <Button size={3} />
Missing prop "variant" -> declared without a default and passed at 14/15 sites
src/legacy/Toolbar.tsx
:12 <Button variant={2} color="red" />
Inconsistent value kind for "variant" -> number here, usually string
Unknown prop "color" -> not in the declared props of Button
Configuration
{
"propDiff.excludeGlobs": [
"**/node_modules/**",
"**/dist/**",
"**/build/**",
"**/out/**",
"**/.next/**",
"**/coverage/**"
],
"propDiff.maxResults": 500
}
Supported frameworks
- React (JSX/TSX)
- Vue 2/3 single-file components
- Svelte
Requirements
- VS Code 1.85.0 or higher
Author
Kanaihya Kumar -> [email protected]
License
MIT