Nark vs SonarQube: Code Quality Metrics vs Runtime Error Checking for TypeScript
By Nark Team
SonarQube and Nark check different dimensions of TypeScript code quality. SonarQube measures code health metrics: cyclomatic complexity, code duplication, test coverage, maintainability ratings, and security hotspots. Nark checks whether your code handles the specific runtime errors that your npm dependencies throw. SonarQube tells you your code is complex. Nark tells you your code will crash when axios.get() returns a 503.
Quick Answer: SonarQube is a code quality platform that tracks metrics, technical debt, and security hotspots across your codebase. Nark is a completeness checker that verifies you handle the runtime errors your npm packages throw (axios, Prisma, Stripe, etc.). They solve different problems. Run both: SonarQube for code health dashboards, Nark for error handling verification:
npx nark --tsconfig ./tsconfig.json
What Does SonarQube Check?
SonarQube is a code quality and security platform. It analyzes your source code against a library of rules and produces dashboards with metrics, trends, and quality gates.
What SonarQube catches:
- Code smells: long methods, deep nesting, high cyclomatic complexity
- Duplicated code blocks
- Security vulnerabilities: SQL injection, XSS, path traversal (via taint analysis)
- Security hotspots: code that needs manual security review
- Bug patterns: null dereferences, resource leaks, dead code
- Maintainability issues: missing documentation, confusing naming
- Test coverage tracking (when integrated with coverage reports)
What SonarQube does not catch:
- Whether
axios.get()is wrapped in a try-catch - Whether your Prisma query handles
P2002on duplicate records - Whether your Stripe integration catches
StripeCardError - Whether your Redis client registers
.on('error') - Any package-specific runtime error handling
SonarQube's rules are language-level. They know TypeScript syntax and common anti-patterns. They do not know what individual npm packages throw at runtime.
What Does Nark Check?
Nark is a Nark Profile scanner for TypeScript. It checks your code against a library of 160+ profiles — covering axios, prisma, stripe, redis, and more — that specify what npm packages throw at runtime and what handling your code needs.
What Nark catches:
axios.get()without try-catch (throwsAxiosErroron 4xx, 5xx, network failures)prisma.user.create()without catchingPrismaClientKnownRequestErrorP2002stripe.charges.create()without catchingStripeCardErrorredis.get()without.on('error')handler registrationopenai.chat.completions.create()without handlingRateLimitError
What Nark does not check:
- Cyclomatic complexity
- Code duplication
- Test coverage
- Security vulnerabilities like SQL injection
- Code smells or maintainability ratings
Nark answers one question: "For every npm package call in your code, did you handle the errors it can throw?" It does not measure code health, track technical debt, or produce dashboards.
Side-by-Side Comparison
| Capability | SonarQube | Nark |
|---|---|---|
| Code complexity metrics | Yes | No |
| Code duplication detection | Yes | No |
| Test coverage tracking | Yes | No |
| Security vulnerability detection | Yes (taint analysis) | No |
| Security hotspot review | Yes | No |
| Quality gates (pass/fail thresholds) | Yes | Yes |
| Knows what axios throws | No | Yes |
| Knows what Prisma throws | No | Yes |
| Knows what Stripe throws | No | Yes |
| Profiles for 160+ npm packages | No | Yes |
| Dashboard and trend tracking | Yes | No (CI output only) |
| Self-hosted option | Yes | Yes (CLI) |
| Cloud option | Yes (SonarCloud) | Yes (nark.sh) |
| Free for open source | Yes | Yes |
| TypeScript support | Yes | Yes |
The Gap SonarQube Misses
SonarQube's TypeScript analyzer includes hundreds of rules. None of them check package-specific error handling. Here is code that passes SonarQube with zero issues:
import axios from 'axios';
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
async function chargeAndNotify(userId: string, amount: number) {
const charge = await stripe.charges.create({
amount,
currency: 'usd',
source: 'tok_visa',
});
await axios.post('https://notifications.example.com/webhook', {
event: 'charge_created',
chargeId: charge.id,
userId,
});
return charge;
}
SonarQube says: no code smells, no security issues, no bugs detected. Quality gate passed.
Nark says:
ERROR stripe stripe.charges.create() without StripeCardError handling
src/billing.ts:7 in chargeAndNotify()
Stripe throws StripeCardError when card is declined
ERROR axios axios.post() called without try-catch
src/billing.ts:13 in chargeAndNotify()
axios throws AxiosError on 4xx/5xx/network error
Two production crashes hiding in code that passes SonarQube's quality gate. A declined card throws StripeCardError. A notification service outage throws AxiosError. Neither is handled.
Why SonarQube Cannot Detect These Issues
SonarQube's rules are structural. They analyze code patterns at the language level:
- "This method has cyclomatic complexity > 15" (structural)
- "This code block is duplicated in 3 places" (structural)
- "This variable is used before assignment" (data flow)
- "This string is concatenated into a SQL query" (taint analysis)
None of these rules encode knowledge about specific npm packages. SonarQube does not know that:
axios.get()throwsAxiosErrorwith a.responseproperty that may beundefinedprisma.user.create()throwsPrismaClientKnownRequestErrorwith error codeP2002stripe.charges.create()throwsStripeCardErrordistinct fromStripeRateLimitErrorjsonwebtoken.verify()throwsJsonWebTokenError,TokenExpiredError, andNotBeforeError
This knowledge comes from package documentation, changelogs, and GitHub issues. Nark's profile corpus encodes this knowledge as machine-readable YAML. SonarQube has no equivalent data source.
When to Use SonarQube
SonarQube is the right tool when you need:
- Code health dashboards for engineering leadership
- Technical debt tracking across sprints and releases
- Quality gates that block PRs based on coverage, duplication, or complexity thresholds
- Security scanning with taint analysis for injection vulnerabilities
- Regulatory compliance (SOC 2, ISO 27001 audits often reference SonarQube reports)
- Multi-language support across a polyglot codebase
SonarQube is a platform. It tracks trends over time, assigns issues to developers, and integrates with project management tools.
When to Use Nark
Nark is the right tool when you need:
- Runtime error verification for npm package calls
- CI-level checks that fail when a new
axios.get()call ships without error handling - Package-specific knowledge about what 160+ npm libraries throw
- Zero-config scanning that runs with
npx nark --tsconfig ./tsconfig.json - Diff-aware scanning that only reports violations introduced in the current PR
Nark is a scanner. It runs, reports violations, and exits. It does not track trends, manage dashboards, or assign issues.
Running Both in CI
# .github/workflows/quality.yml
name: Code Quality
on: [pull_request]
jobs:
sonarqube:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: SonarQube Scan
uses: SonarSource/sonarqube-scan-action@v5
env:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
nark:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- run: npm ci
- name: Nark — runtime error handling
run: npx nark --tsconfig tsconfig.json
SonarQube checks code health. Nark checks error handling completeness. Both run in parallel. A failure in either blocks the PR.
Frequently Asked Questions
Is Nark an alternative to SonarQube?
No. They measure different things. SonarQube tracks code quality metrics (complexity, duplication, coverage). Nark checks runtime error handling for npm packages. You would not replace one with the other any more than you would replace a smoke detector with a thermometer.
Does SonarQube catch missing try-catch?
SonarQube has a rule for empty catch blocks and a rule for catching overly broad exception types. It does not have rules that check whether specific npm package calls are wrapped in try-catch, or whether the catch block handles the correct error type for that package.
Can SonarQube custom rules replace Nark?
In theory, you could write custom SonarQube rules for each npm package. In practice, this requires building and maintaining a SonarQube plugin (Java) that encodes the same knowledge Nark's YAML profiles contain. Nark ships 160+ profiles — including axios, prisma, stripe, and redis — out of the box.
Does Nark produce dashboards?
The Nark CLI produces scan results in the terminal and as JSON/SARIF. The Nark SaaS (nark.sh) provides a dashboard with scan history, violation trends, and repository-level tracking. But Nark does not track cyclomatic complexity, duplication, or test coverage.
Which should I set up first?
If you have neither: start with Nark (npx nark --tsconfig ./tsconfig.json takes 30 seconds). It finds production-crash-level bugs immediately. Add SonarQube when you need code health dashboards and trend tracking for your team.
Does SonarCloud work with Nark?
Yes. SonarCloud (the hosted version of SonarQube) and Nark run independently in CI. There is no conflict. SonarCloud reports to its dashboard. Nark reports to the terminal, JSON output, or SARIF annotations on the PR.
Try It Now
npx nark --tsconfig ./tsconfig.json
Nark checks 160+ packages — including axios, prisma, stripe, and redis — for correct error handling, resource cleanup, and runtime Nark Profiles. Pair it with SonarQube in your CI pipeline to cover both code health metrics and runtime error handling verification.