Detects unused drawables, strings, layouts, colors, and Flutter assets in a project, shows potential storage savings, and lets you clean them up with one click.
How it works
- Android detection: scans every
res/directory in the project, indexes file-based resources (drawables, mipmaps, layouts, menus, anims, raw, fonts) and value-based resources declared insideres/values/*.xml(strings, colors, dimens, styles). It then searches all.kt,.java, and.xmlsource forR.<type>.<name>and@<type>/<name>references. Anything with zero references is flagged as unused. - Flutter detection: parses
pubspec.yamlfor declaredassets:andfonts:entries (including whole-folder references), then searches all.dartsource for the exact asset path string. Anything unreferenced is flagged. - Confidence levels:
high(file-based resource, zero references anywhere),medium(value-type resource — could theoretically be referenced indirectly via a style/theme chain we don't fully resolve),low(the codebase uses dynamic construction likegetIdentifier()or Dart string interpolation near a matching path, so we can't be statically certain). Low-confidence items are never default-checked.
Setup
cd vscode-extension
npm install
npm run compile
Running it in the Extension Development Host (for testing without publishing)
- Open the
vscode-extensionfolder in VS Code. - Press
F5(or Run → Start Debugging). This launches a second VS Code window ("Extension Development Host") with the extension loaded. - In that new window, open any Android or Flutter project folder.
- Run the command "Resource Cleaner: Scan Project" from the Command Palette
(
Cmd/Ctrl+Shift+P), or right-click a folder in the Explorer. - Click Scan Project in the panel, review the grouped checklist, then click Clean Selected.
Packaging as a real, installable .vsix
npm install -g @vscode/vsce
vsce package
This produces a resource-cleaner-0.1.0.vsix file. Install it in any VS Code (or
Android Studio, if you later build the IntelliJ port — see below) via:
code --install-extension resource-cleaner-0.1.0.vsix
or through the Extensions panel's "Install from VSIX…" option.
Safety design choices worth knowing about
- File-based resources (drawables, layouts, Flutter assets) are deleted via
vscode.workspace.fs.deletewithuseTrash: true— they go to your OS trash/recycle bin, not a permanent unlink, so they're recoverable if something was a false positive. - Value-type resources (a
<string>entry insidestrings.xml, for example) can't be "trashed" individually since they're one node inside a shared file. Removing them means parsing the XML, dropping the matching node, and rewriting the file. This is not trash-recoverable the same way — the confirmation dialog says so explicitly, and recommends having a clean git working tree before cleaning these. - Low-confidence items (dynamic lookups, string-interpolated paths) are listed but unchecked by default. You have to deliberately opt in to deleting those.
Project structure
vscode-extension/
├── src/
│ ├── reportSchema.ts # Shared types for the unused-resource report
│ ├── fsUtils.ts # Directory walking, byte formatting, etc.
│ ├── androidDetector.ts # Android res/ scanning + reference search
│ ├── flutterDetector.ts # pubspec.yaml asset scanning + reference search
│ ├── scanner.ts # Orchestrates both detectors into one grouped report
│ ├── cleaner.ts # Performs the actual delete / XML rewrite
│ ├── panel.ts # Webview panel controller (extension host side)
│ └── extension.ts # Command registration / activation
└── media/
├── main.js # Webview UI logic (runs inside the webview, not Node)
├── main.css
└── icon.svg
Known limitations (be upfront with users about these)
- Dynamic resource construction (
getIdentifier()in Android, string interpolation in Dart) can't be perfectly resolved statically — those cases are flagged low-confidence rather than silently treated as either used or unused. - Resources referenced only from Gradle/build config, or from other modules not scanned (e.g. a separate library module outside the project root passed to the scanner), can produce false positives. Scan from the actual top-level project root.
- The XML rewrite for value-type resources reformats the whole file (via a parse + rebuild), so unrelated formatting/whitespace may shift even though content is preserved.
Next steps (not built yet)
- IntelliJ/Android Studio plugin sharing this same detection logic (ported to Kotlin) and reusing this same JSON report schema + webview HTML/CSS, per the architecture discussed.
- Optional:
flutter_genstrongly-typed asset detection,.arblocalization key usage detection, unused Dart class/widget detection.