Veracode published its 2026 GenAI Code Security Report on 28 July, and one pair of numbers explains why static analysis matters more than a year ago. AI-generated code was syntactically correct close to 100 percent of the time. Its security pass rate averaged 56 percent, flat against 55 percent a year earlier. Cross-site scripting passed 15 percent of the time, log injection 12 percent.
That is a tooling problem, not a model problem. Code that always compiles sails past anything that only checks syntax. The checks that catch the rest understand types, follow data across file boundaries, and recognize a tainted string before it reaches a template. That class of analysis got dramatically faster in 2026, and almost all of it is free. Everything with a version number below was run locally.
The three sections below are the three layers, and conflating them leads to bad choices. Linters and type checkers run in milliseconds but do not follow data across files. SAST does that cross-file work in minutes, so it belongs on pull requests. Platforms add dashboards and enforcement. Start with the fast layer, because developers keep it running.
The Fast Layer: Linters and Type Checkers
JavaScript and TypeScript

Oxlint is the biggest change here since the last version of this guide. On 22 July 2026 the Oxc project marked type-aware linting stable, powered by tsgolint, which builds TypeScript programs using the Go port of the compiler. Benchmarks against typescript-eslint show 12x on VS Code, 14x on the TypeScript repo and 18x on TypeORM, and tsgolint v7 implements 59 of typescript-eslint's 61 type-aware rules.
Type awareness is off by default and needs a companion package, which is where most first attempts fail with Failed to find tsgolint executable. On Oxlint 1.76.0:
Bashnpm install --save-dev oxlint oxlint-tsgolint npx oxlint --type-aware src
textsrc/orders.ts:7:5: warning typescript(no-floating-promises): Promises must be awaited, add void operator to ignore.
The same file without --type-aware reports nothing, which is the argument for the feature in one line. One gotcha: Oxlint walks the filesystem rather than reading tsconfig.json includes, so keep node_modules in .gitignore. Shopify, Airbnb and Mercedes-Benz run it alongside ESLint.

Biome is one Rust binary replacing ESLint and Prettier, at 97 percent Prettier compatibility. Version 2.5 shipped 5 June 2026, crossed 500 lint rules and added cross-file rules on its module graph. Its distinguishing trait: type-aware rules never call the TypeScript compiler, so they work with no typescript dependency. Some are nursery rules, so you opt in:
JSON{ "$schema": "https://biomejs.dev/schemas/2.5.6/schema.json", "linter": { "rules": { "recommended": true, "nursery": { "noFloatingPromises": "error" } } } }
That config caught the same floating promise plus a non-null assertion in 116ms. The trade-off against Oxlint is coverage: self-implemented inference is not the compiler, so exotic generics lag.

ESLint v10.0.0 landed 6 February 2026 and removed eslintrc outright, so flat config in eslint.config.js is the only supported format, Node.js 20.19.0 minimum. The date that matters: ESLint v9.x reaches end of life on 6 August 2026. It remains the only option with full plugin coverage. Our ESLint Config Generator produces a working flat config if you are migrating.
Python

Ruff 0.16.1 is the Python default, replacing Flake8, Black and isort with 900+ rules and no configuration: uvx ruff check . returned four findings with fixes on a sloppy sample. Pair it with ty, Astral's Rust type checker, in beta since 19 March 2026 and now 0.0.65:
texterror[invalid-argument-type]: Argument to function `apply_discount` is incorrect --> checkout.py:6:40 | 6 | discounted = apply_discount(price, coupon) | ^^^^^^ Expected `int`, found `str | None`
A real bug in six lines of plausible checkout code, found with no config. Two caveats: it is still 0.0.x, so behavior shifts between releases, and Astral has agreed to join OpenAI's Codex team, pending approval, with a commitment to keep the tools open source. For security add Bandit 1.9.4, which reported B608 (CWE-89) on a concatenated query.
Go, Rust, PHP and Beyond

Go. golangci-lint v2.12.2 bundles staticcheck and govet behind one command; on a swallowed error it reported SA9003: empty branch, which is Go's most common real defect. Add gosec with one caveat from testing: it found G304 but missed a SQL injection in both concatenation and fmt.Sprintf forms, even with -include=G201,G202. Rule coverage is pattern-specific, so a quiet security linter is not proof nothing is there.
Rust. cargo clippy ships with the toolchain, needs no setup, and teaches idiom rather than flagging style. On a function taking &Vec<f64> and looping by index it flagged both the needless allocation and the index loop, with fixes.

PHP. PHPStan 2.2.7 runs from a single phar with ten strictness levels, so legacy code adopts it without a rewrite. Given an array shape of {price: float, qty: int} and a loop reading $item['quantity'] it found the typo PHP surfaces only at runtime. Psalm 6.16.1 is stricter and adds taint analysis, so many teams run both.


Elsewhere. Checkstyle 13.9.0, SpotBugs and PMD for Java, RuboCop v1.88.2 for Ruby, clang-tidy and Cppcheck for C++.

Why These Got So Fast
| Tool | Language | Replaces | Reported speed gain |
|---|---|---|---|
| Ruff | Python | Flake8 + Black + isort | 100-155x faster |
| Biome | JS/TS/CSS | ESLint + Prettier | 15x linting, 35x formatting |
| Oxlint | JS/TS | ESLint | 50-100x faster |
| Oxlint + tsgolint | TS type-aware | typescript-eslint | 12-18x faster |
| ty | Python types | mypy, pyright | 60-100x on cold checks |
The last two rows are the 2026 additions and matter most: type-aware analysis and type checking were nightly jobs, and now they run in seconds.
The Security Layer: SAST
Semgrep and Opengrep

Semgrep CE 1.172.0 is the most approachable way to write a security rule, because the pattern language looks like the code it matches. This one is tested:
yamlrules: - id: python-sqli-string-concat languages: [python] severity: ERROR message: SQL built by concatenation. Use a parameterised query instead. patterns: - pattern-either: - pattern: $CURSOR.execute(<... "..." + $VAR ...>) - pattern: $CURSOR.execute(f"...{$VAR}...") - pattern: $CURSOR.execute("..." % $VAR) - pattern: $CURSOR.execute("...".format(...))
Against a file with a concatenated query, an f-string query and a correctly parameterised one, it reported exactly the two real problems. Worth knowing: the naive $CURSOR.execute("..." + $VAR) matches nothing, because "..." + email + "'" parses as nested concatenation. The deep expression operator <... ...> is what makes it work.

The Opengrep fork. After Semgrep relicensed vendor-maintained rules in December 2024, a consortium of ten-plus security vendors including Aikido, Endor Labs and Orca Security launched Opengrep as an LGPL-2.1 fork, keeping taint analysis and interprocedural scanning free. Now at v1.26.0. I ran the same rule file, unmodified, through it: Ran 1 rule on 1 file: 2 findings. Identical results, so rule investment is portable and the engine choice can wait. Semgrep is free to 10 contributors and 10 repositories, then $30 per contributor per month; Opengrep is free.
CodeQL

CodeQL is the deepest free option for public GitHub repos: twelve languages, Copilot Autofix included, no Copilot subscription. Private repos need GitHub Code Security at $30 per active committer per month. Its dataflow beats pattern matching, but a custom query is a project, not an afternoon.
Infrastructure as Code

Trivy 0.73.0 scans IaC, dependencies, images and secrets from one Apache-2.0 binary. On a fourteen-line Terraform file: Failures: 11 (LOW: 4, MEDIUM: 1, HIGH: 6), including unrestricted SSH ingress. Filtering --severity HIGH,CRITICAL cut eleven to six. Checkov 3.3.9 caught the same exposure but nine of ten failures were policy preferences, so tune the set on day one. In the browser, our Kubernetes Manifest Linter and Dockerfile Linter cover manifests and image builds.
AI-Native SAST, the Paid Alternative

These pair a model with program analysis to cut false positives and draft the patch. ZeroPath claims twice the vulnerabilities with 75 percent fewer false positives at $1,000/month plus $60/developer, Corgea is free for two developers then $39/developer/month, DryRun Security scopes to the PR diff. Vendor numbers, so trial one on a repo where you already know three real issues.
The Platform Layer

SonarQube covers 40+ languages, now on calendar versioning with 2026.1 as the LTA release. The Quality Gate is the reason to adopt it: a pass/fail threshold that blocks pull requests, turning quality from a suggestion into a requirement. Scanning covers OWASP, CWE, STIG, NIST SSDF and PCI DSS with cross-file taint analysis.
The 2026 addition is AI Code Assurance, and secondary coverage of it has been loose. Per Sonar's documentation, an administrator toggles "Contains AI-generated code" in project settings and the project then needs an AI-qualified quality gate to earn the badge: a governance and labelling workflow, not a detector of which lines an assistant wrote. Community Build is free and LGPL-3.0; Cloud Team starts at $32/month.


Qlty differs structurally: its core CLI is open-source Rust, running locally or in any CI across 60+ plugins with no lock-in. MegaLinter is the other bundler worth knowing.
Wiring It Into CI
SARIF ties the layers together. Oxlint, Ruff and Semgrep all emit SARIF 2.1.0, confirmed by generating and parsing output from each, so findings land in GitHub code scanning with inline annotations instead of job logs.
yamlname: static-analysis on: [pull_request] permissions: contents: read security-events: write jobs: lint: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "24" - run: npm ci - name: Type-aware lint continue-on-error: true run: npx oxlint --type-aware --format sarif src > oxlint.sarif - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: oxlint.sarif category: oxlint sast: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v5 with: python-version: "3.13" - run: pip install semgrep==1.172.0 - name: Semgrep scan continue-on-error: true run: semgrep --config p/default --sarif --output semgrep.sarif --metrics=off . - uses: github/codeql-action/upload-sarif@v3 with: sarif_file: semgrep.sarif category: semgrep
continue-on-error: true is deliberate: it lets the SARIF upload run even when findings exist, so code scanning enforces policy rather than the job's exit code. Remove it once the noise level is acceptable.
The Compliance Deadline
From 11 September 2026 the EU Cyber Resilience Act requires manufacturers to report actively exploited vulnerabilities: early warning within 24 hours, fuller notification within 72. The trigger is active exploitation rather than any CVE, and it applies to products still on the market regardless of ship date. That clock is impossible without automated scanning.
Head-to-Head Comparison
| Tool | Category | Languages | License | Free Tier | Paid Starts At |
|---|---|---|---|---|---|
| Ruff | Linter + formatter | Python | MIT | Free forever | - |
| ty | Type checker | Python | MIT | Free forever | - |
| Bandit | Security linter | Python | Apache-2.0 | Free forever | - |
| Oxlint | Linter (type-aware) | JS/TS | MIT | Free forever | - |
| Biome | Linter + formatter | JS/TS/CSS/JSON | MIT or Apache-2.0 | Free forever | - |
| ESLint | Linter | JS/TS | MIT | Free forever | - |
| Clippy | Linter | Rust | MIT or Apache-2.0 | Ships with rustup | - |
| golangci-lint | Linter aggregator | Go | GPL-3.0 | Free forever | - |
| RuboCop | Linter | Ruby | MIT | Free forever | - |
| Checkstyle | Linter | Java | LGPL-2.1 | Free forever | - |
| PHPStan | Type checker | PHP | MIT | Free forever | ~7 EUR/mo (Pro UI) |
| Psalm | SAST + types | PHP | MIT | Free forever | - |
| Semgrep | SAST | 30+ | LGPL-2.1 | 10 contributors, 10 repos | $30/contributor/mo |
| Opengrep | SAST | 30+ | LGPL-2.1 | Free forever | - |
| CodeQL | SAST | 12 | Source-available | Free on public repos | $30/committer/mo |
| Trivy | IaC, deps, images | Multi | Apache-2.0 | Free forever | - |
| Checkov | IaC policy | Multi | Apache-2.0 | Free forever | - |
| Corgea | AI SAST | Multi | Proprietary | 2 devs, 10 repos | $39/dev/mo |
| ZeroPath | AI SAST | Multi | Proprietary | None | $1,000/mo + $60/dev |
| SonarQube | Platform | 40+ | LGPL-3.0 Community Build | Self-hosted Community | $32/mo (Cloud Team) |
| DeepSource | Platform | 16+ | Proprietary | Open source repos | $24/user/mo |
| Qlty | Platform | 40+ | Open-source CLI | 1,000 min/mo | $20/contributor/mo |
How to Pick
Solo developer or open-source maintainer. Ruff for Python or Oxlint for TypeScript plus Semgrep's free tier. Zero cost, covering the two bug classes that matter most.
Small team. The same linters plus SonarQube Cloud Team at $32/month flat or DeepSource at $24/user/month, for the dashboards and enforcement that stop quality eroding as the team grows.
Existing large TypeScript codebase. Keep ESLint for plugins you cannot replace, move type-aware rules to Oxlint, and do the v10 flat config migration since v9 is unmaintained.
A fully open-source pipeline. Oxlint or Biome, Ruff with ty, golangci-lint, Clippy, PHPStan, Opengrep and Trivy, routed into code scanning as SARIF. You trade a license fee for configuration effort, giving up the dashboard, AI triage and support contract that the paid tools sell.
Enterprise or compliance. SonarQube Enterprise or Server for OWASP, CWE, STIG and NIST SSDF with audit trails, plus AI Code Assurance labelling.
Conclusion
The checks that catch real bugs are now fast enough to run on every commit, and the tools that made that happen, Oxlint, Biome, Ruff and ty, are all free and open source. Install a type-aware linter and get to zero findings this week, add one SAST engine with a few relevant rules, and route output into code scanning as SARIF. The tools stopped being the constraint; keeping the finding count low enough that people read it still takes discipline.
Related DevToolLab Tools
- ESLint Config Generator - Generate a working
eslint.config.jsflat config for the ESLint v10 migration. - TypeScript Config Generator - Build the
tsconfig.jsonthat type-aware linting resolves types from. - Dockerfile Linter - Check Dockerfiles against build and security best practices in the browser.
- Kubernetes Manifest Linter - Catch missing limits, privileged containers, and bad probes in K8s YAML.
- Best AI Code Review Tools - The pull request review layer that sits on top of these scanners.
- Best AI Bug Detection Tools - Finding the bugs that already shipped to production.
Pricing and version numbers change frequently. Verify current pricing directly with each vendor before making purchasing decisions.
