Join our Newsletter — 33% off our NHI Course

What is the difference between ESLint and Semgrep in CI/CD enforcement?

ESLint and Semgrep can both run in CI/CD, but they differ in how much orchestration they provide. ESLint is commonly inserted as a CLI check and has broad editor support, while Semgrep’s GitHub Action can scan changed files or full repositories, post PR comments, block or pass builds, and upload findings to security review workflows.

Why This Matters for Security Teams

CI/CD enforcement is where code quality checks become policy, so the practical difference between ESLint and Semgrep is not just what they detect, but how much control they exert over the delivery path. ESLint is mainly a JavaScript and TypeScript linting tool that fits naturally into developer feedback loops. Semgrep is broader in pipeline behavior, with built-in options for repository scanning, pull request feedback, and build gating. That makes Semgrep easier to use as a policy enforcement layer across multiple stages of delivery.

For teams handling source code at scale, the distinction matters because the control objective changes. ESLint is strongest when the goal is to standardise syntax, style, and common code-quality checks before merge. Semgrep is stronger when the goal is to enforce security rules, detect risky patterns across languages, and route findings into review workflows without depending on a developer to notice them locally. In practice, many teams discover the gap only after they need a pipeline decision, not after they have chosen a linter.

How It Works in Practice

In CI/CD, ESLint usually behaves like a deterministic gate: install dependencies, run the linter, and fail the job if rule violations exceed the configured threshold. That works well when the policy is narrowly scoped and the codebase is mostly JavaScript or TypeScript. The result is fast feedback, low orchestration overhead, and a clear developer experience.

Semgrep is closer to a programmable enforcement layer. It can run on changed files or the full repository, surface findings as pull request comments, and route results into security review or triage workflows. That makes it useful when teams want the pipeline to do more than block a build. It can support staged adoption, where low-severity findings are observed first and later promoted to blocking rules once the team trusts the signal.

Common operational differences include:

  • ESLint is usually language-centric and developer-centric; Semgrep is policy-centric and workflow-centric.
  • ESLint is often used to prevent bad code from entering a branch; Semgrep is often used to enforce security patterns before release.
  • ESLint typically fails fast on defined lint violations; Semgrep can be tuned to comment, alert, or block depending on rule severity.
  • Semgrep’s broader reach makes it better suited to cross-language or security-rule enforcement, while ESLint is better when the governance scope is JavaScript hygiene and style.

That difference becomes important when teams need the pipeline to reflect a security standard rather than just a coding convention. If the rule set must evolve with security review, Semgrep usually offers more room to encode that process. These controls tend to break down when organisations expect a linter to replace security review for business-critical code paths, because rule coverage and exception handling become the real constraint.

Common Variations and Edge Cases

Tighter pipeline enforcement often increases developer friction, so organisations have to balance blocking power against false positives and release velocity. The right choice depends on whether the main objective is code quality consistency or security policy enforcement.

Some teams run both tools together. In that model, ESLint handles language-specific correctness and style, while Semgrep enforces higher-level security checks. That separation is useful when teams want to keep ordinary lint failures from being mixed with security findings, especially in large repositories where ownership and triage need to stay clear.

A common edge case is partial adoption. Semgrep can scan only changed files, which reduces noise and speeds up feedback, but it may miss risks in untouched code paths. Full-repository scans are broader but slower and often more appropriate for scheduled assurance runs. Another edge case is custom rule maintenance: if a Semgrep rule set becomes too broad or vague, teams often end up with alert fatigue and start bypassing the control.

Current guidance suggests using ESLint for local and pre-merge code hygiene, and using Semgrep when the enforcement goal includes security patterns, workflow integration, or cross-language coverage. If the pipeline must make a release decision based on security policy, Semgrep is usually the more flexible control.

Risk and Threat Considerations

The main risk difference is control scope. ESLint reduces defects in JavaScript and TypeScript code, but it does not by itself provide broad security enforcement across repositories, languages, or workflow stages. Semgrep introduces broader policy coverage, but that also means the quality of the gate depends heavily on rule precision, exception handling, and triage discipline.

Failure mechanism: Teams either over-trust lint-only checks and miss security-relevant patterns, or they over-block with noisy rules and create pressure to bypass the pipeline. In the second case, enforcement weakens because developers learn to route around the control or ignore its output.

Impact: The practical consequence is inconsistent release gating, slower remediation, and a false sense of coverage when security issues are only being caught by informal review. Where code delivery is fast and repositories are large, weak rule governance quickly turns a pipeline control into a notification mechanism.

Standards & Framework Alignment

This section maps relevant standards and security frameworks to the operational risks and controls described in this guidance.

CIS Controls v8 and NIST CSF 2.0 set the governance and control requirements practitioners need to meet.

Framework Control / Reference Relevance
CIS Controls v8 CIS 16 — Application Software Security CI/CD enforcement governs software checks before release.
Recommendation — Embed automated code and security checks into the build pipeline.
NIST CSF 2.0 PR.IP-1 — Baseline Configuration and Change Management CI/CD gating is part of controlled change and release management.
PR.DS-7 — Integrity Checking Mechanisms Pipeline scans help verify code integrity and detect risky patterns.
Recommendation — Require automated checks as part of controlled software changes. Apply integrity checks to detect unsafe code before release.

Practitioner Guidance

What to prioritise: Use ESLint when you need fast, language-specific quality enforcement; use Semgrep when the requirement is to encode security policy into the pipeline. If the team cannot clearly state what should fail the build, start with non-blocking Semgrep findings and tighten only after triage quality is stable.

What to verify: Confirm whether the control is meant to prevent developer mistakes, enforce security standards, or both. That decision changes the rule design, the severity thresholds, and whether the tool should comment, alert, or block. Also verify who owns rule maintenance, because stale rules are a common reason enforcement degrades over time.

Practitioner takeaway: Treat ESLint as a code-quality gate and Semgrep as a policy-enforcement layer, then decide deliberately how much release authority each one should have.