qleaner
| Install | |
|---|---|
npm install qleaner |
|
| Latest Version: | 2.1.0 |
| License: | MIT |
| Last Updated: | Oct 2, 2026 |
| Links: | GitHub · npm |
Qleaner — unused code & asset cleaner for React / Next / Vue
Qleaner (v2.1.0) finds unused files, images, dependencies, and dead code in React, Next.js, Vue, Nuxt, TypeScript, and JavaScript projects so you can shrink bundles and keep the codebase clean.
What’s new in 2.1
- Optional AI briefs — Off by default.
--explainonscan,prune-logs, andsummaryonly (local Ollama or OpenAI-compatible cloud). Display-only; never deletes. - Health score —
qleaner summaryalways prints a 0–100 Good / Fair / Poor score. No model required. - GitHub Actions — Still deterministic (no
--explain, no Ollama). Opt in withsummary-extra-argsand a cloud API key.
What’s new in 2.0
- Zero-prompt
init— auto-detects framework, path aliases, and package manager. Optional[projectPath]and--forceto overwrite. Safe in CI:qleaner init <path> --force. - Single-path
image—qleaner image [projectPath](no-a/-ror separate assets/code roots). Path styles resolve automatically (imports,public/static,@/aliases). - Stage-only logging — stage timings instead of per-file progress bars; quieter, faster-feeling runs.
- TypeScript source — npm publishes compiled
dist/(prepublishOnlyrunstsc).
Breaking (migrate from 1.x):
- Replace
qleaner image <assetsDir> <codeRoot>(and-a/-r) withqleaner image [projectPath]. - Action input is
image-project-path(not separate asset/code path inputs). initis non-interactive; use--forceto overwrite an existing config.
Speed: Scans report stage timings and skip per-file progress bars, so large trees stay readable in CI and feel snappier locally. Smart cache (unused-check-cache.json) still speeds incremental runs.
Features
- Find Unused Code Files - Identify files that aren't imported or used anywhere (including re-export–aware checks so barrel files are not false positives when their exports are used)
- Find Unused Images - Detect image assets that are never referenced in your code
- Unused Dependencies - Discover npm/yarn/pnpm packages that are installed but not used; optionally uninstall them in one step
- Dead Image Links - Find image references in code that point to non-existent files
- Unused Exports - Find exported symbols nothing imports; optional
--fixto remove them, or--interactiveto select which exports to remove - Vue & Nuxt - Scan
.vuesingle-file components (@vue/compiler-sfc); Vue/Nuxt detection duringqleaner initsetspages/layoutsexclusions and.vueglobs - Prune Unused Code - Remove unused variables, functions, and classes (with dry-run);
-r/--reportprints a file, line, name, and kind table;--interactivelets you select which symbols to remove - Prune Console Logs - Strip
consoledebug calls (log,dir,dirxml,table,debug,info,trace). With-d/--dry-run, reports high / medium / low counts; per-tier hit tables (file, line, preview) print when the dry-run payload includesfoundByRiskand you pass--list-risk-categories(seecontrollers/list.ts→runSurgicalPass).-i/--list-risk-categories-infoprints the risk category index (paths toutils/consoleLogHighRiskPatterns.tsandutils/consoleLogMediumRiskPatterns.ts) and returns without scanning.--list-risk-categoriesalone does not skip the scan—use-dfor a dry run or-ifor docs only.--interactivesuggests hits (low-risk pre-checked) and removes only the selected calls. - Duplicate Detection - Find and clean duplicate functions and classes;
-r/--reportprints a detail table;--interactiveremoves only selected duplicates - Tidy - Run the main cleanup pipeline (quiet graph rebuild, logs, unused code, duplicates, unused exports) in one command; optional
[pathToScan](default.) and--auto-fix/-u.-r/--reportprints per-step dry-run tables for all four steps (console log tiers, unused code, duplicates, exports).--interactiveprompts after each step so you apply only selected items (wins over-u).--list-risk-categorieslimits extra console-log tier tables to that step only;-iprints the console-log risk index (pipeline continues). - Undo - Restore files moved during cleanup from
.trash(code or images) - Project Summary - Get comprehensive statistics about your codebase
- File Size Analysis - Identify the largest files and potential optimization targets
- Dependency Analysis - See which files have heavy dependencies and hotspots
- Smart Caching - Fast incremental scans with intelligent cache invalidation (
unused-check-cache.json, includingparentGraph.fixesfingerprints for surgical passes when present) - Dry-Run Mode - Where supported,
-d/--dry-runmatches the CLI: show what would be deleted without actually deleting (skips prompt) - Interactive Deletion - Choose unused files to delete or move to
.trash, or usescan --auto-fix. Surgical commands (prune,duplicates,prune-logs,exports,tidy) accept--interactiveto suggest in-file removals and apply only the selected items - Enhanced File Finding - Advanced path resolution using jsconfig/tsconfig for accurate dependency tracking in large codebases with complex import structures
- Advanced Image Detection - Sophisticated AST parsing extracts image references from imports, requires, JSX, CSS, styled-components, template literals, arrays, and more
- Optional AI briefs - Off by default. On
scan,prune-logs, andsummaryonly,--explainprints a display-only brief after existing tables (never deletes). Default provider is local Ollama;ai.provider: "openai"uses any OpenAI-compatible cloud endpoint.scanlabels unused paths as asset-code vs code.--domainre-ranksprune-logshits.summaryalways prints a health score without AI;--explainadds a narrative. GitHub Actions do not run--explainunless you opt in. See Optional AI under Commands.
Installation
Global Installation
npm install -g qleaner
Use with npx (No Installation)
npx qleaner <command>
Local Development Dependency
yarn add qleaner --dev
# or
npm install qleaner --save-dev
GitHub Actions
Qleaner ships a composite GitHub Action at the repo root: action.yml (“Qleaner Health Guardian”). It installs the published qleaner package from npm and runs the global qleaner CLI — not yarn start from a cloned dev checkout.
Publish to the GitHub Marketplace by tagging a release (e.g. v2.1.0) that includes action.yml. Pin the same version on npm (qleaner-version input).
AI is optional and off in CI. The action does not install Ollama, does not pass --explain, and does not need an API key. qleaner summary still prints a deterministic health score. Opt in only if you want a cloud narrative (see Optional AI in CI below).
What the action does
- Sets up Node.js (default 20).
- Runs
npm install -g qleaner@<version>(default 2.1.0). - Restores
unused-check-cache.jsonfrom the Actions cache (key usesqleaner.config.jsonandpackage-lock.json). - Runs read-only captures in the job workspace:
qleaner tidy <scan-path> …→tidy_report.txt(quiet by default; passtidy-extra-args: "-r"for per-step detail tables)qleaner image <projectPath> …→image_report.txt(skipped ifimage-project-pathis empty)qleaner summary→health_summary.txt(health score; no--explainunless you setsummary-extra-args)
No --auto-fix / -u: CI is dry-run only. The job succeeds when every command exits 0.
Use in your repository
Prerequisites
- Commit
qleaner.config.json(runqleaner initlocally, or in CI:qleaner init <path> --force). - Add
unused-check-cache.jsonand.trash/to.gitignore(initcan do this). - Set
with:paths to match your app layout (not this repo’s Infisical sample tree). - Pin the Action ref to a tag on this repo (e.g.
uses: trevismurithi/react-cleaner@v2.1.0). Creating a GitHub Release publishes npm via.github/workflows/release.ymlwhenNPM_TOKENis set.
Full workflow (status check + PR health report comment):
Create .github/workflows/qleaner-health.yml in your project and adjust paths. The Action runs Qleaner; the following steps build pr_report.md from the npm-bundled script and post (or update) one sticky PR comment.
name: Qleaner Health Guardian
on:
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
workflow_dispatch:
jobs:
hygiene-check:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Run Qleaner
uses: trevismurithi/react-cleaner@v2.1.0
with:
qleaner-version: "2.1.0"
scan-path: src
image-project-path: src
# Optional: per-step detail tables (off by default)
# tidy-extra-args: "-r"
image-extra-args: "-d -T 0.1"
# AI stays off. Health score does not need Ollama or an API key.
# summary-extra-args: "--explain"
- name: Build PR health report
if: github.event_name == 'pull_request'
env:
NO_COLOR: "1"
run: |
REPORT_SCRIPT="$(npm root -g)/qleaner/dist/.github/scripts/pr-report.js"
node "$REPORT_SCRIPT" \
qleaner.stats.json health_summary.txt tidy_report.txt image_report.txt \
> pr_report.md
- name: Post PR Health Report
if: always() && github.event_name == 'pull_request'
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
if (!fs.existsSync('pr_report.md')) return;
const body = fs.readFileSync('pr_report.md', 'utf8');
const marker = '<!-- qleaner-report -->';
const { data: comments } = await github.rest.issues.listComments({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
per_page: 100,
});
const existing = comments.find(c => c.body?.startsWith(marker));
if (existing) {
await github.rest.issues.updateComment({
comment_id: existing.id,
owner: context.repo.owner,
repo: context.repo.repo,
body,
});
} else {
await github.rest.issues.createComment({
issue_number: context.issue.number,
owner: context.repo.owner,
repo: context.repo.repo,
body,
});
}
uses: …@v2.1.0must match an existing tag ontrevismurithi/react-cleaner(e.g.v2.1.0— the ref is exact).- No image scan: set
image-project-pathto""(or omit and rely on the default). - Quieter tidy: leave
tidy-extra-argsunset; settidy-extra-args: "-r"only when you want per-step dry-run detail tables. - No AI by default: leave
summary-extra-argsunset. Do not install Ollama on the runner. - Report only on PRs:
workflow_dispatchruns Qleaner but skips the comment steps (if: github.event_name == 'pull_request'). - You do not copy
.github/scripts/pr-report.tsinto your repo; it ships compiled asdist/.github/scripts/pr-report.jsin the publishedqleanernpm package. The Action step installs that package globally first.
Check-only workflow (no PR comment — omit the last two steps and pull-requests: write).
Action inputs (all optional except you should set paths for your project):
| Input | Default | Purpose |
|---|---|---|
qleaner-version |
2.1.0 |
npm version of qleaner to install |
node-version |
20 |
Node.js for setup-node |
scan-path |
. |
First argument to qleaner tidy |
image-project-path |
(empty) | Project path for qleaner image (skipped when empty) |
tidy-extra-args |
(empty) | Optional tidy flags; pass -r for per-step detail tables |
image-extra-args |
-d -T 0.1 |
Extra image flags (dry-run + size threshold) |
skip-image |
false |
Set true to skip image scan |
skip-summary |
false |
Set true to skip summary |
summary-extra-args |
(empty) | Extra summary flags. Leave empty for the health score only. Pass --explain only with a cloud provider and secret key |
restore-cache |
true |
Restore unused-check-cache.json before the run |
Outputs: tidy-report-file, image-report-file, summary-file (filenames in the workspace).
The composite Action does not post to GitHub by itself — use the full workflow above for the PR comment.
Optional AI in CI
GitHub-hosted runners do not include Ollama. Leave AI off unless you want a cloud narrative on the summary.
- Store a key as a repo secret (e.g.
QLEANER_AI_API_KEY). Never commit keys toqleaner.config.json. - Pass
summary-extra-args: "--explain"and set provider env on the Action step:
- name: Run Qleaner
uses: trevismurithi/react-cleaner@v2.1.0
with:
qleaner-version: "2.1.0"
scan-path: src
image-project-path: src
summary-extra-args: "--explain"
env:
QLEANER_AI_PROVIDER: openai
QLEANER_AI_ENDPOINT: https://api.openai.com/v1
QLEANER_AI_MODEL: gpt-4.1-mini
QLEANER_AI_API_KEY: ${{ secrets.QLEANER_AI_API_KEY }}
Without a key, --explain prints a skip line and the rest of the job still succeeds. This repo’s dogfood workflow (.github/workflows/qleaner-health.yml) does not enable AI.
This repository (dogfooding)
.github/workflows/qleaner-health.yml uses uses: ./ to test the local action.yml while still installing qleaner@2.1.0 from npm (available after the release is published). It does not set summary-extra-args or AI secrets. It uses npx --yes tsx .github/scripts/pr-report.ts from the checked-out repo instead of $(npm root -g)/qleaner/... (same script, easier for dogfooding). Paths under with: target the bundled Infisical sample tree (src/infisical-main/frontend, etc.) — copy the full workflow above for other repos, not those paths.
Branch protection: After the workflow runs on a PR, you can require status check hygiene-check (job id). If you see “Expected — Waiting for status to be reported”, the workflow did not run (workflow missing on the base branch, Actions disabled, or fork PR awaiting approval).
Publishing (maintainers)
- Add repo secret
NPM_TOKEN(npm token with publish rights) in GitHub → Settings → Secrets. - Bump
"version"inpackage.json(and lockfile) to match the release. - Merge to the default branch, then create a GitHub Release with tag
vX.Y.Zmatching that version (e.g.v2.1.0for2.1.0). .github/workflows/release.ymlruns onrelease: published:npm ci→npm publish(prepublishOnlybuildsdist/). Do not commitdist/.
Monorepos
Run Qleaner per package, not from the repo root unless that root is itself an app:
cd apps/web
qleaner init . # or: qleaner init apps/web from repo root
qleaner scan . --dry-run
qleaner image . --dry-run
Each package gets its own qleaner.config.json and unused-check-cache.json. In GitHub Actions, set scan-path and image-project-path to that package (e.g. apps/web), or use a matrix job per app later. There is no init --workspaces yet.
Quick Start
1. Initialize Configuration
IMPORTANT: Proper configuration is critical for Qleaner to accurately find and resolve files in your project, especially for large codebases.
Set up Qleaner for your project (non-interactive):
qleaner init
# Nested app / monorepo package:
qleaner init apps/web
# Overwrite existing config:
qleaner init . --force
init auto-detects:
- Path to scan — optional
[projectPath](default cwd); written intoqleaner.config.json - Package manager — from lockfiles (npm / yarn / pnpm)
- Framework — React, Next.js, Vue, Nuxt, or vanilla (entry-point patterns and Vue/Nuxt directory exclusions)
- Path aliases — from
tsconfig/jsconfigwhen present (including discoveredcodeAlias)
Review or edit qleaner.config.json if detection misses an alias or entry file. Manually add paths when you have no tsconfig/jsconfig (see Configuration below).
This creates qleaner.config.json and updates .gitignore: a # Qleaner section with unused-check-cache.json and .trash/ when those patterns are not already ignored.
2. Scan for Unused Code Files
Scan for unused files. Pass a directory as the first argument ([pathToScan], default .), or rely on the path field in qleaner.config.json when you omit it.
# Dry run (recommended first time) — explicit directory
qleaner scan src --dry-run
# Current directory (same as qleaner scan . --dry-run)
qleaner scan --dry-run
# Actual scan (will prompt for deletion unless --auto-fix)
qleaner scan src
3. Scan for Unused Images
Find images that aren't referenced in your project (inventory + code refs under one path):
# Scan the current project (cwd)
qleaner image --dry-run
# Scan a nested app (same path style as init/scan)
qleaner image src/infisical-main/frontend --dry-run -H
Breaking change: older qleaner image <assetsDir> <codeRoot> (and -a/-r) is replaced by a single optional [projectPath]. Path styles are resolved automatically.
Commands
The CLI is implemented in bin/cli.ts and published as dist/bin/cli.js. Program name qleaner, tagline A tool to clean up your React code, and qleaner --version match that file (version is read from package.json). Run qleaner --help for the same command and option list Commander registers there.
Optional AI
AI is off by default. Static analysis and the summary health score do not need Ollama or an API key. After tables, an opt-in model can print a short brief. It does not write files or change --auto-fix / --interactive / --uninstall. GitHub Actions do not run --explain unless you opt in (see GitHub Actions above).
AI flags exist only on scan, prune-logs, and summary. Default provider is local Ollama. Set ai.provider to "openai" for OpenAI, Vercel AI Gateway, Groq, or any OpenAI-compatible /v1/chat/completions endpoint.
Ollama (default):
ollama pull qwen2.5-coder:7b
ollama serve
"ai": {
"enabled": false,
"provider": "ollama",
"endpoint": "http://127.0.0.1:11434",
"model": "qwen2.5-coder:7b"
}
OpenAI-compatible (cloud): never put API keys in qleaner.config.json.
"ai": {
"enabled": true,
"provider": "openai",
"endpoint": "https://api.openai.com/v1",
"model": "gpt-4.1-mini"
}
export QLEANER_AI_API_KEY=sk-... # or OPENAI_API_KEY
qleaner summary --explain
Vercel AI Gateway: provider: "openai" and endpoint set to the gateway base URL (the client appends /chat/completions). A 7B behind an OpenAI-compatible proxy can set "profile": "local" to keep small scan batches.
Cloud requests send short unused paths, log previews, and summary totals — not file contents. Those paths leave your machine.
Flags (those three commands only):
| Flag | Meaning |
|---|---|
--explain |
Print an AI brief for this run |
--domain <name> |
Product domain (e.g. healthcare, fintech). Required to re-rank prune-logs hits |
--ask <question> |
Extra question constrained to this command’s findings |
Also runs when qleaner.config.json has "ai": { "enabled": true } (init writes false). Env: QLEANER_AI_PROVIDER, QLEANER_AI_ENDPOINT, QLEANER_AI_MODEL, QLEANER_AI_API_KEY / OPENAI_API_KEY.
scan --explain— sends the full unused-file list as short paths only (no source, no size ranking). The model labels each pathassetorcodewith a 0–100 confidence score. Local batches ~40 ids; cloud ~150.prune-logs --explain --domain <name>— re-ranks listed console hits for that industry. No domain → heuristic tables only. Custom regexes live inconsoleLogPatterns.summary— always prints a deterministic health score (0–100).--explainadds a short narrative from the same totals.
Qleaner waits until the model finishes (Ctrl+C to stop). Object-shaped warnings from the model are printed as text. Missing cloud keys, HTTP 401/403, or an unreachable endpoint skip the brief and keep the tables.
Skipped on scan --quiet (including tidy’s inner graph rebuild) and prune-logs -i (docs only). CI does not pass --explain unless you opt in (see GitHub Actions).
qleaner scan src --dry-run --explain
qleaner prune-logs src --dry-run --list-risk-categories --explain --domain fintech
qleaner summary --explain
qleaner init
Non-interactive setup: detects framework, package manager, path aliases, and entry points, then writes qleaner.config.json. Safe for CI.
Arguments:
[projectPath]- Project root to initialize (default: cwd)
Options:
-f, --force- Overwrite an existingqleaner.config.json
After writing the config, init updates .gitignore: it adds unused-check-cache.json and .trash/ under a # Qleaner heading only when those entries are not already present.
What gets detected:
- Path —
[projectPath]or cwd - Package manager — npm / yarn / pnpm from lockfiles
- Framework — React, Next.js, Vue, Nuxt, or vanilla (entry-point patterns; Vue/Nuxt get
layouts/pagesinexcludeDirPrintand.vueglobs) - Path aliases — from tsconfig/jsconfig when present
Configuration still matters: Review paths, codeAlias, and excludeFilePrint after init. Incorrect aliases can cause false positives. Without tsconfig/jsconfig, set paths manually (see Configuration): "paths": { "@/*": ["./src/*"] }.
Examples:
qleaner init
qleaner init apps/web
qleaner init . --force
cat qleaner.config.json
qleaner scan . --dry-run
Note: Without --force, init exits if qleaner.config.json already exists.
qleaner scan
Scan a directory for unused code files. Merge order: values from qleaner.config.json first, then CLI flags (CLI wins).
Arguments:
[pathToScan]- Directory to scan (default.; combined with configpathand exclusions as implemented incommand.ts)
Options:
-e, --exclude-dir <dir...>- Exclude directories from scan (e.g.,-e node_modules dist)-f, --exclude-file <file...>- Exclude specific files by name (e.g.,-f config.js)-F, --exclude-file-print <files...>- Scan but don't report as unused (for entry points)-x, --exclude-extensions <extensions...>- Exclude file extensions (e.g.,-x test.tsx test.ts)-t, --table- Display results in a formatted table-d, --dry-run- Show what would be deleted without actually deleting (skips prompt)-u, --auto-fix- Skip the interactive prompt and move all reported unused files to.trash(only when not using--dry-run; same flag name asdepis not shared: onscanthis is auto-fix, ondep-uis--uninstall)-q, --quiet- Rebuild the graph cache and print nothing (no unused-file table, totals, cache blurb, or delete prompt). Used byexportsandtidywhen they only need a fresh scan before other checks.-C, --clear-cache- Clear cache before scanning (useful after major changes)--explain/--domain/--ask- optional AI classification of unused paths (see Optional AI). Skipped with--quiet.
Examples:
# Basic scan (will prompt for deletion if unused files found)
qleaner scan src
# Dry run with table output (recommended first time)
qleaner scan src --dry-run --table
# Classify unused paths as asset-code vs code (optional --explain)
qleaner scan src --dry-run --explain
# Move every reported unused file to .trash without prompting (use after a trusted dry-run)
qleaner scan src --auto-fix
# Exclude test files and multiple directories
qleaner scan src -x test.tsx test.ts test.js test.jsx -e node_modules dist build
# Exclude specific files from being reported as unused (entry points)
qleaner scan src -F index.tsx main.tsx app.tsx
# Clear cache and perform fresh scan
qleaner scan src --clear-cache
# Rebuild cache only (no unused-file listing or prompt)
qleaner scan src --quiet
# Comprehensive scan with multiple exclusions
qleaner scan src --exclude-dir node_modules dist build --exclude-extensions test.tsx test.ts --table
qleaner image [projectPath]
Scan for unused images under a single project directory. Inventories image files (png, jpg, jpeg, svg, gif, webp, ico, avif) and matches them against references in code/CSS. Resolves imports, relative paths, public//static/ URLs, and @//~/ aliases automatically.
Arguments:
[projectPath]- Project root to scan (default: cwd). Same path style asqleaner init/qleaner scan.
Options:
-u, --auto-prune- Move all reported unused images to.trashwithout a prompt (only when not using--dry-run)-T, --size-threshold-mb <megabytes>- Highlight unused images larger than this size in the report (table column or list suffix; display only)-e, --exclude-dir-assets <dir...>- Exclude directories from image file scan (can specify multiple)-F, --exclude-file-assets <file...>- Exclude specific image files by name pattern-E, --exclude-dir-code <dir...>- Exclude directories when scanning code for image references (e.g.,-E node_modules dist)-S, --exclude-file-code <file...>- Exclude specific files when scanning code for image references-t, --table- Display results in a formatted table with columns: Unused Images, In Code, Exists, Size-C, --clear-cache- Clear cache before scanning (recommended after major code changes)-H, --hide-not-found-images- Hide images referenced in code but not found on disk (dead links)-d, --dry-run- Show what would be deleted without actually deleting; does not move files and does not run--auto-prune
Breaking change: the old two-argument form qleaner image <assetsDir> <codeRoot> and the -a/-r flags are removed. Use one project path instead.
Examples:
# Scan cwd
qleaner image --dry-run
# Nested app
qleaner image src/infisical-main/frontend --dry-run
# Dry run with table format
qleaner image . --dry-run --table
# Hide dead image links and use table format
qleaner image . -H -t
# Exclude directories from code scan
qleaner image . -E node_modules dist test
# Exclude specific directories from asset scan
qleaner image . -e icons fonts
# Clear cache and rescan
qleaner image . --clear-cache
# Comprehensive scan with common options
qleaner image . --exclude-dir-code node_modules dist --hide-not-found-images --table --dry-run
# Highlight unused images larger than 2 MB (report only)
qleaner image . --dry-run -T 2 --table
# Move all unused images to .trash without prompting (after a trusted dry-run)
qleaner image . --auto-prune
Supported Image Reference Patterns:
Qleaner automatically detects images referenced through various patterns:
- ES6 Imports:
import logo from './logo.png' - CommonJS Require:
require('./logo.png')orrequire('./logo.png') - Dynamic Imports:
import('./logo.png')orimport('./assets/${name}.png') - JSX Attributes:
<img src="https://raw.githubusercontent.com/trevismurithi/react-cleaner/HEAD/logo.png" />or<img src={imagePath} /> - React Style Props:
style={{ backgroundImage: "url('./logo.png')" }} - CSS Files:
url('./logo.png')orurl('/images/logo.png') - Styled-Components:
css`background-image: url('./logo.png')`orstyled.div`background: url('./bg.png')` - Arrays:
const images = ['./logo.png', './icon.png'] - Template Literals:
`./logo-${name}.png`or`/images/${type}.png` - String Literals: Any string containing an image path pattern
qleaner list <dependency>
List files that import modules whose resolved paths match your query. The matcher splits <dependency> on / and finds graph nodes whose file path contains every segment; it then prints the union of those nodes’ importedBy files (direct importers). Works well for package names (lodash), nested paths (react-router/dom), or path fragments that appear in resolved file paths.
Arguments:
<dependency>- Dependency or path pattern (e.g.,react-router,lodash,utils/helpers)
Options:
-t, --table- Display results in a table format
Examples:
# List files using react-router
qleaner list react-router
# List files touching a path segment
qleaner list utils/helpers
# List files using lodash with table format
qleaner list lodash --table
# Find files using a specific package
qleaner list axios
Note: Requires unused-check-cache.json. Run qleaner scan (with -p or config path) first.
qleaner dep
List unused production dependencies from package.json by comparing package names to the dependency graph (packages with no importers in the graph are listed).
Options:
-d, --directory <directory>- Directory containingpackage.jsonto read (defaults to current directory)-t, --table- Display results in a table format-u, --uninstall- After listing, uninstall each unused dependency using your configured package manager (ondeponly;scanuses-ufor--auto-fix, not uninstall.)
Examples:
# Find unused dependencies in current directory
qleaner dep
# Check dependencies in a specific package/monorepo directory
qleaner dep -d ./packages/my-package
# Display results in table format
qleaner dep --table
# Uninstall unused production dependencies (use after dry review)
qleaner dep --uninstall
Note: Requires unused-check-cache.json. Run qleaner scan first. Only analyzes dependencies, not devDependencies.
qleaner exports
List unused exports (symbols exported from a file that nothing imports, following the same graph as the scan). Use --fix to apply edits that remove those exports.
Arguments:
[pathToScan]- Project directory to analyze (default.)
Options:
-r, --fresh-scan- Clear graph-related state before analyzing (via a quietscanwithclearCacheas implemented inunusedExports)-f, --fix- Fix (remove) the unused exports-d, --dry-run- Only print how many unused exports were found (no table unless--report)--report- Print a table of unreferenced exports (export name and file); works with or without--dry-run(-ron this command is--fresh-scan)--interactive- Print the unused-export table, then remove only the selected exports (does not require--fix;--dry-runwins if both are set). Graph rebuild during this command is quiet.
Examples:
qleaner exports . --dry-run
qleaner exports . --dry-run --report
qleaner exports . --fix --report
qleaner exports . --interactive
Note: Requires unused-check-cache.json from qleaner scan over the same project tree you care about. With --fix, files are edited in place—use version control.
qleaner prune
Remove unused internal declarations (unused variables, functions, classes, etc.) via static analysis. Always try --dry-run first.
Arguments:
[pathToScan]- Directory whose files are globbed from config (default.)
Options:
-d, --dry-run- Show what would be deleted without actually deleting (skips prompt)-r, --report- Print a table of unused symbols (file, line, name, kind); works with or without--dry-run--interactive- Suggest unused symbols and remove only the selected items.--dry-runwins if both are set. Default with no flags is still apply-all.
Examples:
qleaner prune . --dry-run -r
qleaner prune . -r
qleaner prune . --interactive
qleaner prune .
Note: Operates on files discovered from qleaner.config.json (path and exclusions). Large refactors may update qleaner.stats.json with change statistics.
qleaner prune-logs
Remove console debug calls: log, dir, dirxml, table, debug, info, trace (standalone expression statements only).
Note:
qleaner prune-logs --helpmay describe flags differently; runtime behavior matchescontrollers/list.ts(pruneConsoleLogs,runSurgicalPass) as summarized below.
Arguments:
[pathToScan]- Directory to scan (default.); globs come fromqleaner.config.jsonlike other prune commands
Options:
-d, --dry-run- Report counts only (no edits). Prints totals asN (high-risk sensitive: H, medium: M, low: L). With--list-risk-categoriesalso set, prints per-tier hit tables (file, line, preview) when the dry-run result includesfoundByRisk(capped per tier incontrollers/list.ts).-i/--list-risk-categories-info- Print the risk-tier category index (pattern file paths and section titles), then return without scanning or editing.--list-risk-categories- Does not skip the scan by itself. Use with-dto dry-run and optionally show hit tables as above, or use-ifor the index-only path.--interactive- Suggest console-log removals (with per-tier tables) and apply only the selected items. Low-risk hits are pre-checked.--dry-runwins if both are set. Default with no flags is still apply-all.--explain/--domain/--ask- optional AI brief.--domainis required to re-rank listed calls (see Optional AI). No AI on-i.
Heuristics (not a security scanner): Builtin patterns live in utils/consoleLogHighRiskPatterns.ts and utils/consoleLogMediumRiskPatterns.ts. Add project regexes in consoleLogPatterns (high, medium, ignore). Classification order is ignore → custom high → builtin high → custom medium → builtin medium → low. ignore keeps a call removable but not sensitive.
Examples:
# Risk index only (no scan, no edits) — preferred for CI / docs
qleaner prune-logs -i
# Dry-run counts (hit tables only if you also pass --list-risk-categories)
qleaner prune-logs src --dry-run
qleaner prune-logs src --dry-run --list-risk-categories
# Domain-aware AI re-rank of listed logs (optional --explain)
qleaner prune-logs src --dry-run --list-risk-categories --explain --domain healthcare
# Apply removals (not a dry run)
qleaner prune-logs src
# Suggest removals and apply only the selected calls
qleaner prune-logs src --interactive
qleaner duplicates
Detect and clean duplicate code patterns across files under the configured path.
Arguments:
[pathToScan]- Directory to scan (default.)
Options:
-d, --dry-run- Show what would be deleted without actually deleting (skips prompt)-r, --report- Print a table of duplicate functions and classes (file, line, name, kind); works with or without--dry-run--interactive- Suggest duplicate removals and apply only the selected items.--dry-runwins if both are set. Default with no flags is still apply-all.
Examples:
qleaner duplicates . --dry-run -r
qleaner duplicates . -r
qleaner duplicates . --interactive
qleaner duplicates .
qleaner undo <type>
Restore files from .trash after a cleanup that moved files instead of deleting them permanently.
Arguments:
<type>-codeorimagesdepending on which kind of deletion you want to revert
Examples:
qleaner undo code
qleaner undo images
qleaner tidy
Tidy up the project — starts with a quiet scan to refresh the graph. Each step dry-runs first, then applies edits only if --auto-fix / -u is set and the dry-run reported work. --interactive prompts per step instead of applying all.
Arguments:
[pathToScan]- Project root or source directory for globs (default.)
Options:
-u, --auto-fix- After a successful dry-run count for a step, run the real pass (console logs, internal unused code, duplicates, unused exports with--fix). Finishes with a dry-runscan(unused files listed, not moved).-r/--report- During each step’s dry-run, print detail tables: console log tiers, unused code, duplicates, and exports (also enables console-log tier tables; same as passing--list-risk-categoriesfor that step).--list-risk-categories- Console-log step only: per-tier hit tables whenfoundByRiskis present (also enabled when-ris set).-i/--list-risk-categories-info- Print the console-log risk category index; tidy continues with remaining steps.--interactive- After each step’s suggestions, select which items to remove (wins over-u). Finishes with a normal unused-filescanprompt.
Sequence (see controllers/list.ts):
- Quiet scan — rebuild graph cache with no unused-file listing
- Console logs — dry-run (counts + tier tables with
-ror--list-risk-categories) → apply all if--auto-fix, or selected items if--interactive - Unused internal code —
prunedry-run (detail table with-r) → apply if needed - Duplicates — dry-run (detail table with
-r) → apply if needed - Unused exports — dry-run (detail table with
-r) → apply with fix if needed (exportsrebuilds the graph quietly) - Unused files scan — after any mutation: dry-run
scanfor--auto-fix(reports unused files; does not move them); with--interactive, print unused files and offeraskDeleteFiles
Prefer exercising prune, prune-logs, duplicates, exports, and scan manually with --dry-run and -r until you trust the behavior.
Examples:
# Dry-run each step; no edits
qleaner tidy
# Per-step detail tables (CI default: tidy-extra-args "-r")
qleaner tidy -r
# Risk index for console logs (pipeline continues)
qleaner tidy -i
# Select items to remove at each step
qleaner tidy . --interactive
# Apply safe code cleanups when issues are found
qleaner tidy . --auto-fix
qleaner summary
Get comprehensive project statistics and insights. (qleaner summary --help uses the short description List all the imports in the project; the sections below describe the full behavior.)
Options:
-l, --largest-files- Show top 10 largest code and image files-d, --dependencies- Show dependency analysis and hotspots--explain/--domain/--ask- optional AI health narrative (see Optional AI)
Note: When no options are provided, shows a general project summary with totals and a health score (0–100, Good / Fair / Poor). The score is deterministic and does not need AI.
Examples:
# Full project summary (health score, no AI)
qleaner summary
# Optional AI narrative (same totals; needs Ollama or a cloud key)
qleaner summary --explain
# Show largest files
qleaner summary --largest-files
# Show dependency analysis
qleaner summary --dependencies
Summary Output Breakdown:
General Summary (no flags):
- Total code files count
- Total image files count
- Total unused files count
- Total unused images count
- Total dead image links count
- Total files count
- Health score (0–100) with the two largest penalty drivers
Largest Files (-l or --largest-files):
- Top 10 largest code files (sorted by size in KB)
- Top 10 largest image files (sorted by size in MB)
- Total code size and total image size
- Code files exceeding 100 KB (warning list)
- Health score (same formula as the general summary)
Dependencies (-d or --dependencies):
- Top 10 files with heavy dependencies (most imports)
- Top 10 files with light dependencies (fewest imports)
- Top 10 file hotspots (most imported files - files that many other files import)
- Top 10 dependency hotspots (most used dependencies/packages)
- Top 10 dead image hotspots (dead image links referenced by many files)
- Top 10 alive image hotspots (images referenced by many files)
- Health score (same formula as the general summary)
Note: Requires a cache file. Run qleaner scan to generate code cache and/or qleaner image [projectPath] to generate image cache first.
Configuration
Qleaner can be configured via qleaner.config.json or CLI flags. For qleaner scan, CLI flags override values merged from the config file.
Configuration File Structure
{
"path": "src",
"framework": "react",
"codeAlias": "tsconfig.json",
"paths": {},
"packageManager": "yarn",
"excludeDir": ["node_modules", "dist", "build", ".next"],
"excludeFile": ["payload-types.ts"],
"excludeExtensions": [".test.tsx", ".test.ts"],
"excludeDirPrint": [],
"excludeFilePrint": ["index.js", "index.tsx", "main.js"],
"excludeDirAssets": [],
"excludeFileAssets": [],
"excludeDirCode": ["node_modules", "dist"],
"excludeFileCode": [],
"isRootFolderReferenced": true,
"alias": false,
"autoFix": false,
"autoPrune": false,
"sizeThresholdMb": null,
"domain": null,
"consoleLogPatterns": {
"high": [],
"medium": [],
"ignore": []
},
"ai": {
"enabled": false,
"provider": "ollama",
"endpoint": "http://127.0.0.1:11434",
"model": "qwen2.5-coder:7b",
"maxCandidates": 12
}
}
Configuration Options
| Option | Type | Description |
|---|---|---|
path |
string | Default directory for qleaner scan (when -p is omitted) and for commands that glob from config (exports, prune, prune-logs, duplicates, tidy). Often your app root or src. |
autoFix |
boolean | When true (and not overridden), qleaner scan without --dry-run moves all reported unused files to .trash via moveToTrash instead of opening the interactive delete prompt (same effect as --auto-fix / -u on the scan command). |
autoPrune |
boolean | When true, qleaner image without --dry-run moves all reported unused images to .trash without a prompt (same as --auto-prune / -u on the image command). |
sizeThresholdMb |
number | null | Optional default for highlighting large unused images in the image report (same semantics as --size-threshold-mb / -T). |
domain |
string | null | Optional product domain for AI ranking (e.g. healthcare). CLI --domain overrides. Required for prune-logs --explain. |
consoleLogPatterns |
object | Extra console-log regex strings: high, medium, ignore. Invalid or >200-character patterns are skipped. Classification: ignore → custom high → builtin high → custom medium → builtin medium → low. |
ai |
object | Optional AI for scan, prune-logs, and summary. enabled default false; --explain still opts in. provider: "ollama" (default) or "openai" (OpenAI-compatible). endpoint, model, maxCandidates, optional profile (local | cloud). Never store API keys here. Env: QLEANER_AI_PROVIDER, QLEANER_AI_ENDPOINT, QLEANER_AI_MODEL, QLEANER_AI_API_KEY / OPENAI_API_KEY. |
framework |
string | One of react, nextjs, or vue (use vue for Vue and Nuxt apps). Sets default excludeFilePrint and, for Vue, default excludeDirPrint (layouts, pages). |
codeAlias |
string | null | Critical! Config file to use for path alias resolution. Options: "tsconfig.json", "jsconfig.json", "tsconfig.app.json", "tsconfig.base.json", or null for manual configuration. Qleaner reads path aliases from this file to resolve imports (e.g., @/components, ~/utils). |
paths |
object | Manual path aliases (only used if codeAlias is null). Object mapping alias patterns to file paths. Example: { "@/*": ["./src/*"], "~/*": ["./src/*"] }. If codeAlias is set, this field is ignored and paths are read from the config file instead. |
packageManager |
string | Package manager used: npm, yarn, or pnpm |
excludeDir |
string[] | Directories to exclude from code scans |
excludeFile |
string[] | Files to exclude by name from code scans |
excludeExtensions |
string[] | File extensions to exclude (e.g., ["test.tsx"]) |
excludeDirPrint |
string[] | Path segments matched against file paths; matching files are excluded from the unused-files result (e.g. Vue defaults layouts, pages) |
excludeFilePrint |
string[] | Entry point files to scan but not report as unused |
excludeDirAssets |
string[] | Directories to exclude from image scans |
excludeFileAssets |
string[] | Image files to exclude by name |
excludeDirCode |
string[] | Directories to exclude when scanning code for image references |
excludeFileCode |
string[] | Files to exclude when scanning code for image references |
isRootFolderReferenced |
boolean | true if image paths are root-referenced (e.g., /images/logo.png) |
alias |
boolean | true if image paths use aliases (e.g., @/assets/images/logo.png) |
Important Configuration Notes:
-
codeAliasandpaths:- If
codeAliasis set (e.g.,"tsconfig.json"), Qleaner will read path aliases from that config file. Thepathsfield will be ignored. - If
codeAliasisnull, Qleaner will use thepathsfield for manual path alias configuration. - Getting this right is crucial for accurate file resolution in large codebases!
- If
-
isRootFolderReferencedandalias: These should not both betrueor both befalse. Set one totrueand the other tofalse.
Manual Path Configuration
If you don't use jsconfig.json or tsconfig.json, or need custom path resolution, you can manually configure paths in qleaner.config.json:
{
"codeAlias": null,
"paths": {
"@/*": ["./src/*"],
"~/*": ["./src/*"],
"components/*": ["./src/components/*"],
"utils/*": ["./src/utils/*"]
}
}
The paths object follows the same format as TypeScript's path mapping:
- Key: The alias pattern (e.g.,
"@/*"matches@/components,@/utils, etc.) - Value: Array of actual file paths to resolve to (relative to project root)
Example: If you have import Button from '@/components/Button' in your code, and your config has "@/*": ["./src/*"], Qleaner will resolve it to ./src/components/Button.tsx (or .ts, .jsx, .js).
Default Exclusions
Qleaner automatically excludes common build and generated directories:
node_modules,dist,build,.next,outcoverage,.turbo,.vite,.cache.vercel,.netlify,storybook-staticgenerated,prisma,graphql,supabase,drizzle,__generated__
Framework-Specific Entry Points
React:
index.js,index.jsx,index.ts,index.tsxmain.js,main.jsx,main.ts,main.tsx
Vue: Default excludeFilePrint may be empty after init; typical unused-file exclusions use excludeDirPrint (layouts, pages) so framework routes are not flagged.
Next.js:
page.tsx,page.jsx,route.ts,route.jsxlayout.tsx,layout.jsxmiddleware.ts,middleware.jserror.tsx,error.jsx,loading.tsx,loading.jsxnot-found.tsx,not-found.jsxglobal-error.tsx,global-error.jsx_app.tsx,_app.jsx,_document.tsx,_document.jsx_error.tsx,_error.jsx
Caching
Qleaner uses intelligent caching to speed up subsequent scans:
- File Hashing - Files are only re-analyzed if their content changed
- Incremental Updates - Only changed files are re-processed
- Cache Location -
unused-check-cache.jsonin your project root
Some edit-heavy commands (prune, prune-logs, duplicates, exports --fix) may append summary metrics to qleaner.stats.json in the project root.
When to Clear Cache:
- After major refactoring
- When dependencies change significantly
- If you get unexpected results
# Clear cache and rescan
qleaner scan src --clear-cache
File Deletion
When you run qleaner scan without --dry-run:
- Default — Qleaner prompts you to select unused files and whether to move them to
.trashor delete permanently (askDeleteFiles). --auto-fix/-u(orautoFix: truein config, merged like other scan options) — Skips the prompt and moves all reported unused files to.trashin one step (moveToTrash).
Recommended Workflow:
- Run with
--dry-runfirst to see what would be deleted - Review the results carefully
- Run without
--dry-runand either use the interactive flow or--auto-fixif you want everything moved to.trashwithout prompts - Prefer Move to
.trashwhen using the interactive flow - Test your application
- Empty
.trashwhen confident
How It Works
Code Analysis
- File Discovery - Uses
fast-globto find all code files matching patterns with intelligent exclusion handling - Path Alias Resolution - Reads path aliases from your
jsconfig.jsonortsconfig.json(or manualpathsconfig) to understand how imports are resolved. This enables accurate file finding even in large codebases with complex import structures. - AST Parsing - Parses JavaScript/TypeScript with Babel;
.ts/.mts/.ctsare parsed without the JSX plugin so TypeScript angle-bracket assertions (e.g.<Type>expr) are valid, while.tsx/.js/.jsxkeep JSX parsing. Vue & Nuxt:.vueSFCs are compiled with@vue/compiler-sfc; script blocks uselangfor the TS/JSX split. Image and dependency scanning understand.vuefiles (utils/astParser.ts,utils/fileProcessing.ts,controllers/image.ts). For Nuxt, runqleaner init, choose Vue, and setpathto your app root (e.g.src/or project root). - Module Resolution - Uses
enhanced-resolvewith your project's path aliases to resolve import paths accurately. Supports:- Path aliases (e.g.,
@/components,~/utils) - Relative imports (
./component,../utils) - Node modules (
react,lodash) - Directory index files (automatically resolves
./componentsto./components/index.ts)
- Path aliases (e.g.,
- Dependency Graph - Builds a comprehensive graph of file dependencies, tracking both imports and exports
- Unused Detection - Identifies files with no incoming imports (except entry points in
excludeFilePrintand paths matchingexcludeDirPrint). Files that are only used via re-exports (barrel files) are treated as used when downstream files import the exported symbols or*.
Image Analysis
- Image Discovery - Finds all image files (png, jpg, jpeg, svg, gif, webp) using glob patterns with exclusion support
- Advanced Code Scanning - Uses sophisticated AST traversal to extract image references from:
- ES6 import statements (
import logo from './logo.png') - CommonJS require (
require('./logo.png')) - Dynamic imports (
import('./logo.png')) - JSX attributes (
<img src="https://raw.githubusercontent.com/trevismurithi/react-cleaner/HEAD/logo.png" />) - React style props (
style={{ backgroundImage: "url('./logo.png')" }}) - CSS files (
url('./logo.png')orurl('/images/logo.png')) - Styled-components (
css`background-image: url('./logo.png')`) - Arrays (
const images = ['./logo.png', './icon.png']) - Template literals (
`./logo-${name}.png`) - String literals (any string containing an image path pattern)
- Spread elements in arrays
- ES6 import statements (
- Path Normalization - Normalizes paths based on alias/root configuration, handling both relative and absolute paths
- Unused Detection - Compares image files against all discovered references to identify truly unused images
📊 Example Workflow
# 1. Initialize configuration (CRITICAL STEP - get this right!)
qleaner init
# Make sure to select the correct jsconfig.json or tsconfig.json file
# Verify the generated qleaner.config.json has the correct codeAlias
# 2. Verify your configuration
cat qleaner.config.json
# Check that codeAlias matches your project's config file
# 3. Scan for unused code files (dry run first!)
qleaner scan src --dry-run --table
# 4. Review results - if you see false positives, check your config
# Fix codeAlias or paths if needed, then clear cache and rescan:
qleaner scan src --clear-cache --dry-run --table
# 5. Scan for unused images (dry run)
qleaner image . --dry-run --table
# 6. Check for unused dependencies
qleaner dep --table
# 7. Optional: unused exports, prune, logs, duplicates (dry-run first)
qleaner exports . --dry-run
qleaner prune . --dry-run
qleaner prune-logs -i
qleaner prune-logs src/infisical-main/frontend --dry-run
qleaner duplicates . --dry-run
# 8. Get project summary
qleaner summary
# 9. Get largest files report
qleaner summary --largest-files
# 10. Get dependency analysis
qleaner summary --dependencies
# 11. Once confident with results, run actual scans and delete files
qleaner scan src
qleaner image .
# 12. Optional one-shot cleanup (dry-run each step; add --auto-fix to apply)
# qleaner tidy
# qleaner tidy . --auto-fix
Use Cases
- Before Deployment - Clean up unused files to reduce bundle size
- Code Review - Verify no unused files are being added
- Refactoring - Find files that can be safely removed
- Optimization - Identify large files and dependency hotspots
- Maintenance - Regular cleanup to keep codebase healthy
Requirements
- Node.js 14+ (LTS recommended)
- npm or yarn
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT
Links
- Repository: https://github.com/trevismurithi/react-cleaner
- Issues: https://github.com/trevismurithi/react-cleaner/issues
- NPM Package: https://www.npmjs.com/package/qleaner
📚 Additional Resources
Tips for Best Results
- Get configuration right first - Most important! Ensure
codeAliaspoints to the correctjsconfig.jsonortsconfig.jsonfile, or manually configurepathsif you don't use these config files. Incorrect configuration leads to false positives and missed dependencies. - Verify your config file - After running
qleaner init, check thatcodeAliasmatches your project's actual config file. For monorepos, you may needtsconfig.app.jsonortsconfig.base.jsoninstead oftsconfig.json. - Run scans regularly - Set up a cron job or CI check to catch unused files early
- Use dry-run first - Always preview with
--dry-runbefore deleting anything - Review entry points - Make sure
excludeFilePrintin config includes all entry point files (index.tsx, main.js, etc.) - Clear cache when needed - After major refactoring, dependency changes, or config file updates, use
--clear-cachefor accurate results - Test after deletion - Always test your application thoroughly after removing files
- Use table format for large outputs - The
-tflag makes results easier to read - Check summary regularly - Use
qleaner summaryto monitor project health - For large codebases - The enhanced file finding mechanism with proper config ensures accurate results even in projects with thousands of files and complex import structures
Command Dependencies
Best practice: Run qleaner scan <your-src> (or qleaner scan with path in qleaner.config.json) before commands that need unused-check-cache.json.
| Command | Requires |
|---|---|
qleaner list <dependency> |
unused-check-cache.json from qleaner scan |
qleaner dep |
unused-check-cache.json from qleaner scan |
qleaner exports |
unused-check-cache.json from qleaner scan |
qleaner summary |
Code and/or image cache from qleaner scan / qleaner image |
qleaner prune, prune-logs, duplicates |
qleaner.config.json with path; optional unused-check-cache.json for incremental behavior / parentGraph.fixes |
qleaner tidy |
Config, scan cache for the exports step, and the same prerequisites as the sub-steps |
Common Issues
Q: Qleaner reports files as unused that are actually used. A:
- Check your configuration - Most commonly, this happens when
codeAliasis incorrect orpathsis not configured properly. Verify that Qleaner can resolve your import aliases:- Ensure
codeAliaspoints to the correct config file (check if it exists and has the right path mappings) - If using manual
paths, verify the alias patterns match your imports - Try running with
--clear-cacheafter fixing config
- Ensure
- These might be entry points - Add them to
excludeFilePrintin your config or use-Fflag - Verify the file is actually imported - Check with
qleaner list <file-path>to see if it's referenced - Check for dynamic imports - Some dynamic imports may not be detected
Q: Images aren't being detected. A:
- Verify your
-a(alias) or-r(root-referenced) flag matches how images are referenced in code - Check if the image path patterns match what's in your code
- Try
--clear-cacheto rebuild the image graph - Ensure the
<rootPath>argument includes all directories that reference images
Q: Scan is slow on large projects. A:
- First scan is always slower - it builds the complete dependency graph
- Subsequent scans use caching and are much faster (only changed files are re-analyzed)
- The enhanced file finding mechanism with proper config ensures accurate and efficient resolution even in large codebases
- Exclude more directories with
-eflag to speed up scans - Consider scanning smaller subdirectories separately
- Ensure your
codeAliasconfig is correct - incorrect config can cause unnecessary resolution attempts
Q: How do I know if my configuration is correct? A:
- After
qleaner init, verifycodeAliasinqleaner.config.jsonmatches your project's config file - Run a test scan:
qleaner scan src --dry-runand check if files you know are used are incorrectly reported as unused - If you see false positives, check:
- Does your
jsconfig.json/tsconfig.jsonexist and have correctpathsconfiguration? - Is
codeAliaspointing to the right file? - If using manual
paths, do the patterns match your import statements?
- Does your
- For monorepos, you may need
tsconfig.app.jsonortsconfig.base.jsoninstead oftsconfig.json
Q: How do I undo deletions? A:
- If you used "Move to
.trash", files are safely stored in.trashdirectory in your project root - Permanently deleted files can be restored from git if you're using version control
- Always test after deletions before emptying
.trash
Q: list command shows no results but I know the dependency is used.
A:
- Make sure you ran
qleaner scan(with-porpathin config) first to generate the cache - The dependency path might need to match exactly - try partial paths (e.g.,
reactinstead ofreact/dist/react.production.min.js) - Check if the dependency is in
node_modulesor a local file path
Q: dep command shows dependencies I know are used.
A:
- Some dependencies might be used only in config files (webpack.config.js, etc.) which aren't scanned
- Dynamic requires/imports might not be detected
- Check if they're actually used with
qleaner list <dependency-name>
Made with love for clean codebases
Related Packages
Static analysis engine for full-stack TypeScript and JavaScript: maps each UI ac...
Monorepo-aware static analysis and codemod engine for JavaScript/TypeScript/Vue....
🔍 AST Analyzer - AI Toolkit для анализа кода с GraphStore и CompactReportConfig
Trace any user action from the UI to the database. Maps every click through Reac...
Version History
| Version | Released | License |
|---|---|---|
| 2.1.0 | MIT | |
| 2.0.0 | MIT | |
| 1.5.1 | MIT | |
| 1.5.0 | MIT | |
| 1.4.2 | MIT | |
| 1.4.1 | MIT | |
| 1.4.0 | MIT | |
| 1.3.3 | MIT | |
| 1.3.2 | MIT | |
| 1.3.1 | MIT | |
| 1.3.0 | MIT | |
| 1.2.0 | MIT | |
| 1.1.5 | MIT | |
| 1.1.4 | MIT | |
| 1.1.3 | MIT | |
| 1.1.2 | MIT | |
| 1.1.1 | MIT | |
| 1.1.0 | MIT | |
| 1.0.34 | MIT | |
| 1.0.32 | MIT | |
| 1.0.31 | MIT | |
| 1.0.30 | MIT | |
| 1.0.29 | MIT | |
| 1.0.28 | MIT | |
| 1.0.27 | MIT | |
| 1.0.26 | ||
| 1.0.25 | ||
| 1.0.24 | ||
| 1.0.23 | ||
| 1.0.22 |
Showing the latest 30 of 52. See every release on npm