Four numbers describe most of what teams mean by code quality. Here is what each one counts, the range worth acting on, the point where it starts lying to you, and which browser tool on Toolexe measures it.
Static analysis catches a narrow band of defects. Style drift, unsafe sinks, structural risk and orphaned branches show up reliably. Logic errors almost never do, because no scanner knows what your feature was supposed to do.
The narrow band still pays for itself, because the defects inside it are the ones people read straight past. A reviewer skims a 400 line diff and misses the third nested ternary on line 218. A parser counts it in under a millisecond. Everything on this page exists to clear mechanical work off the reviewer's desk so their attention lands on intent, edge cases and naming, which is the part machines handle badly.
Two failure modes follow from misreading the output. Teams either treat every metric as a hard gate and split perfectly readable functions to satisfy a number, or they run the scan, glance at a green summary and skip the reading entirely. The thresholds below exist to keep you between those two.
Dozens of quality metrics exist. Four carry most of the signal for day to day work, and each has a documented range you act on rather than a target you chase. The last column matters more than the others, because a metric you trust blindly does more damage than one you never ran.
| Metric | What it counts | Range to act on | Where it misleads you |
|---|---|---|---|
| Cyclomatic complexity | Independent paths through one function. Start at 1, add 1 for every if, else if, case, loop, catch, ternary and short-circuit operator. | 1-10 low risk 11-20 moderate 21-50 high risk 50+ rewrite candidate | A flat switch with 30 unrelated cases scores 30 while reading perfectly well. The metric counts branches, not confusion. |
| Maintainability index | A composite of Halstead volume, cyclomatic complexity and lines of code, rescaled onto 0 through 100. | 0-9 red, act now 10-19 amber, watch list 20-100 green | Length drags the score down on its own, so a long well factored module rates worse than a short tangled one. |
| Duplication ratio | Share of tokens sitting inside clone blocks, usually measured at a 50 token minimum match length. | Under 3% normal 3-5% review the clones Over 5% schedule a refactor | Generated API clients, database migrations and test fixtures inflate the ratio. Exclude them before reading the number. |
| Statement coverage | Share of executable lines a test run touched at least once. | 70-80% working band for app code 90%+ for parsers and libraries | A suite with no assertions still reports 100%. Coverage proves execution, never correctness. |
Complexity bands follow McCabe (1976) and NIST SP 500-235. Maintainability bands follow the Microsoft 0 to 100 rescaling.
Neither number means much alone. A file at complexity 24 with duplication near zero is usually one dense algorithm, and dense algorithms are fine when they are tested. A file at complexity 24 with 11 percent duplication is copy paste growth, and it will keep growing until somebody names the shared behavior. Pair the structural metric with the duplication ratio before deciding whether to refactor.
Order matters more than tool count. Running a security scan on a file the parser rejected wastes the scan, and arguing about comment style before checking branching wastes the review. This sequence takes about twenty minutes on a medium pull request.
A syntax error poisons every check downstream. Complexity counts go wrong, scanners bail out silently, and you spend ten minutes reading a report about a file nothing could read.
Structural problems survive every rename and every formatting pass. Look at branching, clones and orphaned exports before anyone argues about brace placement.
Injection shapes, unsafe sinks and stale dependency versions are pattern work. Machines beat tired humans at pattern work every time, so give the machine that job.
The branch you added this morning is the branch nobody covers. Write the missing case while the reasoning behind it is still in your head.
Reviewers move faster when the risky parts are named up front. Three lines of context beat a 600 line diff with no map.
Run the count manually a single time and the tool output stops being a mystery number. Every decision point adds one to a base of one. Here is a shipping fee function with the additions marked.
function shippingFee(order) {if (!order) return 0; // +1let fee = 5;if (order.weight > 10) fee += 4; // +1if (order.express) fee += 12; // +1for (const item of order.items) { // +1if (item.fragile) fee += 2; // +1}
return order.total > 100 ? 0 : fee; // +1}Seven sits inside the low risk band, so nothing here needs splitting. The second figure is the one worth carrying into your test file: the complexity score doubles as the count of paths a suite has to walk to claim full branch coverage. A function scoring 22 needs 22 test cases, which is the practical argument for splitting it, rather than any aesthetic objection to long functions.
Where the count misfires: guard clauses inflate it cheaply. Five early returns validating five arguments score five points and read more clearly than one nested block scoring the same. Check whether the branches belong to one concern before you act on the number. Paste the function into the Code Complexity Analyzer to compare your manual count against the parser.
The stages above assume a change under review. Production incidents run backwards, from symptom to cause, so the entry point differs.
Formatting, generators, load testing and monitoring live alongside the analysis tools.
Being direct about the ceiling saves you a wasted afternoon. Five limits apply to every analyzer in this category, and knowing them tells you when to reach for a pipeline scanner instead.
Every analyzer on Toolexe reads the text you paste into it. Nothing resolves imports across a repository, so an export consumed by three other modules still reads as dead code when the file is viewed alone. Confirm any removal with a project wide search before you delete a line.
Reflection, eval, computed property access and SQL assembled from strings defeat lightweight parsing. Complexity and security passes under-report on files built around those patterns, and a clean result there means the parser gave up, not that the code is safe.
Paste an lcov file or an Istanbul summary and you get the uncovered branches ranked by risk. Your suite still executes in your own environment, on your own runner.
A scanner finds an unescaped sink. No scanner knows a route was supposed to check record ownership before returning the row. Business logic flaws remain a human review problem, which is the main reason a green scan is never a merge signal on its own.
Repository wide enforcement on every push belongs to ESLint, Semgrep, SonarQube, PHPStan or your language equivalent, wired into the pipeline. These pages fit the ten minutes before you open a pull request, or an audit of a snippet with no project checked out.
Most teams warn above 10 and block above 15 for application code. Treat the figure as a prompt rather than a rule. A function scoring 12 across one validation chain reads fine. A function scoring 12 across four unrelated concerns needs splitting, whatever the threshold says.
No. Analysis runs as JavaScript inside your browser tab, so the snippet never leaves your device. Reload the page and the input is gone. Nothing is written to a Toolexe server and nothing is logged.
Rarely. The final 15 percent is usually error handling nobody triggers plus generated code nobody reads. Target 70 to 80 percent on application code, then spend the leftover effort on assertion quality and on the branches your bug tracker keeps pointing at.
JavaScript and TypeScript get the deepest parsing. PHP, Python, Java, C# and Go run through pattern level analysis, so structural metrics hold up while language specific idioms report less accurately. The syntax validators are exact for JSON, XML, CSS and HTML because those grammars are fully parsed.
Copy the report output and paste it into the description inside a fenced block. The Review Checklist Generator emits Markdown task lists, which GitHub and GitLab render as tickable items. Reviewers work through a checklist faster than a prose summary.
No. Scope is one file or one pasted snippet. Repository level scoring needs a checkout and a build, which means a CI job. Use these pages for the change in front of you, and a pipeline scanner for the trend line across releases.
Thresholds on this page are not house opinions. Each one traces to a published source, listed below, and gets rechecked whenever a referenced standard changes.
Pick the stage matching the work in front of you, run the two or three tools it names, and attach the output to your pull request. The reviewer reads faster and you stop relitigating brace style.
Open the code quality catalog