Stop guessing what your CSS classes do — hover and see everything instantly.
Class Spy turns your class and className attributes into interactive CSS explorers. Hover over any class string in your code and instantly see:
No more switching between files, no more "where did I define this style?", no more memorizing Tailwind scales.
| Feature | Description |
|---|---|
| Hover Reveal | Hover over any className="...", class="...", :class, [ngClass], or cn() / clsx() call to instantly see all matching CSS definitions. |
| Tailwind Decoder | Automatically decodes Tailwind utility classes (bg-red-500, p-4, flex) into their generated CSS equivalents and combines them into a single output block. |
| Workspace-wide Indexing | Scans your entire workspace for .css, .scss, .sass, .less, and inline <style> blocks in .vue, .svelte, .astro, .html, .jsx, .tsx. |
| Clickable References | Every found definition includes a clickable link to its file and line number, opening in a new tab for quick navigation. |
| Edit in Place | Click Edit next to any CSS rule to open the source file with the rule auto-selected — modify and save directly. |
| Live Updates | File watchers keep the CSS index updated automatically as you add, modify, or delete styles. |
Search for "Class Spy" in the Extensions panel (Ctrl+Shift+X / Cmd+Shift+X) and click Install.
Download the latest .vsix from the Releases page, then run:
code --install-extension class-spy-0.0.2.vsix
// React / TSX
<div className="flex p-4 bg-red-500 text-white">
Hover anywhere inside "flex p-4 bg-red-500 text-white" and you will see:
.flex, .p-4, .bg-red-500, .text-white rules found across your workspace, with file paths and line numbers.Click Open styles.css:12 to jump to the rule in a new editor tab.
Click Edit next to any definition. The source file opens in a split tab with the exact rule highlighted. Modify it and save with Ctrl+S.
Works inside JSX/TSX template literals and interpolations:
// Template literals with dynamic prefixes
<div className={`${base}-btn flex p-4`}>
// Ternary expressions — still decodes quoted strings
<div className={`${isActive ? 'bg-red-500' : 'bg-blue-500'} flex`}>
Static classes are always shown. Quoted string literals inside ${…} blocks are extracted as a best-effort, so you still see CSS definitions and Tailwind decoding for conditional classes.
Works inside cn(), clsx(), and classNames() calls:
// shadcn/ui, Radix, etc.
<div className={cn("flex p-4", isActive && "bg-blue-600")}>
.html, .htm).jsx, .tsx).vue).svelte).astro)[ngClass], [class], ng-class).css.scss.sass.less<style> blocks inside templatesClass Spy includes a comprehensive test suite covering all core modules.
npm install
npm run compile
npm test
| Module | Tests | Coverage |
|---|---|---|
| Tailwind Decoder | 50+ utility classes decoded, arbitrary value syntax ([...]), invalid class handling |
>90% |
| CSS Indexer | Selector parsing (simple & compound), inline <style> extraction, deduplication, file watcher updates |
>85% |
| Hover Provider | class / className / cn() extraction, combined output formatting, edge cases |
>80% |
| Extension | Command registration, integration smoke tests | >75% |
npm install
npm run compile
npm run watch
npm run lint
npx vsce package
npx vsce publish
Contributions are welcome! Please open an issue or pull request on GitHub.
git checkout -b feature/amazing-feature)git commit -m 'Add amazing feature')git push origin feature/amazing-feature)If Class Spy saves you time and you want to keep it growing, consider supporting the project:
Your support helps fund new features, better Tailwind coverage, and more framework support.
MIT © Class Spy Contributors
See CHANGELOG.md for release history.