PropDiff
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})
- Vue support: scans only the
<template> section and matches both PascalCase and kebab-case tags, including :prop bindings and @event handlers
- Svelte support:
on: handlers, {value} shorthand, and {...spread}
- Respects the
propDiff.excludeGlobs setting (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.propTypes plus Component.defaultProps
- Vue:
defineProps<{...}>(), defineProps({...}), options API props: {...} or props: [...]
- 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 -> PropDiff CodeLens 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
Author
Kanaihya Kumar -> kanaihyakmr@gmail.com
License
MIT