{"_id":"dead-styles","_rev":"8-7771de9638ba1dbe90086bd521107bd6","name":"dead-styles","dist-tags":{"latest":"0.1.7"},"versions":{"0.1.0":{"name":"dead-styles","version":"0.1.0","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.0","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"4e451050fdb3a43208deaf6dd872965a4ee8e664","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.0.tgz","fileCount":17,"integrity":"sha512-i2zD7BZlmESF7qfZcI+2+Wl+ULVYFVPkWrU515LfsQ4DVmWsKn89s/eTM68/SM0wHdf2nX0OA0aiSyUbYGBqtw==","signatures":[{"sig":"MEUCIDtA8HdhbI9WOSpdaPNu3bFX+o5XzUcSvozllCm5xwoUAiEA8u6dVWGGBD8SzxGelW6cAnsyYDAJBXI55KgP0yVz6c0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":28073},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"12aed092a6415f939f0056d33bb8154519d5c11d","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.0_1789583356877_0.916927081659578","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"dead-styles","version":"0.1.1","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.1","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"c56f29ec4f73b6b2b70471cb919507ee85609a0c","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.1.tgz","fileCount":17,"integrity":"sha512-J1PW2nh4JNJZRVN7go6bLVfrX+fsvan1xHzI3l8qTXidPxCsAbXJ60qCRZrWjEFhRNOdbVEpQaGEG3ctFAx37w==","signatures":[{"sig":"MEUCIQCEgcnE2kIUxJCgPFJcRDfIx/Kdj/ol8uscWDNAOl8oAQIgf4DnDj1zsOaRABpkhD1oBUSqR7KKODsayltABCdGWC4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33081},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"7099e250d97f06a739b22a728eb0bd2e3ee4e424","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.1_1789584070891_0.5416208238107316","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"dead-styles","version":"0.1.2","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.2","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"1a925daec8671b5ce1589fd4162effc35e1ddcb6","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.2.tgz","fileCount":17,"integrity":"sha512-7H+8b8jOzJtTHoofIQ4f3bBV2AHqN1IgXS5o9fqwuPePek6u8GrpEHGpkoCzfVzQ+uxBNXZLztwofbWleSIV/w==","signatures":[{"sig":"MEQCID9MRiBNHa8guic1EpuVf8Oano7AmbEbDMlfQLla7noEAiBuI55mKZLInKXtIpBZoSEaS5lckZa63h7FTMczZuieQQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34550},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"35179e6655d59d373a0a44d98c7429af8a026712","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.2_1789584604069_0.11878812078365275","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"dead-styles","version":"0.1.3","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.3","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"0f1b8fe202a661486c16f4a7d4cda27db09d3894","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.3.tgz","fileCount":17,"integrity":"sha512-yB839tJVdU51b1MDsRdR8X2qRARKgrcqapTqHNJuTla595fucnUYJeV+oaAKsWMg5T1s2LbRmqaG/fkNUFd9bQ==","signatures":[{"sig":"MEYCIQDFtUw5r77Lx5eiQKQBXlSx/CAwvWuFjVahZwbh95hg4QIhALjj6TNiLxN4XuRDB++qQ9bfjKomQAxL1k0rfEA/rDQD","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34967},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"d38f4181a05d3cd3bbd79e85de1d385cfcb23132","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.3_1789585338208_0.2781181113738378","host":"s3://npm-registry-packages-npm-production"}},"0.1.4":{"name":"dead-styles","version":"0.1.4","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.4","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"538e7d91edfb57f92f4878220a89919e7f7d6bf8","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.4.tgz","fileCount":17,"integrity":"sha512-t3GndR2FNQeRHiY9gL76XQL2BVaXQe4XHhIE0I6rJRefwvRM3WOtPcy26E2xa+9ortq7Spwsj9r5P4I4wqEM5Q==","signatures":[{"sig":"MEQCIGA/OF5SVzel0uYA+tuXrar2zYnC0X0RVvy5ZlFk6lmeAiBG8XazvcpiNCCOltHT+qtW0Ks4wAqUSZ6jQmVqbgHjAQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36272},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"6a9ec7560dfa244481f6b2e547e24ba939b31124","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.4_1789586265590_0.49769038298692414","host":"s3://npm-registry-packages-npm-production"}},"0.1.5":{"name":"dead-styles","version":"0.1.5","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.5","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"444d63e29f83b2853545e679abc52da458c955ec","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.5.tgz","fileCount":19,"integrity":"sha512-xQWkZmizFqpqNT9nrBV+iNgIeCUcyvlfAdNMf55LJ2RRlnFa4nTp5dsRSGFMBZFl9iYvdSZLtMNpW5zJJTAMew==","signatures":[{"sig":"MEUCIQCOItCTQWtIDaX7EDxAeN0sXWghDbY1O68CsO8rNCRiSwIgMnqKCyyJTYlnuzeR3oiZlAkmEq6oy3jTr4k8NHJU+lY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45312},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"f569ee601cf5fdf115b80ec1bc1fef84a46d0874","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.5_1789587556829_0.7164067540304122","host":"s3://npm-registry-packages-npm-production"}},"0.1.6":{"name":"dead-styles","version":"0.1.6","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","_id":"dead-styles@0.1.6","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"homepage":"https://github.com/frontbond/dead-styles#readme","bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"bin":{"dead-styles":"dist/cli.js"},"dist":{"shasum":"468d46f67f2905e4d60eee05152515cb3c06530b","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.6.tgz","fileCount":23,"integrity":"sha512-0ZDzLXcXU2xm5xC5tJcGSuQ+5PKKkxoP64ZEN/nxKVXdFrWrtcJE9DTO5l+MBFgX4Fdz+Ypv5OB2nZR6EC/5VA==","signatures":[{"sig":"MEQCIEhPH2N4h6tIsz1tmupjrxSec0ZqpfYv4Xh8x/vs4CNkAiBZ4QLoubvBmLak8/5beMnGsVFuekphBn+Uz22ksyohVA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53609},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","engines":{"node":">=18"},"gitHead":"ee22f7e79055f1e575030f9857e28d55a22fa199","scripts":{"test":"node --experimental-vm-modules node_modules/.bin/vitest run","build":"tsc -p tsconfig.build.json","prepublishOnly":"npm run build"},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"repository":{"url":"git+https://github.com/frontbond/dead-styles.git","type":"git"},"_npmVersion":"12.0.2","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) and unused global Sass/SCSS/CSS classes across your whole project, not just one file","directories":{},"_nodeVersion":"22.23.2","dependencies":{"ts-morph":"^24.0.0","commander":"^12.1.0"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","typescript":"^5.6.0","@types/node":"^22.20.3"},"_npmOperationalInternal":{"tmp":"tmp/dead-styles_0.1.6_1789588589768_0.5755943679842459","host":"s3://npm-registry-packages-npm-production"}},"0.1.7":{"name":"dead-styles","version":"0.1.7","description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) and unused global Sass/SCSS/CSS classes across your whole project, not just one file","type":"module","bin":{"dead-styles":"dist/cli.js"},"main":"dist/index.js","types":"dist/index.d.ts","scripts":{"build":"tsc -p tsconfig.build.json","test":"node --experimental-vm-modules node_modules/.bin/vitest run","prepublishOnly":"npm run build"},"keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"author":{"name":"frontbond"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/frontbond/dead-styles.git"},"bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"homepage":"https://github.com/frontbond/dead-styles#readme","engines":{"node":">=18"},"dependencies":{"commander":"^12.1.0","ts-morph":"^24.0.0"},"devDependencies":{"@types/node":"^22.20.3","typescript":"^5.6.0","vitest":"^2.1.0"},"gitHead":"540cf5d659e7231652f1bb86f61cf4c84b53e7fc","_id":"dead-styles@0.1.7","_nodeVersion":"22.23.2","_npmVersion":"12.0.2","dist":{"integrity":"sha512-ifrdZd5HxbkhWUIejCokcEEskk40bWmFXxNdi8Iy82n/3Bk+vVwP3OOjQfs6Y66mraezUb8tYVj8s6tdxYlS1w==","shasum":"ce463f006c27556d74cb9105e4d29724e74071a8","tarball":"https://registry.npmjs.org/dead-styles/-/dead-styles-0.1.7.tgz","fileCount":23,"unpackedSize":55562,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEDEb+yDqWeFdKTn4+FZD8IoKtYcnbt3n6Uhq53oSU1DAiEA185U6ARk7iEOAgTrwLJpoHil8ReimUREratUpU+YdF0="}]},"_npmUser":{"name":"mr.bond","email":"frontbond@gmail.com"},"directories":{},"maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/dead-styles_0.1.7_1789642008759_0.4542419734859653"},"_hasShrinkwrap":false}},"time":{"created":"2026-09-16T18:29:16.801Z","modified":"2026-09-17T10:46:49.050Z","0.1.0":"2026-09-16T18:29:17.019Z","0.1.1":"2026-09-16T18:41:11.127Z","0.1.2":"2026-09-16T18:50:04.219Z","0.1.3":"2026-09-16T19:02:18.348Z","0.1.4":"2026-09-16T19:17:45.747Z","0.1.5":"2026-09-16T19:39:16.961Z","0.1.6":"2026-09-16T19:56:29.930Z","0.1.7":"2026-09-17T10:46:48.896Z"},"bugs":{"url":"https://github.com/frontbond/dead-styles/issues"},"author":{"name":"frontbond"},"license":"MIT","homepage":"https://github.com/frontbond/dead-styles#readme","keywords":["css-in-js","tss-react","makeStyles","mui","jss","unused-css","dead-code","static-analysis","knip"],"repository":{"type":"git","url":"git+https://github.com/frontbond/dead-styles.git"},"description":"Find unused CSS-in-JS classes (tss-react / MUI makeStyles / JSS) and unused global Sass/SCSS/CSS classes across your whole project, not just one file","maintainers":[{"name":"mr.bond","email":"frontbond@gmail.com"}],"readme":"# dead-styles\n\nFind CSS-in-JS classes (tss-react / MUI `makeStyles` / JSS) that are defined but never used **anywhere in the project** — including when the styles hook is defined in one file and called from several others (a very common convention: `Component.styles.ts` + `Component.tsx`, or a shared hook consumed by many components across a monorepo).\n\n> Unofficial, third-party tool. Not affiliated with or endorsed by tss-react, MUI, or Knip.\n\n## Why not just use an ESLint rule?\n\nThere's already a good ESLint rule for this: [`eslint-plugin-tss-unused-classes`](https://github.com/garronej/eslint-plugin-tss-unused-classes), officially recommended by the [tss-react docs](https://docs.tss-react.dev/detecting-unused-classes). Use it if it fits your setup.\n\nIts limitation (inherent to how ESLint rules work — one file's AST at a time) is that it can only see a class as \"used\" if `classes.foo` appears **in the same file** as the `makeStyles`/`tss.create()` call. The moment styles are defined in their own file and the hook is called from a different file (or from several different files/packages), every class in that styles file gets reported as unused — a 100% false-positive rate for that very common layout.\n\n`dead-styles` uses the TypeScript compiler API (via [ts-morph](https://github.com/dsherret/ts-morph)) to resolve the hook's declaration, find **every** call site across the whole project (any file, any package in a monorepo), and union up class usage across all of them before deciding anything is dead.\n\n## What it supports\n\n- `makeStyles((theme) => ({...}))` — classic MUI v4 / `@mui/styles` single-call form\n- `makeStyles(options)((theme, params) => ({...}))` — tss-react's curried `createMakeStyles()` form\n- `makeStyles()({...})` exported as a bare `export default` (the `tss-react/mui` convention), with **no local variable at all** — each importing file picks its own local name, and every one of them is resolved back to the same definition\n- `tss.create({...})` / `tss.create((params) => ({...}))`\n- `tss.withParams<...>().create(...)`, `tss.withName(...).create(...)`, and any other chain ending in `.create(...)`\n- Both `const classes = useStyles()` (direct binding) and `const { classes } = useStyles()` (destructured, with or without renaming)\n- A hook re-assigned to a plain local variable before it's called (`import styles from \"./styles\"; const useStyles = styles; ...; useStyles()`), followed transitively through any number of hops\n- Cross-file and cross-package (monorepo `paths`-alias) resolution of every call site\n\n## What it deliberately does NOT guess\n\nTo keep the false-positive rate near zero, `dead-styles` skips (rather than reports on) a hook whenever it can't fully verify usage:\n\n- The styles object has a computed property key (`{ [dynamic]: {...} }`) — the class's real name isn't known statically.\n- A class is accessed via a computed/dynamic key (`classes[someVariable]`) instead of `classes.foo` — could be any class.\n- The whole `classes` object is forwarded somewhere we can't follow (spread with `{...classes}`, passed as a prop to a child component, assigned to another variable, returned from a function, etc.).\n- The hook **itself** (not its call result) is spread into a different `makeStyles()`/`tss.create()` call's styles object elsewhere — a real production pattern: `const styles = { ...stylesRow, ...stylesRowInner }; const useStyles = makeStyles()(styles);`. That merged, re-wrapped hook can make any of the spread hook's classes reachable through a call site that never actually calls the *original* hook at all, so once this is seen, nothing about that original hook is reported as dead.\n\nSkipped hooks are reported separately so you know what wasn't checked, but never show up as \"dead.\"\n\n## Global stylesheet classes (`--sass` / `--scss` / `--css`)\n\nSome projects also keep a global stylesheet of plain classes (text styles, color utilities, etc.), applied via literal strings (`className=\"textStylesActive\"`, `clsx(...)`, `classnames(...)`) rather than through a CSS-in-JS hook. Pass one or more `--sass <path>` (indented syntax), `--scss <path>` (brace syntax), and/or `--css <path>` flags — any combination, repeatable — to also check those:\n\n```bash\nnpx dead-styles scan --tsconfig ./tsconfig.json \\\n  --sass ./src/styles/global.sass \\\n  --scss ./src/styles/global.scss \\\n  --css ./src/styles/global.css\n```\n\nThis works completely differently from the CSS-in-JS strategy above — there's no hook, no call site, no `classes` object to trace. Instead:\n\n1. Every **top-level** class selector in the file is a candidate — `.foo` or `.foo, .bar` (including split across lines). \"Top-level\" means different things depending on the syntax:\n   - `--sass` (indented syntax): an unindented line. A pseudo-class like `&:hover`, a modifier block like `.root-blazing .foo`, or anything under a `@media` block is indented, so it's a nested reference, not a definition, and is ignored.\n   - `--scss` / `--css` (brace syntax): a selector block that isn't nested inside any `{ }` at all. SCSS nesting (`&:hover { ... }`, `.foo .bar { ... }`), and anything inside an `@media`/`@supports`/`@keyframes`/`@font-face` block, is one level deeper and is ignored the same way.\n2. Every JS/TS/JSX/TSX file in the project is scanned for that exact class name appearing anywhere as a literal token — as a bare string, inside `clsx()`/`classnames()`/`cx()` (string arguments or object keys), or inside a template literal.\n3. Anything never found this way is reported as an unused global stylesheet class.\n\n**Known blind spots**:\n\n- A class name assembled dynamically at runtime (`'textStyles' + variant`) won't be seen as a literal token and will be reported as unused even if it's actually applied. This is a one-directional risk — it can under-report (miss a real usage) but never over-report a class that's genuinely referenced by a static string, so it's a safe default, just not exhaustive.\n- Only simple class selectors are recognized as definitions; compound selectors (`.a.b`), descendant/tag/id selectors, and anything nested (see above) aren't picked up as definitions — they're silently skipped, never guessed at.\n- For `--scss`, a `//` line comment right before a `url(...)` is deliberately *not* treated as the start of a comment when it's preceded by a `:` (covers `url(http://...)`/`url(https://...)`), but an unquoted, protocol-relative `url(//cdn.example.com/...)` has no `:` to guard it and could still be mis-treated as a comment start. Quoting the URL (`url(\"//cdn.example.com/...\")`) avoids this entirely and is good practice regardless.\n\n## Not (yet) supported\n\n- Plain CSS Modules (`*.module.css`) — see [`check-unused-css`](https://github.com/malinindev/check-unused-css) for that.\n- `styled-components` / `emotion`'s `styled` tagged templates.\n- React Native `StyleSheet.create` / `eslint-plugin-react-native`'s `no-unused-styles` territory.\n- Tailwind utility classes — Tailwind's own JIT compiler already purges genuinely unused utility classes at build time, so static \"unused class\" detection isn't meaningful there. Custom `@layer components` classes are a different, still-unhandled case.\n\nThese may become separate strategies/tools later; PRs welcome.\n\n## Install\n\n```bash\nnpm install --save-dev dead-styles\n```\n\n## Usage\n\n```bash\nnpx dead-styles scan --tsconfig ./tsconfig.json\n```\n\n### Options\n\n| Flag | Description | Default |\n| --- | --- | --- |\n| `--tsconfig <path>` | Path to `tsconfig.json` (required) | — |\n| `--sass <path>` | Path to a global Sass (indented syntax) file to also scan for unused classes (repeatable) | — |\n| `--scss <path>` | Path to a global SCSS (brace syntax) file to also scan for unused classes (repeatable) | — |\n| `--css <path>` | Path to a global plain CSS file to also scan for unused classes (repeatable) | — |\n| `--format <format>` | `text`, `markdown`, or `json` | `text` |\n| `--out <path>` | Write output to a file instead of stdout | — |\n| `--fail-on <mode>` | `dead-styles` (exit 1 if any found) or `never` | `dead-styles` |\n\n### Example\n\n```bash\nnpx dead-styles scan --tsconfig ./tsconfig.json --format markdown\n```\n\n```md\n# dead-styles report\n\nAnalyzed 6 style hooks (2 fully verified, 3 skipped).\n\nFound dead classes in 3 style hooks:\n\n### `useCardStyles` — src/Card.styles.ts:3\n\nCalled from 2 sites.\n\n- `unusedLabel` (line 7)\n...\n```\n\n## How it decides a class is \"used\"\n\nFor each style hook (`useStyles`, or whatever you named it):\n\n1. Collect the top-level keys of the object passed to `makeStyles(...)` / `tss.create(...)` — these are the candidate class names.\n2. Find every place the hook is *called* anywhere in the project via TypeScript's own symbol resolution (works across `paths` aliases in a monorepo).\n3. At each call site, figure out what the returned `classes` got bound to (`const classes = ...` or `const { classes } = ...`).\n4. Trace every reference to that local `classes` binding **within its own file** (a local variable can't be referenced outside its lexical scope — cross-file usage happens through additional call sites, not through this identifier).\n5. A class is \"used\" if it shows up as `classes.foo` or `classes['foo']` at **any** call site, anywhere in the project.\n6. Anything left over is reported as dead — unless step 3 or 4 hit something unverifiable (see above), in which case the whole hook is skipped instead.\n\n## License\n\nMIT\n","readmeFilename":"README.md"}