Why open source code review matters
Choosing an open source code review tool is not just about saving money - it is about control. When your code review infrastructure is proprietary, you are trusting a vendor with your most sensitive asset: your source code. Every pull request, every diff, every comment passes through servers you do not own. For teams working on regulated software, defense contracts, healthcare applications, or financial systems, that is a non-starter.
Open source code review tools solve four problems that proprietary tools cannot:
Data privacy and sovereignty. Self-hosted open source tools keep your code on your infrastructure. Nothing leaves your network. PR-Agent can run in a Docker container on your own servers, connected to your own LLM API keys. SonarQube Community Build runs entirely within your firewall. For teams subject to GDPR, HIPAA, SOC 2, or FedRAMP requirements, this is often the only compliant option.
Deep customization. Open source tools let you modify the analysis engine itself, not just configure it. You can fork Semgrep and add custom language support. You can extend PR-Agent with new commands. You can write SonarQube plugins that enforce your organization's specific coding standards. Proprietary tools give you configuration knobs. Open source gives you the entire machine.
Cost predictability. Proprietary code review tools charge $15-40 per developer per month. For a 50-person engineering team, that is $9,000-24,000 per year - and the price only goes up as your team grows. Open source tools cost the infrastructure to run them, which is often a single Docker container on an existing server. The economics are fundamentally different.
No vendor lock-in. When a proprietary tool shuts down, gets acquired, or changes its pricing model, you scramble. When an open source tool's maintainer moves on, the code is still there. You can fork it, maintain it, or migrate to an alternative on your own timeline. Your configuration files, custom rules, and workflow integrations remain under your control.
This guide covers 15 open source code review tools organized into three categories: AI-powered tools that use large language models to understand code semantics, rule-based tools that apply deterministic pattern matching, and language-specific linters that provide deep analysis within a single ecosystem. For each tool, we include setup guides, configuration examples, GitHub Actions YAML, and an honest difficulty assessment.
Quick comparison: all 15 open source tools
| Tool | GitHub Stars | License | Languages | Setup Difficulty | AI-Powered | Best For |
|---|---|---|---|---|---|---|
| PR-Agent | 7k+ | Apache 2.0 | 20+ | Medium | Yes | Self-hosted AI PR review |
| Aider | 30k+ | Apache 2.0 | 20+ | Easy | Yes | Terminal-based AI coding and review |
| Continue | 25k+ | Apache 2.0 | 20+ | Easy | Yes | IDE-based AI review |
| Cody (Sourcegraph) | 3k+ | Apache 2.0 | 20+ | Medium | Yes | Codebase-aware AI review |
| Sweep AI | 7k+ | BSL 1.1 | 10+ | Medium | Yes | Automated PR fixes |
| Semgrep | 11k+ | LGPL 2.1 | 30+ | Easy | Partial | Custom security rules |
| SonarQube Community | 9k+ | LGPL 3.0 | 30+ | Hard | Partial | Quality gates and compliance |
| CodeQL | 8k+ | MIT | 10 | Medium | No | Security vulnerability research |
| Danger JS | 5k+ | MIT | Any | Easy | No | Automated PR policy checks |
| ReviewBot | 200+ | MIT | Any | Easy | No | Configurable review automation |
| ESLint | 25k+ | MIT | JS/TS | Easy | No | JavaScript/TypeScript linting |
| Ruff | 40k+ | MIT | Python | Easy | No | Python linting (fast) |
| golangci-lint | 16k+ | GPL 3.0 | Go | Easy | No | Go linting meta-runner |
| Clippy | Part of Rust | MIT/Apache 2.0 | Rust | Easy | No | Rust idiom linting |
| RuboCop | 13k+ | MIT | Ruby | Easy | No | Ruby style and quality |
AI-powered open source tools
These five tools use large language models to understand code semantics, catch logic errors, and generate natural language explanations. They go beyond pattern matching to reason about what your code does and whether it does it correctly.
1. PR-Agent (Qodo Merge OSS)
PR-Agent is the most capable open source AI code review tool available. Built by Qodo (formerly CodiumAI), it provides AI-powered pull request review, description generation, improvement suggestions, and more - all self-hostable with your own LLM API keys. The open source version covers the core review functionality that most teams need, while the commercial Qodo Merge adds enterprise features.
What it does. PR-Agent connects to your GitHub, GitLab, Bitbucket, or Azure DevOps repositories and uses LLMs to analyze every pull request. It provides several slash commands that you can invoke from PR comments:
-
/review- Performs a comprehensive code review and posts inline comments identifying bugs, security issues, and improvement opportunities -
/describe- Generates a structured PR description including a summary, walkthrough of changes, and labels -
/improve- Suggests specific code improvements with diff-ready suggestions -
/ask- Lets you ask natural language questions about the PR changes -
/update_changelog- Automatically updates your CHANGELOG file based on the PR changes -
/test- Generates test suggestions for the changed code
The tool works by sending diffs to an LLM (OpenAI, Anthropic, or any OpenAI-compatible endpoint) with carefully engineered prompts that produce structured, actionable output. Because you supply your own API keys, you control exactly which model processes your code and where that processing happens.
Setup guide. The fastest way to get PR-Agent running is through GitHub Actions. Create a workflow file in your repository:
# .github/workflows/pr-agent.yml
name: PR-Agent
on:
pull_request:
types: [opened, reopened, ready_for_review]
issue_comment:
types: [created]
jobs:
pr_agent:
if: ${{ github.event.sender.type != 'Bot' }}
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
contents: write
steps:
- name: PR-Agent Review
id: pr-agent
uses: Codium-ai/pr-agent@main
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github_action_config.auto_review: "true"
github_action_config.auto_describe: "true"
github_action_config.auto_improve: "true"
For self-hosted deployment with Docker, PR-Agent provides a Docker image that runs as a webhook server:
docker pull codiumai/pr-agent:latest
docker run -d \
--name pr-agent \
-p 3000:3000 \
-e OPENAI.KEY=sk-your-openai-key \
-e GITHUB.WEBHOOK_SECRET=your-webhook-secret \
-e GITHUB.APP_ID=your-app-id \
-e GITHUB.PRIVATE_KEY_PATH=/keys/private-key.pem \
-v /path/to/keys:/keys \
codiumai/pr-agent:latest
Then configure a GitHub App that points its webhook URL to your server. PR-Agent will process events and post review comments automatically.
Configuration. PR-Agent is configured through a .pr_agent.toml file in your repository root:
# .pr_agent.toml
[pr_description]
publish_labels = true
add_original_user_description = true
generate_ai_title = false
use_bullet_points = true
[pr_reviewer]
require_tests_review = true
require_security_review = true
require_focused_review = true
num_code_suggestions = 4
inline_code_comments = true
extra_instructions = """
Focus on:
- Null safety and error handling
- SQL injection and XSS vulnerabilities
- Race conditions in concurrent code
- Missing input validation on API endpoints
"""
[pr_code_suggestions]
num_code_suggestions = 4
extra_instructions = """
Suggest improvements for:
- Error handling patterns
- Performance optimization
- Type safety
"""
LLM backend options. PR-Agent supports multiple LLM providers:
# OpenAI (default)
[config]
model = "gpt-4o"
# Anthropic Claude
[config]
model = "anthropic/claude-sonnet-4-20250514"
# Local models via Ollama
[config]
model = "ollama/codellama"
custom_model_max_tokens = 4096
# Azure OpenAI
[config]
model = "azure/gpt-4o"
Pros:
- Fully open source (Apache 2.0 license)
- Self-hostable with your own API keys - complete data sovereignty
- Multiple LLM backends including local models for air-gapped environments
- Rich command set covering review, description, improvement, and testing
- Active development with frequent releases
- Supports GitHub, GitLab, Bitbucket, and Azure DevOps
Cons:
- Requires an LLM API key, which carries its own costs ($5-30/month depending on PR volume and model choice)
- Review quality depends heavily on which LLM you choose - GPT-4o and Claude Sonnet produce substantially better reviews than smaller models
- Self-hosted deployment requires managing a webhook server
- The open source version lacks some features available in commercial Qodo Merge (such as advanced analytics and SOC 2 compliance)
Setup difficulty: Medium. GitHub Actions setup takes 5-10 minutes. Self-hosted Docker deployment takes 30-60 minutes including GitHub App creation and webhook configuration. Ongoing maintenance is minimal if using a cloud LLM provider.
2. Aider
Aider is a terminal-based AI coding assistant that works directly with your Git repositories. While primarily designed for AI-assisted code generation, its Git awareness and diff-based workflow make it a powerful code review tool that can analyze changes, suggest improvements, and apply fixes directly.
What it does. Aider operates from the command line and uses LLMs to understand your entire codebase. For code review, you can point it at specific files or diffs and ask it to review changes, identify bugs, suggest improvements, or explain complex code. Because it works directly with Git, it can create commits, manage branches, and apply fixes without leaving the terminal.
Aider's "architect" mode is particularly useful for code review. It analyzes code structure and suggests architectural improvements, not just line-level fixes. It understands cross-file dependencies and can identify issues that arise from how different parts of your codebase interact.
Setup guide. Install Aider and configure it with your preferred LLM:
# Install via pip
pip install aider-chat
# Or via pipx for isolation
pipx install aider-chat
# Configure your API key
export OPENAI_API_KEY=sk-your-key
# Or use Anthropic
export ANTHROPIC_API_KEY=sk-ant-your-key
# Start Aider in your repo
cd /path/to/your/repo
aider
For reviewing specific changes, you can use Aider non-interactively:
# Review uncommitted changes
aider --message "Review my uncommitted changes. \
Identify bugs, security issues, and suggest improvements." \
--no-auto-commits
# Review changes in a specific file
aider src/auth/login.ts --message "Review this file for \
security vulnerabilities and missing error handling."
You can also integrate Aider into a CI pipeline for automated review:
# .github/workflows/aider-review.yml
name: Aider Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Aider
run: pip install aider-chat
- name: Review PR changes
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_KEY }}
run: |
git diff origin/main...HEAD > /tmp/changes.diff
aider --message "Review the following diff for bugs, \
security issues, and improvements. Provide specific, \
actionable feedback." --no-auto-commits --yes \
$(git diff --name-only origin/main...HEAD)
Configuration. Aider reads configuration from a .aider.conf.yml file:
# .aider.conf.yml
model: anthropic/claude-sonnet-4-20250514
auto-commits: false
dark-mode: true
map-tokens: 2048
edit-format: diff
Pros:
- Works from the terminal with full Git integration
- Supports virtually every major LLM provider (OpenAI, Anthropic, Google, local models)
- Understanding of entire repository context, not just diffs
- Can apply fixes directly as Git commits
- Apache 2.0 license
- Active community with 30k+ GitHub stars
Cons:
- Not designed as a dedicated code review tool - review is a secondary use case
- No native PR comment integration (requires custom scripting for CI use)
- Terminal-based interface has a learning curve
- Costs depend on LLM API usage
Setup difficulty: Easy. Single pip install. Configuration is a single YAML file. Getting useful review output requires learning Aider's interaction model, but basic usage is straightforward.
3. Continue
Continue is an open source AI code assistant that runs as a VS Code or JetBrains extension. It connects to any LLM (local or cloud) and provides in-editor code review, explanation, and refactoring capabilities.
What it does. Continue integrates directly into your IDE and provides AI-powered code analysis as you work. You can highlight code, ask Continue to review it, and receive inline feedback without leaving your editor. It supports multi-file context, meaning it can understand how a change in one file affects others in your project.
For code review specifically, Continue lets you:
- Highlight code and ask "review this for bugs and security issues"
- Use the
/reviewcommand in the chat panel to analyze selected code - Get explanations of complex code you are reviewing
- Generate test cases for code under review
- Suggest refactoring improvements
Setup guide. Install Continue from the VS Code marketplace or JetBrains plugin store:
# VS Code
code --install-extension continue.continue
# Or search for "Continue" in the VS Code extensions panel
Then configure your LLM provider in ~/.continue/config.json:
{
"models": [
{
"title": "Claude Sonnet",
"provider": "anthropic",
"model": "claude-sonnet-4-20250514",
"apiKey": "sk-ant-your-key"
},
{
"title": "Local Ollama",
"provider": "ollama",
"model": "codellama:13b"
}
],
"tabAutocompleteModel": {
"title": "Starcoder",
"provider": "ollama",
"model": "starcoder2:3b"
}
}
For team-wide configuration, create a .continuerc.json in your repository root:
{
"customCommands": [
{
"name": "review",
"description": "Review selected code for issues",
"prompt": "Review the following code for bugs, security vulnerabilities, performance issues, and code quality. Provide specific, actionable feedback with code examples for fixes:\n\n{{{ input }}}"
},
{
"name": "security-review",
"description": "Security-focused code review",
"prompt": "Perform a security review of this code. Check for: SQL injection, XSS, CSRF, authentication bypass, authorization issues, sensitive data exposure, insecure deserialization, and missing input validation:\n\n{{{ input }}}"
}
]
}
Pros:
- Native IDE integration (VS Code and JetBrains)
- Works with any LLM provider, including local models for air-gapped environments
- Full codebase context through IDE file access
- Custom commands allow team-specific review workflows
- Apache 2.0 license
- Strong community (25k+ GitHub stars)
Cons:
- Review is manual and developer-initiated, not automated on PRs
- No PR comment integration out of the box
- Not a substitute for automated CI-based review
- Quality depends on LLM choice and prompt engineering
Setup difficulty: Easy. Extension install plus API key configuration. Takes 5 minutes. Custom commands for team-specific review add another 10-15 minutes.
4. Cody (Sourcegraph)
Cody is Sourcegraph's AI coding assistant with an open source core. Its key differentiator is deep codebase awareness - it indexes your entire repository (or multiple repositories) and uses that context to provide more accurate code review than tools that only see the current diff.
What it does. Cody combines Sourcegraph's code intelligence platform with LLM-powered analysis. For code review, this means it can understand how a change in one function affects callers across your entire codebase. When reviewing a pull request, Cody can identify:
- Breaking changes that affect downstream consumers
- Missing updates to related code (e.g., changing a function signature without updating all call sites)
- Inconsistencies with patterns established elsewhere in the codebase
- Security issues that span multiple files or services
This cross-repository awareness is something most AI review tools lack. Tools like PR-Agent and CodeRabbit only see the diff and surrounding context. Cody sees everything.
Setup guide. Install the Cody extension for VS Code or JetBrains:
# VS Code
code --install-extension sourcegraph.cody-ai
For self-hosted Sourcegraph with Cody, deploy using Docker Compose:
# docker-compose.sourcegraph.yml
version: '3.8'
services:
sourcegraph:
image: sourcegraph/server:latest
ports:
- "7080:7080"
- "127.0.0.1:3370:3370"
volumes:
- sourcegraph-data:/var/opt/sourcegraph
- sourcegraph-config:/etc/sourcegraph
environment:
- SRC_LOG_LEVEL=warn
- CODY_ENABLED=true
volumes:
sourcegraph-data:
sourcegraph-config:
Configure Cody in your Sourcegraph instance settings:
{
"cody.enabled": true,
"completions": {
"provider": "anthropic",
"chatModel": "claude-sonnet-4-20250514",
"completionModel": "claude-haiku-4-20250414",
"accessToken": "sk-ant-your-key"
}
}
Pros:
- Deep codebase indexing provides cross-file and cross-repository context
- IDE integration for VS Code and JetBrains
- Self-hostable Sourcegraph instance for complete data control
- Understanding of code relationships beyond the current diff
- Apache 2.0 license for the Cody client
Cons:
- Full value requires Sourcegraph server infrastructure (heavier than PR-Agent)
- Self-hosted Sourcegraph has significant resource requirements (8GB+ RAM recommended)
- Primarily an IDE tool - no native PR comment integration in the open source version
- Codebase indexing takes time on large repositories
Setup difficulty: Medium. IDE extension install is easy (5 minutes). Self-hosted Sourcegraph deployment is moderate (1-2 hours) and requires more infrastructure than simpler tools.
5. Sweep AI
Sweep AI is an AI-powered tool that goes beyond review comments to automatically create pull requests that fix issues. You can describe a bug or feature request in a GitHub issue, and Sweep generates a PR with the implementation. For code review, it can identify problems in existing PRs and propose fixes as follow-up commits.
What it does. Sweep monitors your GitHub issues and pull requests. When triggered, it reads the codebase context, generates code changes, and opens a pull request. For code review use cases, you can:
- Tag Sweep on an existing PR to get AI-generated review feedback
- Ask Sweep to fix issues identified during manual review
- Use Sweep to automatically address linter warnings or failing tests
- Request refactoring of complex code segments
Sweep plans its changes before implementing them, showing you a step-by-step breakdown of what it intends to modify. This transparency makes it easier to evaluate whether the AI's approach is correct before it generates code.
Setup guide. Install the Sweep GitHub App from the GitHub marketplace, or self-host:
# Clone the Sweep repository
git clone https://github.com/sweepai/sweep.git
cd sweep
# Configure environment variables
cp .env.example .env
# Edit .env with your API keys
The .env file requires:
# .env
OPENAI_API_KEY=sk-your-key
GITHUB_APP_ID=your-app-id
GITHUB_APP_PEM=your-private-key
GITHUB_BOT_USERNAME=sweep-ai[bot]
ANTHROPIC_API_KEY=sk-ant-your-key # optional
Deploy with Docker:
docker-compose up -d
Configuration. Create a sweep.yaml in your repository:
# sweep.yaml
branch: main
blocked_dirs:
- node_modules
- .next
- dist
- vendor
description: "A TypeScript web application using Next.js and Prisma"
docs:
- "https://nextjs.org/docs"
- "https://www.prisma.io/docs"
draft: false
gha_enabled: true
Pros:
- Goes beyond review to actually fix issues via pull requests
- Understands codebase context through repository indexing
- Plans changes transparently before implementing
- Can be self-hosted
Cons:
- BSL 1.1 license (not fully permissive open source - transitions to Apache 2.0 after 3 years)
- Still maturing - fix quality varies on complex tasks
- More focused on code generation than pure review
- Self-hosted deployment requires meaningful infrastructure
Setup difficulty: Medium. GitHub App install is straightforward. Self-hosted deployment requires more configuration than PR-Agent due to additional dependencies.
Rule-based open source tools
These five tools use deterministic pattern matching and static analysis rather than LLMs. They produce consistent, reproducible results and do not require API keys or cloud connections. Their analysis is faster and more predictable, but they cannot catch the semantic and logic-level issues that AI tools identify.
6. Semgrep
Semgrep is a fast, open source static analysis engine that excels at custom security rule authoring. Its rules are written in a syntax that resembles the source code being analyzed, making them accessible to application developers rather than just security specialists.
What it does. Semgrep scans code against pattern-based rules that detect security vulnerabilities, bugs, and anti-patterns. Unlike traditional SAST tools with XML-based rule formats, Semgrep rules look like the code they match:
# .semgrep/custom-rules.yml
rules:
- id: hardcoded-jwt-secret
patterns:
- pattern: jwt.sign($PAYLOAD, "...")
message: >
JWT signing with a hardcoded secret. Use an environment
variable or secrets manager instead.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: "CWE-798"
owasp: "A07:2021"
- id: missing-auth-middleware
patterns:
- pattern: |
app.$METHOD($PATH, (req, res) => { ... })
- pattern-not-inside: |
app.$METHOD($PATH, authenticate, ...)
message: >
Route handler without authentication middleware.
Add the authenticate middleware before the handler.
severity: WARNING
languages: [javascript, typescript]
- id: unsafe-sql-query
patterns:
- pattern: |
$DB.query(`... ${$INPUT} ...`)
message: >
SQL query built with template literals. Use
parameterized queries to prevent SQL injection.
severity: ERROR
languages: [javascript, typescript]
metadata:
cwe: "CWE-89"
Semgrep runs at a median of 10 seconds in CI, making it one of the fastest static analysis tools available. It supports 30+ languages and ships with a community registry of thousands of rules.
Setup guide with GitHub Actions:
# .github/workflows/semgrep.yml
name: Semgrep
on:
pull_request: {}
push:
branches: [main]
jobs:
semgrep:
name: Scan
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- name: Run Semgrep
run: semgrep scan --config auto --config .semgrep/ --error --json > results.json
- name: Upload results
if: always()
uses: actions/upload-artifact@v4
with:
name: semgrep-results
path: results.json
For the full Semgrep Cloud Platform (which includes PR comments and a dashboard), use the official action:
# .github/workflows/semgrep-cloud.yml
name: Semgrep Cloud
on:
pull_request: {}
push:
branches: [main]
jobs:
semgrep:
name: Scan
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep ci
env:
SEMGREP_APP_TOKEN: ${{ secrets.SEMGREP_APP_TOKEN }}
Configuration. Create a .semgrep.yml configuration file:
# .semgrep.yml
rules:
- id: no-console-log
pattern: console.log(...)
message: "Remove console.log before merging"
severity: WARNING
languages: [javascript, typescript]
- id: no-any-type
pattern: "let $X: any"
message: "Avoid using 'any' type. Use a specific type or 'unknown'."
severity: WARNING
languages: [typescript]
Pros:
- Rules are written in source-like syntax - easy to author and understand
- Extremely fast (median 10 seconds in CI)
- 30+ language support
- Community registry with thousands of pre-built rules
- LGPL 2.1 license (open source CLI)
- Excellent for custom security rules specific to your frameworks
Cons:
- Open source CLI lacks cross-file analysis (requires paid Semgrep Supply Chain)
- No AI-powered semantic understanding
- PR comments require Semgrep Cloud Platform (free for up to 10 contributors, paid beyond that)
- Learning to write effective custom rules takes time despite the approachable syntax
Setup difficulty: Easy. CLI install and basic GitHub Actions integration takes 10 minutes. Writing custom rules takes 15-30 minutes per rule depending on complexity.
7. SonarQube Community Build
SonarQube Community Build is the industry-standard self-hosted static analysis platform. With over 5,000 rules across 30+ languages, it provides the deepest rule-based analysis available at zero licensing cost.
What it does. SonarQube performs comprehensive static analysis covering bugs, vulnerabilities, code smells, security hotspots, and technical debt. It quantifies remediation time for each issue, tracks quality trends over time, and enforces quality gates that define pass/fail thresholds for your code.
The platform maps findings to industry standards: OWASP Top 10, CWE, SANS Top 25, and PCI DSS. For regulated industries, this compliance mapping provides the audit trail that security and compliance teams require.
SonarQube also includes AI CodeFix in newer versions, providing machine learning-powered fix suggestions for detected issues.
Docker setup guide.
# Pull and run SonarQube Community
docker run -d \
--name sonarqube \
-p 9000:9000 \
-v sonarqube_data:/opt/sonarqube/data \
-v sonarqube_logs:/opt/sonarqube/logs \
-v sonarqube_extensions:/opt/sonarqube/extensions \
sonarqube:community
# Access at http://localhost:9000
# Default credentials: admin / admin
For production deployments, use Docker Compose with PostgreSQL:
# docker-compose.sonarqube.yml
version: '3.8'
services:
sonarqube:
image: sonarqube:community
depends_on:
- db
ports:
- "9000:9000"
environment:
SONAR_JDBC_URL: jdbc:postgresql://db:5432/sonarqube
SONAR_JDBC_USERNAME: sonarqube
SONAR_JDBC_PASSWORD: sonarqube_password
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
ulimits:
nofile:
soft: 65536
hard: 65536
db:
image: postgres:16
environment:
POSTGRES_USER: sonarqube
POSTGRES_PASSWORD: sonarqube_password
POSTGRES_DB: sonarqube
volumes:
- postgresql_data:/var/lib/postgresql/data
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql_data:
GitHub Actions integration:
# .github/workflows/sonarqube.yml
name: SonarQube Analysis
on:
push:
branches: [main]
pull_request:
types: [opened, synchronize, reopened]
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@v3
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
- name: SonarQube Quality Gate
uses: sonarsource/sonarqube-quality-gate-action@v1
timeout-minutes: 5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
Project configuration. Create a sonar-project.properties file:
# sonar-project.properties
sonar.projectKey=my-project
sonar.projectName=My Project
sonar.sources=src
sonar.tests=tests
sonar.language=ts
sonar.sourceEncoding=UTF-8
# Exclusions
sonar.exclusions=**/node_modules/**,**/dist/**,**/*.test.ts
sonar.coverage.exclusions=**/*.test.ts,**/*.spec.ts
# Test coverage
sonar.javascript.lcov.reportPaths=coverage/lcov.info
# Quality gate
sonar.qualitygate.wait=true
Quality gate configuration. In the SonarQube UI, define quality gates:
| Metric | Operator | Value |
|---|---|---|
| New bugs | Greater than | 0 |
| New vulnerabilities | Greater than | 0 |
| New code coverage | Less than | 80% |
| New code smells | Greater than | 10 |
| New duplicated lines | Greater than | 3% |
Pros:
- 5,000+ rules across 30+ languages - deepest rule library available for free
- Quality gates enforce minimum standards before merge
- Technical debt quantification and trend tracking
- Compliance mapping to OWASP, CWE, SANS, PCI DSS
- Completely self-hosted - total data control
- LGPL 3.0 license
Cons:
- Community Build lacks pull request decoration (comments on PRs require the paid Developer Edition)
- Community Build lacks branch analysis - only scans the main branch
- Requires self-hosting Java application + PostgreSQL database
- UI feels dated compared to modern cloud tools
- Infrastructure maintenance burden (upgrades, backups, monitoring)
Setup difficulty: Hard. Docker setup takes 30-45 minutes. Production deployment with PostgreSQL, reverse proxy, and proper security takes 2-4 hours. Ongoing maintenance requires regular attention to updates and database backups.
8. CodeQL
CodeQL is GitHub's semantic code analysis engine, open sourced under the MIT license. It treats code as data and lets you write queries in a SQL-like language to find security vulnerabilities and bugs. It is deeply integrated with GitHub's code scanning feature.
What it does. CodeQL creates a database from your source code that represents its structure as a relational model. You then write queries against this database to find patterns that indicate vulnerabilities. Unlike regex-based tools, CodeQL understands control flow, data flow, and type information, enabling it to track how tainted data flows from user input to sensitive operations across function boundaries.
CodeQL ships with thousands of pre-built queries covering common vulnerability patterns for JavaScript, TypeScript, Python, Java, C/C++, C#, Go, Ruby, Swift, and Kotlin. GitHub runs these queries automatically through code scanning on public repositories at no cost.
Setup guide with GitHub Actions:
# .github/workflows/codeql.yml
name: CodeQL Analysis
on:
push:
branches: [main]
pull_request:
branches: [main]
schedule:
- cron: '0 6 * * 1' # Weekly Monday 6am
jobs:
analyze:
name: Analyze
runs-on: ubuntu-latest
permissions:
security-events: write
actions: read
contents: read
strategy:
fail-fast: false
matrix:
language: ['javascript-typescript', 'python']
steps:
- name: Checkout repository
uses: actions/checkout@v4
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
queries: +security-extended
- name: Autobuild
uses: github/codeql-action/autobuild@v3
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
with:
category: "/language:${{ matrix.language }}"
Custom queries. Write your own CodeQL queries for organization-specific patterns:
/**
* @name API endpoint without authentication
* @description Finds Express route handlers that don't use
* authentication middleware.
* @kind problem
* @problem.severity warning
* @id js/api-without-auth
*/
from Express::RouteHandler handler, Express::RouteSetup setup
where
setup.getAHandler() = handler and
not exists(Express::RouteHandler authMiddleware |
setup.getAHandler() = authMiddleware and
authMiddleware.getAParameter().getName() = "authenticate"
)
select handler, "Route handler without authentication middleware."
Pros:
- Semantic analysis that understands code structure, not just patterns
- Data flow and taint tracking across function boundaries
- Deep integration with GitHub code scanning (free for public repos)
- MIT license for the CodeQL engine
- Thousands of pre-built security queries
- Results appear directly in GitHub Security tab
Cons:
- Limited to 10 languages (no Rust, no PHP in stable)
- Query language has a significant learning curve
- Analysis is slower than Semgrep (minutes vs. seconds)
- Full functionality requires GitHub - not ideal for GitLab or Bitbucket workflows
- Custom query development requires understanding of CodeQL's data model
Setup difficulty: Medium. Basic GitHub Actions setup takes 10-15 minutes. Writing custom queries requires investing time in learning the CodeQL query language, which has a steeper curve than Semgrep's pattern syntax.
9. Danger JS / Danger Swift
Danger is an open source tool that automates common PR review tasks by running custom rules against pull request metadata. It does not analyze code itself - instead, it checks PR attributes like file changes, description content, label presence, reviewer assignment, and CI status to enforce team conventions.
What it does. Danger runs during CI and has access to the pull request context: which files were changed, how many lines were added or removed, what the PR description says, which labels are attached, and more. You write rules in JavaScript (Danger JS), Ruby (Danger Ruby), or Swift (Danger Swift) that define your team's PR policies:
// dangerfile.js
// Warn if PR description is too short
if (danger.github.pr.body.length < 50) {
warn("Please add a more detailed PR description (at least 50 characters).");
}
// Fail if no tests were added with new source files
const hasSourceChanges = danger.git.created_files.some(f =>
f.startsWith("src/") && !f.includes(".test.")
);
const hasTestChanges = danger.git.created_files.some(f =>
f.includes(".test.") || f.includes(".spec.")
);
if (hasSourceChanges && !hasTestChanges) {
fail("New source files were added without corresponding tests.");
}
// Warn on large PRs
const bigPR = danger.github.pr.additions + danger.github.pr.deletions > 500;
if (bigPR) {
warn("This PR has more than 500 changed lines. Consider splitting it into smaller PRs.");
}
// Check that package.json changes include lockfile updates
const packageChanged = danger.git.modified_files.includes("package.json");
const lockfileChanged = danger.git.modified_files.includes("package-lock.json") ||
danger.git.modified_files.includes("yarn.lock");
if (packageChanged && !lockfileChanged) {
fail("package.json was modified but the lockfile was not updated.");
}
// Require CHANGELOG update for non-trivial changes
const isTrivial = danger.github.pr.title.includes("[trivial]");
const changelogUpdated = danger.git.modified_files.includes("CHANGELOG.md");
if (!isTrivial && !changelogUpdated) {
warn("Please update CHANGELOG.md with a summary of your changes.");
}
// Flag if sensitive files are modified
const sensitiveFiles = danger.git.modified_files.filter(f =>
f.includes(".env") || f.includes("credentials") || f.includes("secret")
);
if (sensitiveFiles.length > 0) {
fail(`Sensitive files modified: ${sensitiveFiles.join(", ")}. Ensure secrets are not committed.`);
}
GitHub Actions setup:
# .github/workflows/danger.yml
name: Danger PR Checks
on:
pull_request:
types: [opened, synchronize, reopened, edited]
jobs:
danger:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm install danger
- name: Run Danger
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: npx danger ci
Pros:
- Write PR policies in familiar languages (JS, Ruby, Swift)
- Enforces team conventions automatically (description quality, test presence, changelog updates)
- MIT license, fully open source
- Works with GitHub, GitLab, and Bitbucket
- Lightweight - no infrastructure required beyond CI
- Extensive plugin ecosystem
Cons:
- Does not analyze code quality or security - only PR metadata
- Rules are imperative code, not declarative configuration
- Each team needs to write and maintain their own rule set
- No built-in rule library comparable to Semgrep or SonarQube
Setup difficulty: Easy. npm install plus a dangerfile takes 15-20 minutes. Writing comprehensive rules takes 1-2 hours but is approachable for any JavaScript developer.
10. ReviewBot
ReviewBot is a lightweight open source tool for creating automated code review bots. It provides a framework for building custom review checks that run during CI and post comments on pull requests.
What it does. ReviewBot lets you define review checks as simple scripts that examine code changes and produce structured feedback. It bridges the gap between writing custom linter rules (which requires understanding AST tooling) and writing full Danger rules (which are imperative). ReviewBot provides a declarative configuration format for common checks while allowing custom scripts for specialized rules.
Setup guide:
# .reviewbot.yml
checks:
- name: file-size
description: "Warn about large files"
max_lines: 500
severity: warning
message: "This file exceeds 500 lines. Consider breaking it into smaller modules."
- name: todo-check
description: "Flag TODO comments without issue references"
pattern: "TODO(?!\\s*\\(#\\d+\\))"
severity: info
message: "TODO found without an issue reference. Use format: TODO(#123)"
- name: no-console
description: "Disallow console statements"
pattern: "console\\.(log|warn|error|debug)"
file_pattern: "src/**/*.{ts,js}"
severity: error
message: "Remove console statements before merging."
- name: custom-script
description: "Run custom review logic"
script: ./scripts/review-check.sh
severity: warning
GitHub Actions integration:
# .github/workflows/reviewbot.yml
name: ReviewBot
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Run ReviewBot
uses: reviewbot/action@v1
with:
config: .reviewbot.yml
github_token: ${{ secrets.GITHUB_TOKEN }}
Pros:
- Simple, declarative configuration for common checks
- Extensible with custom scripts for specialized rules
- Lightweight - no heavy infrastructure
- MIT license
- Easy to understand and maintain
Cons:
- Smaller community and ecosystem compared to Danger
- Pattern-based checks are less powerful than AST-based analysis
- Limited built-in check types
- No AI-powered analysis
Setup difficulty: Easy. YAML configuration plus GitHub Action setup takes 10-15 minutes. Custom scripts add development time but are straightforward.
Language-specific open source linters
These five tools provide deep analysis within a single language ecosystem. They understand language-specific idioms, conventions, and pitfalls better than any general-purpose tool can. For most teams, these linters form the foundation of code quality enforcement alongside a broader review tool.
11. ESLint
ESLint is the standard linting tool for JavaScript and TypeScript. With over 25,000 GitHub stars and near-universal adoption, it is the most widely used code quality tool in the JavaScript ecosystem.
What it does. ESLint statically analyzes JavaScript and TypeScript code to find problems, enforce coding standards, and catch common bugs. It supports custom rules, shareable configurations, and integrates with virtually every JavaScript tool and IDE.
Setup guide:
# Initialize ESLint in your project
npm init @eslint/config@latest
Configuration (flat config format, ESLint 9+):
// eslint.config.mjs
export default [
js.configs.recommended,
{
files: ["**/*.ts", "**/*.tsx"],
languageOptions: {
parser: tsParser,
parserOptions: {
project: "./tsconfig.json",
},
},
plugins: {
"@typescript-eslint": typescript,
},
rules: {
"@typescript-eslint/no-explicit-any": "error",
"@typescript-eslint/no-unused-vars": ["error", {
argsIgnorePattern: "^_",
}],
"@typescript-eslint/strict-boolean-expressions": "error",
"no-console": "warn",
"eqeqeq": ["error", "always"],
"no-eval": "error",
"prefer-const": "error",
"no-var": "error",
},
},
{
ignores: ["dist/", "node_modules/", "coverage/"],
},
];
GitHub Actions setup:
# .github/workflows/eslint.yml
name: ESLint
on:
pull_request:
paths:
- '**.js'
- '**.ts'
- '**.tsx'
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx eslint . --format json --output-file eslint-results.json
continue-on-error: true
- name: Annotate ESLint results
uses: ataylorme/eslint-annotate-action@v3
with:
report-json: eslint-results.json
Pros:
- Universal adoption in the JavaScript ecosystem
- Thousands of community plugins and shareable configs
- Flat config format (ESLint 9+) is cleaner and more composable
- Type-aware linting with typescript-eslint
- MIT license
Cons:
- JavaScript/TypeScript only
- Configuration can become complex in large monorepos
- Performance degrades with type-aware rules on large codebases (Ruff and Biome are faster alternatives for some checks)
Setup difficulty: Easy. npm init @eslint/config handles initial setup. Fine-tuning rules takes 30-60 minutes.
12. Ruff (Python)
Ruff is a Python linter and formatter written in Rust. It is 10-100x faster than existing Python linters (Pylint, Flake8, isort, pycodestyle combined) and has rapidly become the default Python code quality tool with over 40,000 GitHub stars.
What it does. Ruff reimplements the rules from Pylint, Flake8, isort, pyupgrade, pydocstyle, and dozens of other Python tools in a single, fast binary. It checks for bugs, enforces style, organizes imports, and can auto-fix many issues. Because it is written in Rust, it can lint an entire Python monorepo in milliseconds rather than minutes.
Setup guide:
# Install Ruff
pip install ruff
# Or via Homebrew
brew install ruff
# Lint your project
ruff check .
# Fix auto-fixable issues
ruff check --fix .
# Format code
ruff format .
Configuration:
# pyproject.toml
[tool.ruff]
target-version = "py312"
line-length = 88
[tool.ruff.lint]
select = [
"E", # pycodestyle errors
"W", # pycodestyle warnings
"F", # pyflakes
"I", # isort
"N", # pep8-naming
"UP", # pyupgrade
"S", # flake8-bandit (security)
"B", # flake8-bugbear
"A", # flake8-builtins
"C4", # flake8-comprehensions
"DTZ", # flake8-datetimez
"T20", # flake8-print
"SIM", # flake8-simplify
"TCH", # flake8-type-checking
"RUF", # Ruff-specific rules
]
ignore = [
"E501", # line too long (handled by formatter)
]
[tool.ruff.lint.per-file-ignores]
"tests/**/*.py" = ["S101"] # Allow assert in tests
"__init__.py" = ["F401"] # Allow unused imports
[tool.ruff.lint.isort]
known-first-party = ["myproject"]
GitHub Actions setup:
# .github/workflows/ruff.yml
name: Ruff
on:
pull_request:
paths:
- '**.py'
- 'pyproject.toml'
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Ruff Linting
uses: chartboost/ruff-action@v1
with:
args: check
- name: Ruff Formatting
uses: chartboost/ruff-action@v1
with:
args: format --check
Pros:
- 10-100x faster than Pylint/Flake8 combined
- Single tool replaces Pylint, Flake8, isort, pyupgrade, and more
- 800+ rules from dozens of Python linting tools
- Auto-fix support for many rules
- Built-in formatter (replaces Black)
- MIT license, 40k+ GitHub stars
Cons:
- Python only
- Some advanced Pylint rules are not yet implemented (though coverage is expanding rapidly)
- Relatively new - some edge cases may differ from established tools
Setup difficulty: Easy. pip install, add config to pyproject.toml, and run. Takes 5-10 minutes including rule selection.
13. golangci-lint
golangci-lint is a fast, configurable meta-linter for Go that runs dozens of linters in parallel. It is the standard code quality tool in the Go ecosystem with over 16,000 GitHub stars.
What it does. golangci-lint aggregates and runs 100+ individual Go linters simultaneously, deduplicates their findings, and presents unified output. Instead of installing and configuring staticcheck, govet, errcheck, gosimple, and others individually, golangci-lint provides a single binary and configuration file.
Setup guide:
# Install
brew install golangci-lint
# Or via Go install
go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
# Run linting
golangci-lint run
# Run with auto-fix
golangci-lint run --fix
Configuration:
# .golangci.yml
run:
timeout: 5m
modules-download-mode: readonly
linters:
enable:
- errcheck # Check for unchecked errors
- gosimple # Simplify code
- govet # Examine Go source code
- ineffassign # Detect ineffectual assignments
- staticcheck # Advanced Go static analysis
- unused # Check for unused code
- gocritic # Opinionated Go linter
- gosec # Security issues
- prealloc # Slice preallocation
- misspell # Find misspelled words
- revive # Extensible Go linter
- errorlint # Error wrapping issues
- exhaustive # Exhaustive enum switch
- nilerr # nil error return
- wrapcheck # Error wrapping checks
linters-settings:
gocritic:
enabled-tags:
- diagnostic
- performance
- style
revive:
rules:
- name: blank-imports
- name: context-as-argument
- name: error-return
- name: exported
- name: increment-decrement
- name: var-naming
gosec:
excludes:
- G104 # Allow unhandled errors in defers
errcheck:
check-type-assertions: true
check-blank: true
issues:
exclude-rules:
- path: _test\.go
linters:
- gosec
- gocritic
max-issues-per-linter: 50
max-same-issues: 5
GitHub Actions setup:
# .github/workflows/golangci-lint.yml
name: golangci-lint
on:
pull_request:
paths:
- '**.go'
- 'go.mod'
- 'go.sum'
- '.golangci.yml'
jobs:
golangci-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version: '1.22'
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
with:
version: latest
args: --timeout 5m
Pros:
- Runs 100+ linters in parallel with a single command
- Unified configuration for all Go linting tools
- Fast incremental analysis (only checks changed files by default)
- GPL 3.0 license
- Industry standard in Go ecosystem
Cons:
- Go only
- Configuration can be complex with many linters to choose from
- Some linters have conflicting rules that require careful selection
- Occasional false positives with aggressive linter combinations
Setup difficulty: Easy. Single binary install, YAML config file, and a GitHub Action. Takes 15-20 minutes including linter selection.
14. Clippy (Rust)
Clippy is the official Rust linter, maintained by the Rust project itself. It ships with rustup and provides over 700 lints that catch common mistakes, suggest idiomatic Rust, and flag performance issues.
What it does. Clippy analyzes Rust code and provides suggestions organized into categories: correctness (catching bugs), style (idiomatic Rust), complexity (simplifying code), performance (avoiding unnecessary allocations), and pedantic (stricter style checks). Because it uses the Rust compiler's own analysis infrastructure, it has deep understanding of ownership, lifetimes, and type system guarantees.
Setup guide:
# Clippy ships with rustup
rustup component add clippy
# Run Clippy
cargo clippy
# Run with all lints (including pedantic)
cargo clippy -- -W clippy::pedantic
# Fix auto-fixable issues
cargo clippy --fix
Configuration:
# Cargo.toml
[lints.clippy]
# Enable pedantic lints
pedantic = { level = "warn", priority = -1 }
# Individual lint overrides
module_name_repetitions = "allow"
must_use_candidate = "allow"
missing_errors_doc = "warn"
missing_panics_doc = "warn"
unwrap_used = "deny"
expect_used = "warn"
Or in a clippy.toml file:
# clippy.toml
msrv = "1.75.0"
cognitive-complexity-threshold = 25
too-many-arguments-threshold = 10
type-complexity-threshold = 350
GitHub Actions setup:
# .github/workflows/clippy.yml
name: Clippy
on:
pull_request:
paths:
- '**.rs'
- 'Cargo.toml'
- 'Cargo.lock'
jobs:
clippy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
with:
components: clippy
- name: Run Clippy
run: cargo clippy --all-targets --all-features -- -D warnings
- name: Clippy with annotations
uses: auguwu/clippy-action@1.4.0
with:
deny: warnings
all-features: true
Pros:
- Official Rust project tool - deeply integrated with the compiler
- 700+ lints covering correctness, style, performance, and complexity
- Understands Rust's ownership, lifetime, and type system
- Auto-fix support for many lints
- MIT/Apache 2.0 dual license
- Zero additional installation if you have rustup
Cons:
- Rust only
- Some pedantic lints are controversial and need per-project tuning
- Analysis time scales with compilation time (can be slow on large projects)
- Some lints produce false positives in macro-heavy code
Setup difficulty: Easy. Already installed with rustup. Adding to CI takes 5 minutes. Configuring lint levels takes 15-20 minutes.
15. RuboCop
RuboCop is the standard code quality tool for Ruby, providing static analysis and formatting for Ruby codebases. With over 13,000 GitHub stars, it is the near-universal linting tool in the Ruby ecosystem.
What it does. RuboCop analyzes Ruby code against a comprehensive set of rules organized into departments: Layout (formatting), Lint (suspicious code), Metrics (complexity), Naming (naming conventions), Security (vulnerability patterns), and Style (Ruby idioms). It also supports auto-correction for the majority of its rules.
Extensions like rubocop-rails, rubocop-rspec, and rubocop-performance add specialized rules for Rails applications, RSpec tests, and performance-sensitive code.
Setup guide:
# Install RuboCop
gem install rubocop
# Or add to Gemfile
# gem 'rubocop', require: false
# gem 'rubocop-rails', require: false
# gem 'rubocop-rspec', require: false
# gem 'rubocop-performance', require: false
# Initialize configuration
rubocop --init
# Run RuboCop
rubocop
# Auto-correct fixable offenses
rubocop --autocorrect
Configuration:
# .rubocop.yml
require:
- rubocop-rails
- rubocop-rspec
- rubocop-performance
AllCops:
TargetRubyVersion: 3.3
NewCops: enable
Exclude:
- 'db/schema.rb'
- 'bin/**/*'
- 'vendor/**/*'
- 'node_modules/**/*'
# Layout
Layout/LineLength:
Max: 120
AllowedPatterns: ['^\s*#']
# Metrics
Metrics/MethodLength:
Max: 20
CountAsOne:
- array
- hash
- heredoc
Metrics/ClassLength:
Max: 200
Metrics/AbcSize:
Max: 20
# Style
Style/Documentation:
Enabled: false
Style/FrozenStringLiteralComment:
Enabled: true
EnforcedStyle: always
Style/StringLiterals:
EnforcedStyle: double_quotes
# Rails
Rails/SkipsModelValidations:
Enabled: true
Rails/Output:
Enabled: true
# RSpec
RSpec/ExampleLength:
Max: 15
RSpec/NestedGroups:
Max: 4
# Security
Security/Eval:
Enabled: true
Security/YAMLLoad:
Enabled: true
GitHub Actions setup:
# .github/workflows/rubocop.yml
name: RuboCop
on:
pull_request:
paths:
- '**.rb'
- '.rubocop.yml'
- 'Gemfile'
jobs:
rubocop:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.3'
bundler-cache: true
- name: Run RuboCop
run: bundle exec rubocop --format json --out rubocop-results.json --format progress
continue-on-error: true
- name: Annotate RuboCop results
uses: reviewdog/action-rubocop@v2
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
reporter: github-pr-review
Pros:
- Comprehensive Ruby analysis covering style, bugs, security, and complexity
- Auto-correction for most rules
- Excellent Rails, RSpec, and performance extensions
- MIT license
- Near-universal adoption in Ruby projects
Cons:
- Ruby only
- Default configuration is opinionated - most teams need to customize significantly
- Can be slow on very large Ruby codebases
- Some rules are controversial in the Ruby community (frozen string literals, method length limits)
Setup difficulty: Easy. gem install rubocop plus configuration file. Initial setup takes 10 minutes. Tuning rules to your team's preferences takes 30-60 minutes.
Setup difficulty ratings
| Tool | Time to First Review | Prerequisites | Ongoing Maintenance | Difficulty Rating |
|---|---|---|---|---|
| PR-Agent (GitHub Actions) | 10 minutes | OpenAI API key, GitHub secrets | Low - update action version | Medium |
| PR-Agent (self-hosted) | 45-60 minutes | Docker, GitHub App, API keys | Medium - server monitoring | Medium-Hard |
| Aider | 5 minutes | pip, API key | None | Easy |
| Continue | 5 minutes | VS Code or JetBrains, API key | None | Easy |
| Cody (IDE) | 10 minutes | VS Code or JetBrains, Sourcegraph account | None | Easy |
| Cody (self-hosted) | 1-2 hours | Docker, 8GB+ RAM, API keys | High - Sourcegraph instance | Hard |
| Sweep AI | 20-30 minutes | GitHub App, API keys | Low | Medium |
| Semgrep (CLI) | 5 minutes | pip or Docker | Low - update rules | Easy |
| Semgrep (Cloud) | 10 minutes | Semgrep account, API token | Low | Easy |
| SonarQube | 2-4 hours | Docker, PostgreSQL, JDK | High - database backups, upgrades | Hard |
| CodeQL | 15 minutes | GitHub repository | Low - update action version | Medium |
| Danger JS | 15-20 minutes | Node.js, dangerfile | Low - update rules as needed | Easy |
| ReviewBot | 10-15 minutes | GitHub Actions | Low | Easy |
| ESLint | 10 minutes | Node.js | Low - update configs | Easy |
| Ruff | 5 minutes | pip | None | Easy |
| golangci-lint | 15 minutes | Go toolchain | Low | Easy |
| Clippy | 5 minutes | rustup | None | Easy |
| RuboCop | 10 minutes | Ruby, Bundler | Low - update gem | Easy |
Self-hosting guide
For teams with strict data privacy requirements, self-hosting is the only viable option. Here is a complete Docker Compose setup that deploys PR-Agent and SonarQube together, giving you both AI-powered PR review and rule-based static analysis under your own control.
Combined Docker Compose deployment
# docker-compose.yml
# Self-hosted code review stack: PR-Agent + SonarQube
version: '3.8'
services:
# ─────────────────────────────────────
# PR-Agent: AI-powered PR review
# ─────────────────────────────────────
pr-agent:
image: codiumai/pr-agent:latest
container_name: pr-agent
restart: unless-stopped
ports:
- "3000:3000"
environment:
# LLM Configuration
OPENAI.KEY: "${OPENAI_API_KEY}"
# Or use Anthropic:
# ANTHROPIC.KEY: "${ANTHROPIC_API_KEY}"
# config.model: "anthropic/claude-sonnet-4-20250514"
# GitHub App Configuration
GITHUB.APP_ID: "${GITHUB_APP_ID}"
GITHUB.WEBHOOK_SECRET: "${GITHUB_WEBHOOK_SECRET}"
GITHUB.PRIVATE_KEY_PATH: /keys/private-key.pem
# Review Configuration
PR_REVIEWER.REQUIRE_TESTS_REVIEW: "true"
PR_REVIEWER.REQUIRE_SECURITY_REVIEW: "true"
PR_REVIEWER.NUM_CODE_SUGGESTIONS: "4"
PR_REVIEWER.INLINE_CODE_COMMENTS: "true"
# Auto-run on PR open
GITHUB_ACTION_CONFIG.AUTO_REVIEW: "true"
GITHUB_ACTION_CONFIG.AUTO_DESCRIBE: "true"
GITHUB_ACTION_CONFIG.AUTO_IMPROVE: "true"
volumes:
- ./keys:/keys:ro
networks:
- review-network
# ─────────────────────────────────────
# SonarQube: Rule-based static analysis
# ─────────────────────────────────────
sonarqube:
image: sonarqube:community
container_name: sonarqube
restart: unless-stopped
depends_on:
- sonarqube-db
ports:
- "9000:9000"
environment:
SONAR_JDBC_URL: jdbc:postgresql://sonarqube-db:5432/sonarqube
SONAR_JDBC_USERNAME: sonarqube
SONAR_JDBC_PASSWORD: "${SONAR_DB_PASSWORD}"
SONAR_ES_BOOTSTRAP_CHECKS_DISABLE: "true"
volumes:
- sonarqube_data:/opt/sonarqube/data
- sonarqube_extensions:/opt/sonarqube/extensions
- sonarqube_logs:/opt/sonarqube/logs
ulimits:
nofile:
soft: 131072
hard: 131072
nproc:
soft: 8192
hard: 8192
networks:
- review-network
# ─────────────────────────────────────
# PostgreSQL for SonarQube
# ─────────────────────────────────────
sonarqube-db:
image: postgres:16-alpine
container_name: sonarqube-db
restart: unless-stopped
environment:
POSTGRES_USER: sonarqube
POSTGRES_PASSWORD: "${SONAR_DB_PASSWORD}"
POSTGRES_DB: sonarqube
volumes:
- postgresql_data:/var/lib/postgresql/data
networks:
- review-network
networks:
review-network:
driver: bridge
volumes:
sonarqube_data:
sonarqube_extensions:
sonarqube_logs:
postgresql_data:
Create a .env file for secrets:
# .env (do NOT commit this file)
OPENAI_API_KEY=sk-your-openai-key
GITHUB_APP_ID=123456
GITHUB_WEBHOOK_SECRET=your-webhook-secret
SONAR_DB_PASSWORD=a-strong-database-password
Deploy the stack:
# Set the required sysctl for Elasticsearch (SonarQube requirement)
sudo sysctl -w vm.max_map_count=524288
# Start everything
docker-compose up -d
# Check health
docker-compose ps
docker-compose logs -f pr-agent
docker-compose logs -f sonarqube
Post-deployment setup
SonarQube initial configuration:
- Access SonarQube at
http://your-server:9000 - Log in with default credentials (
admin/admin) and change the password immediately - Create a project and generate a project token
- Add the token as a CI secret (
SONAR_TOKEN) - Add the SonarQube URL as a CI secret (
SONAR_HOST_URL)
PR-Agent GitHub App setup:
- Create a new GitHub App in your organization settings
- Set the webhook URL to
http://your-server:3000/api/v1/github_webhooks - Grant permissions: Pull requests (read/write), Issues (read/write), Contents (read)
- Subscribe to events: Pull request, Issue comment, Push
- Generate and download the private key
- Place the private key at
./keys/private-key.pem
Combined CI pipeline:
# .github/workflows/code-review.yml
name: Code Review Pipeline
on:
pull_request:
types: [opened, synchronize, reopened]
push:
branches: [main]
jobs:
# AI-powered review via PR-Agent
ai-review:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: PR-Agent Review
uses: Codium-ai/pr-agent@main
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github_action_config.auto_review: "true"
github_action_config.auto_describe: "true"
github_action_config.auto_improve: "true"
# Rule-based analysis via SonarQube
static-analysis:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@v3
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
# Security scanning via Semgrep
security-scan:
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep scan --config auto --error
Decision framework
Choosing the right combination of tools depends on your team's size, data privacy requirements, primary languages, and budget. Here is a structured framework to guide the decision.
By team size
Solo developer or side project:
- Ruff or ESLint (language-specific linting)
- Continue or Aider (on-demand AI review from your editor or terminal)
- Total cost: $0 (bring your own LLM API key, approximately $5/month)
Small team (2-10 developers):
- PR-Agent via GitHub Actions (automated AI PR review)
- Semgrep CLI (security scanning)
- Language-specific linter (ESLint, Ruff, golangci-lint, Clippy, or RuboCop)
- Danger JS (PR policy enforcement)
- Total cost: $5-30/month for LLM API usage
Medium team (10-50 developers):
- PR-Agent self-hosted (AI review with data control)
- SonarQube Community (quality gates, compliance tracking)
- Semgrep with custom rules (security scanning)
- Language-specific linters
- Danger JS (PR policy enforcement)
- Total cost: $20-100/month for LLM API usage plus server infrastructure
Large team (50+ developers):
- Consider commercial tools (Qodo Merge, CodeRabbit Pro) for support SLAs
- SonarQube Developer or Enterprise for PR decoration and branch analysis
- Semgrep with full rule library
- CodeQL for deep security analysis
- Language-specific linters
- Total cost: Varies significantly - commercial licenses may be more cost-effective than self-hosted infrastructure at scale
By data privacy requirements
Standard (code can leave your network):
- Any tool on this list works
- Cloud-hosted options (Semgrep Cloud, CodeRabbit free tier) are the simplest
- LLM APIs (OpenAI, Anthropic) process your diffs but do not store them
Elevated (prefer data stays internal):
- PR-Agent self-hosted with cloud LLM APIs (diffs sent to API but not stored)
- SonarQube self-hosted (no external connections)
- Semgrep CLI (runs entirely locally)
- Language-specific linters (run entirely locally)
Strict (no code leaves your infrastructure):
- PR-Agent self-hosted with local LLM (Ollama, vLLM, or similar)
- SonarQube self-hosted
- Semgrep CLI
- Language-specific linters
- No cloud LLM APIs - all processing happens on your hardware
- Trade-off: Local models (CodeLlama, DeepSeek Coder) produce lower quality reviews than GPT-4o or Claude
Air-gapped (no internet access):
- SonarQube self-hosted (download container images offline)
- Semgrep CLI with pre-downloaded rules
- Language-specific linters (install from internal package mirrors)
- PR-Agent with Ollama running a local model
- Most restrictive option - requires careful planning for updates and rule refreshes
By primary language
| Primary Language | Recommended Linter | Recommended Security Tool | AI Review |
|---|---|---|---|
| JavaScript/TypeScript | ESLint | Semgrep, CodeQL | PR-Agent |
| Python | Ruff | Semgrep (bandit rules), CodeQL | PR-Agent |
| Go | golangci-lint | Semgrep, gosec (via golangci-lint) | PR-Agent |
| Rust | Clippy | cargo-audit, Semgrep | PR-Agent |
| Ruby | RuboCop | Semgrep (Ruby rules), Brakeman | PR-Agent |
| Java | SonarQube, Checkstyle | SonarQube, CodeQL, Semgrep | PR-Agent |
| C/C++ | SonarQube, cppcheck | CodeQL, Semgrep | PR-Agent |
| Multi-language | SonarQube | Semgrep, CodeQL | PR-Agent |
By budget
Truly free ($0/month):
- Semgrep CLI (open source, no API costs)
- SonarQube Community (self-hosted, no license fee - but infrastructure costs apply)
- Language-specific linters (ESLint, Ruff, golangci-lint, Clippy, RuboCop)
- Danger JS (open source)
- CodeQL on GitHub public repos
- Trade-off: No AI-powered review at zero cost (LLM APIs always have usage fees)
Low budget ($5-30/month):
- All free tools above, plus:
- PR-Agent via GitHub Actions with your own OpenAI or Anthropic API key
- Aider or Continue with pay-per-use LLM API
- Actual spend depends on PR volume - teams opening 20-50 PRs/month typically spend $10-20 on API calls
Moderate budget ($50-200/month):
- All tools above, plus:
- PR-Agent self-hosted on a small VM ($10-20/month)
- SonarQube on a dedicated server ($20-40/month for a small instance)
- Semgrep Cloud free tier (up to 10 contributors)
- Higher-quality LLM models (GPT-4o, Claude Sonnet) for better review output
Enterprise budget:
- Commercial Qodo Merge or CodeRabbit Pro for support SLAs and compliance
- SonarQube Developer or Enterprise Edition
- Semgrep paid tier for cross-file analysis and supply chain scanning
- Dedicated infrastructure for self-hosted components
Recommended open source stack
For most teams, the highest-value open source code review stack combines three layers:
Layer 1: AI-powered PR review. PR-Agent via GitHub Actions provides automated AI feedback on every pull request. Configure it with GPT-4o or Claude Sonnet for the best review quality. This catches logic errors, security issues, and improvement opportunities that rule-based tools miss.
Layer 2: Rule-based security scanning. Semgrep CLI with the auto config (community rules) plus any custom rules specific to your frameworks. This provides consistent, deterministic security checks that complement the AI layer.
Layer 3: Language-specific linting. ESLint for JavaScript/TypeScript, Ruff for Python, golangci-lint for Go, Clippy for Rust, or RuboCop for Ruby. These tools understand language-specific idioms and catch issues that neither AI nor general security scanners can identify.
Here is a GitHub Actions workflow that runs all three layers:
# .github/workflows/review-stack.yml
name: Code Review Stack
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
ai-review:
name: AI Review (PR-Agent)
runs-on: ubuntu-latest
permissions:
pull-requests: write
contents: write
steps:
- uses: actions/checkout@v4
- uses: Codium-ai/pr-agent@main
env:
OPENAI_KEY: ${{ secrets.OPENAI_KEY }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
github_action_config.auto_review: "true"
github_action_config.auto_describe: "true"
github_action_config.auto_improve: "true"
security:
name: Security Scan (Semgrep)
runs-on: ubuntu-latest
container:
image: semgrep/semgrep
steps:
- uses: actions/checkout@v4
- run: semgrep scan --config auto --error --json > semgrep-results.json
- uses: actions/upload-artifact@v4
if: always()
with:
name: semgrep-results
path: semgrep-results.json
lint-typescript:
name: Lint (ESLint)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
cache: npm
- run: npm ci
- run: npx eslint . --max-warnings 0
lint-python:
name: Lint (Ruff)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: chartboost/ruff-action@v1
with:
args: check
pr-checks:
name: PR Policy (Danger)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm install danger
- run: npx danger ci
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
This stack provides comprehensive coverage: AI catches semantic issues, Semgrep catches security patterns, language linters catch idiom violations, and Danger enforces PR policies. The entire setup runs in parallel, adding only 2-5 minutes to your CI pipeline, and the total cost is limited to LLM API usage (typically $10-30/month for a small team).
Wrapping up
The open source code review ecosystem in 2026 is mature enough that no team needs to choose between data privacy and review quality. PR-Agent brings AI-powered review to any codebase with full self-hosting support. Semgrep provides lightning-fast security scanning with an approachable rule format. SonarQube delivers enterprise-grade quality gates at zero licensing cost. And language-specific linters like ESLint, Ruff, golangci-lint, Clippy, and RuboCop provide the deepest analysis within their respective ecosystems.
The key insight is that these tools are complementary, not competing. The strongest code review setup combines AI-powered review for semantic understanding, rule-based scanning for deterministic security checks, and language-specific linting for idiomatic code quality. Each layer catches issues the others miss.
Start with the stack that matches your team size and privacy requirements. A solo developer can get meaningful code review from Aider and a language linter in under 10 minutes. A team of 50 can deploy a full self-hosted stack with PR-Agent, SonarQube, and Semgrep in an afternoon. The tools are ready - the only question is which combination fits your workflow.
Frequently Asked Questions
What is the best open source AI code review tool?
PR-Agent (by Qodo) is the best open source AI code review tool. It provides AI-powered PR review, description generation, and improvement suggestions. It supports GitHub, GitLab, and Bitbucket, and can be self-hosted with your own LLM API keys.
Are there free AI code review tools?
Yes. PR-Agent is fully open source. CodeRabbit offers a free tier for unlimited repos. Semgrep is free for up to 10 contributors. SonarQube Community is free for self-hosted use. Danger JS and ReviewBot are free open source tools for automated review checks.
Can I self-host an AI code review tool?
Yes. PR-Agent can be self-hosted with Docker and your own LLM API keys (OpenAI, Anthropic, or local models). SonarQube is designed for self-hosting. Semgrep CLI is open source and can run anywhere. For teams with data privacy requirements, self-hosting is the recommended approach.
How do I set up open source code review in GitHub Actions?
Most open source tools provide GitHub Action definitions. For PR-Agent: use the qodo-ai/pr-agent action with your OpenAI API key as a secret. For Semgrep: use returntocorp/semgrep-action. For SonarQube: use sonarsource/sonarqube-scan-action with your SonarQube server URL.
Originally published at aicodereview.cc



Top comments (0)