RepoPilotOpen in app →

projectdiscovery/nuclei

Nuclei is a fast, customizable vulnerability scanner powered by the global security community and built on a simple YAML-based DSL, enabling collaboration to tackle trending vulnerabilities on the internet. It helps you find vulnerabilities in your applications, APIs, networks, DNS, and cloud configurations.

Healthy

Healthy across the board

Use as dependencyHealthy

Permissive license, no critical CVEs, actively maintained — safe to depend on.

Fork & modifyHealthy

Has a license, tests, and CI — clean foundation to fork and modify.

Learn fromHealthy

Documented and popular — useful reference codebase to read through.

Deploy as-isHealthy

No critical CVEs, sane security posture — runnable as-is.

  • Last commit 1d ago
  • 16 active contributors
  • Distributed ownership (top contributor 36% of recent commits)
Show 3 more →
  • MIT licensed
  • CI configured
  • Tests present

Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/projectdiscovery/nuclei)](https://repopilot.app/r/projectdiscovery/nuclei)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card (1200×630)

This card auto-renders when someone shares https://repopilot.app/r/projectdiscovery/nuclei on X, Slack, or LinkedIn.

Onboarding doc

Onboarding: projectdiscovery/nuclei

Generated by RepoPilot · 2026-05-09 · Source

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/projectdiscovery/nuclei shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

🎯Verdict

GO — Healthy across the board

  • Last commit 1d ago
  • 16 active contributors
  • Distributed ownership (top contributor 36% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live projectdiscovery/nuclei repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/projectdiscovery/nuclei.

What it runs against: a local clone of projectdiscovery/nuclei — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in projectdiscovery/nuclei | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch dev exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 31 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>projectdiscovery/nuclei</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of projectdiscovery/nuclei. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/projectdiscovery/nuclei.git
#   cd nuclei
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of projectdiscovery/nuclei and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "projectdiscovery/nuclei(\\.git)?\\b" \\
  && ok "origin remote is projectdiscovery/nuclei" \\
  || miss "origin remote is not projectdiscovery/nuclei (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify dev >/dev/null 2>&1 \\
  && ok "default branch dev exists" \\
  || miss "default branch dev no longer exists"

# 4. Critical files exist
test -f "cmd/nuclei/main.go" \\
  && ok "cmd/nuclei/main.go" \\
  || miss "missing critical file: cmd/nuclei/main.go"
test -f "internal/runner/inputs.go" \\
  && ok "internal/runner/inputs.go" \\
  || miss "missing critical file: internal/runner/inputs.go"
test -f "go.mod" \\
  && ok "go.mod" \\
  || miss "missing critical file: go.mod"
test -f "DESIGN.md" \\
  && ok "DESIGN.md" \\
  || miss "missing critical file: DESIGN.md"
test -f "SYNTAX-REFERENCE.md" \\
  && ok "SYNTAX-REFERENCE.md" \\
  || miss "missing critical file: SYNTAX-REFERENCE.md"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 31 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~1d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/projectdiscovery/nuclei"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

TL;DR

Nuclei is a fast, customizable vulnerability scanner written in Go that uses simple YAML-based DSL templates to define and execute security checks against applications, APIs, networks, DNS, and cloud configurations. It enables security professionals to write once, share, and collaborate on vulnerability detection patterns that produce near-zero false positives by design. Monolithic structure: cmd/nuclei/ is the main binary entry point, pkg/ contains core scanning logic (matcher/request processing), internal/ likely holds private utilities. Heavy use of Go's concurrency primitives (remeh/sizedwaitgroup for goroutine pooling). Template DSL parsing happens at startup with YAML unmarshaling (gopkg.in/yaml.v2). Browser automation via go-rod/rod, DNS via miekg/dns, HTTP via rawhttp and retryablehttp-go.

👥Who it's for

Security researchers, penetration testers, and DevSecOps engineers who need to rapidly scan infrastructure for known and custom vulnerabilities without writing complex code. Contributors are security professionals who author YAML templates in the projectdiscovery/nuclei-templates repository.

🌱Maturity & risk

Highly mature and production-ready. The project has significant activity (3.3MB of Go code), comprehensive CI/CD pipelines (.github/workflows/ contains 10+ automation jobs including release, fuzz, govulncheck, and perf-regression), and is actively maintained with recent Go version bump to 1.25.7. It's widely adopted by the security community with thousands of contributed templates.

Low risk for core stability but moderate complexity: 70+ direct dependencies (retryablehttp, fastdialer, interactsh, rod for browser automation, govaluate for expression evaluation) create a supply-chain surface. The project handles untrusted YAML templates which requires careful sandboxing (govaluate expressions, Lua scripts possible). No visible single-maintainer risk given ProjectDiscovery's organization backing.

Active areas of work

Actively maintained: recent workflows show ongoing work on performance regression testing (perf-regression.yaml), PGO optimization (generate-pgo.yaml), fuzzing (fuzz.yaml), memory optimization (memogen/ code generator), vulnerability scanning (govulncheck.yaml), and automatic merging (auto-merge.yaml). No specific milestone data visible but the breadth of CI coverage suggests rapid iteration on scanner performance and template engine stability.

🚀Get running

git clone https://github.com/projectdiscovery/nuclei.git
cd nuclei
make build
./nuclei -h

Or install binary: go install github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest. The Makefile is the build orchestrator (see Makefile in root).

Daily commands: Build: make build produces ./nuclei binary. Run: ./nuclei -t /path/to/template.yaml -target http://example.com. The Makefile likely has test/lint targets; check make help or review Makefile for details. For development: go run ./cmd/nuclei -h to run from source.

🗺️Map of the codebase

  • cmd/nuclei/main.go — Entry point for the Nuclei CLI scanner; all contributors must understand the initialization and argument parsing flow.
  • internal/runner/inputs.go — Handles target input processing and validation; critical for understanding how templates are matched against targets.
  • go.mod — Declares all dependencies including core libraries (httpx, retryablehttp, interactsh); essential for dependency management.
  • DESIGN.md — Documents architecture and design decisions; foundational reading for understanding the codebase philosophy.
  • SYNTAX-REFERENCE.md — Specifies the YAML template DSL syntax; required knowledge for template engine contributions.
  • internal/runner/banner.go — Displays configuration summary and execution plan; shows how runner orchestrates the scan workflow.
  • .github/workflows/tests.yaml — Defines CI/CD testing pipeline; essential for understanding quality gates and release process.

🛠️How to make changes

Add a new protocol handler

  1. Create a new protocol package under internal/ (e.g., internal/websocket/handler.go) implementing the Nuclei protocol interface (internal/ (new directory))
  2. Register the handler in the main template engine loader to bind YAML directives (e.g., 'websocket:' in templates) (SYNTAX-REFERENCE.md (update DSL spec))
  3. Add integration tests in cmd/nuclei/testdata/ with example templates (cmd/nuclei/testdata/)
  4. Update internal/runner/inputs.go or banner.go if protocol requires special handling during initialization (internal/runner/inputs.go)

Add support for a new vulnerability check type

  1. Define the YAML syntax in SYNTAX-REFERENCE.md with examples (SYNTAX-REFERENCE.md)
  2. Implement the check executor in a new module under the template engine (internal/ (new handler))
  3. Add test template to benchmark suite to validate performance (cmd/nuclei/testdata/benchmark/multiproto/)
  4. Integrate result formatting in internal/pdcp/writer.go for output serialization (internal/pdcp/writer.go)

Integrate a new issue tracking system

  1. Add client library to go.mod and update go.sum (go.mod)
  2. Create handler under internal/issuetracker/ implementing the tracker interface (internal/ (new directory))
  3. Add configuration schema to issue-tracker-config.yaml (cmd/nuclei/issue-tracker-config.yaml)
  4. Register tracker in runner initialization and wire to result output pipeline (internal/runner/inputs.go or internal/pdcp/writer.go)

Add a new command-line tool or utility

  1. Create new directory under cmd/ with main.go (e.g., cmd/my-tool/main.go) (cmd/my-tool/main.go)
  2. Add tool to .goreleaser.yml build targets if binary should be released (.goreleaser.yml)
  3. Create GitHub Actions workflow in .github/workflows/ if tool needs CI testing (.github/workflows/)

🔧Why these technologies

  • Go 1.25.7 — Fast compilation, minimal runtime overhead, native concurrency with goroutines—critical for a high-throughput vulnerability scanner.
  • YAML DSL for templates — Lower barrier to entry for security researchers and community contributions; enables collaborative template development.
  • Interactsh (out-of-band detection) — Detects blind vulnerabilities (SSRF, RCE, data exfiltration) where responses cannot be directly observed.
  • go-rod (Chromium automation) — Handles JavaScript-heavy applications and browser-based vulnerabilities not detectable via static HTTP.
  • httpx & retryablehttp — Robust HTTP client with retry logic, custom headers, and connection pooling for reliable scanning.
  • gojq (JSON query) — Flexible template matchers for extracting and validating data from JSON responses.

⚖️Trade-offs already made

  • YAML templates instead of Go plugins

    • Why: Simplifies contribution and distribution; no compilation step for end users.
    • Consequence: Limited expressiveness compared to a full programming language; matcher/extractor logic must be predefined.
  • Community-driven template repository (Nuclei templates project)

    • Why: Scales template creation across the security community; reduces maintenance burden.
    • Consequence: Quality, accuracy, and false-positive rates depend on community submissions; requires review process.
  • Single binary with all protocols compiled in

    • Why: Simplifies deployment and avoids dependency hell.
    • Consequence: Larger binary size; must rebuild to add new protocols or update vulnerability checks.
  • Parallel scanning with configurable concurrency

    • Why: Enables scanning thousands of targets or templates efficiently.
    • Consequence: Risk of target rate-limiting; requires careful tuning and may be blocked by aggressive WAF/IDS.

🚫Non-goals (don't propose these)

  • Does not provide authentication or identity management for Nuclei itself—assumes deployment in trusted environments.
  • Does not perform code static analysis or binary reverse engineering—focuses on runtime/live service scanning.
  • Does not include payload obfuscation—assumes legitimate security testing with proper authorization.
  • Not a real-time vulnerability alerting system—generates reports post-scan, not live threat detection.
  • Does not handle vulnerability remediation—reporting and tracking only; fixes are external.

🪤Traps & gotchas

YAML Template Parsing: Nuclei unmarshals untrusted YAML—expression evaluation (govaluate) is sandboxed but worth auditing if adding new expression types. Concurrency Gotcha: remeh/sizedwaitgroup pools goroutines; if you add blocking I/O, carefully tune pool size to avoid deadlocks. Memory Optimization: cmd/memogen/ is a pre-step—modify template structs and run make memogen or equivalent before rebuilding. DNS/HTTP Dialers: projectdiscovery/fastdialer is used; it has internal connection pooling and retries—check config if scanner seems slow. Interactsh Integration: Out-of-band callbacks require network connectivity to projectdiscovery's callback server; offline scans will fail interactsh matchers silently.

🏗️Architecture

💡Concepts to learn

  • YAML-based DSL (Domain-Specific Language) — Nuclei's entire strength is letting security pros define exploits in declarative YAML without writing Go—understanding the template schema (request format, matchers, extractors, workflows) is critical to using and extending nuclei
  • Expression Evaluation & Sandboxing — Nuclei uses Knetic/govaluate to evaluate dynamic expressions in matchers; understanding how expressions are parsed and isolated prevents security regressions when adding new expression types
  • Out-of-Band (OOB) Callback Detection — The interactsh integration enables detection of blind vulnerabilities (XXE, SSRF, RCE) that don't return responses; critical for modern exploit chains but requires understanding callback timing and reliability
  • Goroutine Pooling & Bounded Concurrency — nuclei uses remeh/sizedwaitgroup to limit concurrent scans (prevents resource exhaustion); incorrectly managing pool size when adding I/O-heavy protocols causes hangs or OOM
  • Header Injection & HTTP Request Normalization — nuclei uses projectdiscovery/rawhttp which supports raw HTTP (bypassing Go's automatic normalization); critical for testing HTTP smuggling and protocol edge cases, but easy to misuse
  • Headless Browser Automation (go-rod) — nuclei via go-rod/rod can automate browser-based attacks (DOM-XSS, JavaScript execution); understanding when and how to spawn browser instances is key to performance (many open browsers = OOM)
  • JQ Query Language Integration (gojq) — Template matchers can extract data using JQ; the itchyny/gojq library is embedded, so understanding JQ syntax is essential for writing advanced extractors and filters
  • projectdiscovery/nuclei-templates — Official repository of 9000+ community-contributed YAML templates; users of nuclei/v3 must clone or update templates from here
  • projectdiscovery/subfinder — Companion subdomain enumeration tool; often chained with nuclei for reconnaissance-to-exploitation workflows
  • projectdiscovery/interactsh — Out-of-band interaction server that nuclei's interactsh matchers depend on; used for blind XXE, SSRF, RCE detection
  • projectdiscovery/katana — Web crawler and scraper; commonly used to feed nuclei with URLs discovered during spidering
  • aquasecurity/trivy — Alternative vulnerability scanner focused on container/dependency scanning; different niche but comparable in speed and ease-of-use

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add integration tests for cloud provider template execution (Azure, AWS, GCP)

The repo has Azure SDK dependencies (azidentity, azblob) and references cloud configurations in the README, but there are no visible integration tests in cmd/nuclei/testdata for cloud-specific templates. This would validate that cloud credential handling and API interactions work correctly across providers.

  • [ ] Create cmd/nuclei/testdata/cloud/ directory with sample Azure/AWS/GCP templates
  • [ ] Add GitHub Action workflow (.github/workflows/cloud-integration-tests.yaml) to run tests against mock cloud services (LocalStack for AWS, Azurite for Azure)
  • [ ] Update cmd/nuclei/main_benchmark_test.go to include cloud provider scenarios
  • [ ] Document setup in DEBUG.md for local cloud integration testing

Add comprehensive YAML DSL syntax validation tests for edge cases

The repo has SYNTAX-REFERENCE.md but lacks automated tests for template parsing edge cases. Given the complex YAML DSL with conditionals, matchers, and extractors, gaps in test coverage could allow invalid templates to compile. This validates the parser robustness.

  • [ ] Create pkg/templates/parser_test.go (or similar) with test cases for: nested template variables, invalid matcher combinations, malformed YAML in templates, unsupported protocol combinations
  • [ ] Add cmd/nuclei/testdata/invalid-templates/ directory with intentionally malformed templates that should fail validation
  • [ ] Create a GitHub Action (.github/workflows/template-validation.yaml) that runs these tests on every PR
  • [ ] Reference specific failing cases in SYNTAX-REFERENCE.md

Add performance regression tests for protocol handlers (HTTP, DNS, TCP, WebSocket)

The repo has .github/workflows/perf-regression.yaml but no visible protocol-specific benchmarks. Given the multi-protocol nature (HTTP, DNS, raw TCP, WebSocket mentioned in testdata), adding dedicated benchmarks would catch performance regressions in individual protocol handlers.

  • [ ] Create cmd/nuclei/testdata/benchmark/protocols/ with separate templates for each protocol (http/, dns/, tcp/, websocket/)
  • [ ] Add protocol-specific benchmark tests in cmd/nuclei/main_benchmark_test.go using Go's testing.B
  • [ ] Update .github/workflows/perf-regression.yaml to track per-protocol metrics and fail if any protocol handler degrades by >10%
  • [ ] Document benchmark methodology in DESIGN.md

🌿Good first issues

  • Add unit tests for pkg/protocols/{newprotocol}/ if a new protocol module exists without test coverage—check _test.go file presence in protocol subdirectories
  • Generate missing YAML schema documentation for template fields: projectdiscovery/yamldoc-go is in deps but docs/ may be incomplete for new matcher types
  • Optimize expression evaluation caching in govaluate usage: if matchers evaluate the same expression repeatedly, add memoization layer (profile with pprof, see flamegraph.yaml workflow)

Top contributors

Click to expand

📝Recent commits

Click to expand
  • 397ffaa — Merge pull request #7383 from projectdiscovery/dwisiswant0/fix/workflow/propagate-context-to-child-race-steps (Mzack9999)
  • 89d0e65 — Merge pull request #7322 from projectdiscovery/dwisiswant0/fix/interactsh/serialize-InternalEvent-access (Mzack9999)
  • 805bcfe — fix(workflow): propagate context to child & race steps (dwisiswant0)
  • 3e996eb — test(workflow): added unit tests for parent-to-child (dwisiswant0)
  • 1f8dd03 — fix(runner): write unsigned-templates WRN to stderr (ChrisJr404)
  • bdf7500 — chore(deps): bump the modules group across 1 directory with 4 updates (#7372) (dependabot[bot])
  • 54f002d — Merge pull request #7356 from projectdiscovery/feat-impacket (Mzack9999)
  • 7148ff9 — Merge pull request #7379 from projectdiscovery/bugfix-7374-dns-vars (dogancanbakir)
  • 7926e22 — fix lint (dogancanbakir)
  • 10831d6 — fix lint (dogancanbakir)

🔒Security observations

Failed to generate security analysis.

LLM-derived; treat as a starting point, not a security audit.


Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Healthy signals · projectdiscovery/nuclei — RepoPilot