nats-io/nats-server
High-Performance server for NATS.io, the cloud and edge native messaging system.
Healthy across the board
Permissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 1d ago
- ✓6 active contributors
- ✓Distributed ownership (top contributor 49% of recent commits)
Show 3 more →Show less
- ✓Apache-2.0 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.
[](https://repopilot.app/r/nats-io/nats-server)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/nats-io/nats-server on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: nats-io/nats-server
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:
- 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. - 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.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/nats-io/nats-server 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
- 6 active contributors
- Distributed ownership (top contributor 49% of recent commits)
- Apache-2.0 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 nats-io/nats-server
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/nats-io/nats-server.
What it runs against: a local clone of nats-io/nats-server — 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 nats-io/nats-server | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch main 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 |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of nats-io/nats-server. If you don't
# have one yet, run these first:
#
# git clone https://github.com/nats-io/nats-server.git
# cd nats-server
#
# 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 nats-io/nats-server and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "nats-io/nats-server(\\.git)?\\b" \\
&& ok "origin remote is nats-io/nats-server" \\
|| miss "origin remote is not nats-io/nats-server (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
&& ok "default branch main exists" \\
|| miss "default branch main no longer exists"
# 4. Critical files exist
test -f "main.go" \\
&& ok "main.go" \\
|| miss "missing critical file: main.go"
test -f "server/client.go" \\
&& ok "server/client.go" \\
|| miss "missing critical file: server/client.go"
test -f "server/accounts.go" \\
&& ok "server/accounts.go" \\
|| miss "missing critical file: server/accounts.go"
test -f "server/auth.go" \\
&& ok "server/auth.go" \\
|| miss "missing critical file: server/auth.go"
test -f "conf/parse.go" \\
&& ok "conf/parse.go" \\
|| miss "missing critical file: conf/parse.go"
# 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/nats-io/nats-server"
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).
⚡TL;DR
NATS Server is a high-performance, cloud-native messaging system written in Go that provides publish-subscribe, request-reply, and queue-based communication patterns. It's a CNCF-backed message broker designed to run anywhere—on-premise, cloud, edge devices, or Raspberry Pi—with minimal footprint and latency, acting as the core infrastructure for distributed systems communication. Monolithic Go binary architecture: server/ contains the core NATS server logic, conf/ handles config parsing (lex.go, parse.go) and includes (passwords.conf, users.conf), internal/antithesis/ has test instrumentation, and internal/fastrand/ provides optimized randomization. Main entry point orchestrates server startup with configuration, JetStream storage, and protocol handling.
👥Who it's for
DevOps engineers, cloud architects, and backend developers building distributed systems, microservices, or edge computing solutions who need a lightweight, zero-copy messaging backbone with support for 40+ client languages and JetStream persistence.
🌱Maturity & risk
Highly mature and production-ready: the project is a CNCF member project with extensive CI/CD coverage (multiple GitHub workflows for tests, nightly builds, MQTT testing, vulnerability scanning), comprehensive test suites across the codebase, and active maintenance visible in the go.mod (Go 1.25.0 with current dependencies). It powers critical infrastructure globally.
Standard open source risks apply.
Active areas of work
Active development on performance and feature stability: recent workflows include long-tests.yaml and mqtt-test.yaml suggesting MQTT protocol expansion, antithesis-based property testing integration (internal/antithesis/), and nightly release automation. The presence of claude.yml workflow suggests ongoing AI-assisted development tooling.
🚀Get running
Check README for instructions.
Daily commands:
# Basic server with default config
./nats-server
# With custom config
./nats-server -c conf/simple.conf
# With docker
docker build -f docker/Dockerfile.nightly .
🗺️Map of the codebase
main.go— Entry point for the NATS server; every contributor must understand how the server initializes and starts.server/client.go— Core client connection handler managing NATS protocol parsing, subscriptions, and message routing—fundamental to all client interactions.server/accounts.go— Implements NATS account isolation and authorization model; critical for understanding multi-tenancy and permission enforcement.server/auth.go— Authentication system (JWT, NKey, basic auth) that secures all server access; essential for security-aware development.conf/parse.go— Configuration parser that translates server config files into runtime state; required to understand how options propagate.server/ats/ats.go— NATS account token store and JWT validation; core to the server's authentication and authorization infrastructure.go.mod— Dependency manifest showing Go version (1.25.0) and key imports (JWT, nkeys, crypto); baseline for reproducible builds.
🛠️How to make changes
Add a new authentication method
- Define the auth provider interface in server/auth.go and implement the Provider interface (
server/auth.go) - Add configuration parsing for the new auth method in conf/parse.go (
conf/parse.go) - Wire the new provider into Options struct initialization in server/auth.go (
server/auth.go) - Implement account-level permission checking in server/accounts.go (
server/accounts.go)
Add a new TLS feature (cipher suites, OCSP, etc.)
- Update TLS cipher suite definitions in server/ciphersuites.go (
server/ciphersuites.go) - Add config parsing support in conf/parse.go for new TLS options (
conf/parse.go) - Implement feature logic (e.g., OCSP responder) in server/certidp/ocsp_responder.go (
server/certidp/ocsp_responder.go) - Integrate into client connection setup in server/client.go handshake logic (
server/client.go)
Add a new configuration option
- Define the field in the Options struct (typically in server/server.go, not in file list but referenced by conf/parse.go) (
conf/parse.go) - Add lexer recognition for the new keyword in conf/lex.go (
conf/lex.go) - Implement parsing logic in conf/parse.go to extract and validate the option (
conf/parse.go) - Create tests in conf/parse_test.go to verify config parsing (
conf/parse_test.go)
Integrate a new external identity provider (LDAP, OCSP, etc.)
- Create new provider package (e.g., internal/ldap/dn.go for LDAP DN parsing) (
internal/ldap/dn.go) - Implement the Provider interface defined in server/auth.go (
server/auth.go) - Add configuration parsing in conf/parse.go for provider-specific settings (
conf/parse.go) - Wire provider into auth initialization and client authentication flow in server/client.go (
server/client.go)
🔧Why these technologies
- Go 1.25.0 — High-performance concurrency via goroutines and channels; fast compilation and native binaries for minimal dependencies on edge devices.
- JWT (github.com/nats-io/jwt/v2) + NKeys (github.com/nats-io/nkeys) — Stateless, cryptographically-signed authentication that scales across distributed deployments without a centralized auth server.
- TLS 1.2+ — Encryption in transit for secure cloud and edge deployments; configurable cipher suites for compliance and performance trade-offs.
- AVL trees (server/avl/seqset.go) — Efficient range queries on message sequences for subscription management and backpressure handling.
- Custom config parser (conf/parse.go + conf/lex.go) — Lightweight, minimal-dependency configuration without external YAML/TOML libraries; suitable for edge environments.
⚖️Trade-offs already made
-
Custom protocol parser in client.go instead of Protocol Buffers
- Why: NATS protocol is simple text-based; protobuf would add complexity and dependency overhead.
- Consequence: Manual protocol parsing is faster and lighter but requires careful testing for edge cases.
-
JWT-only stateless auth vs. server-side session storage
- Why: Enables horizontal scaling and multi-instance deployments without shared state.
- Consequence: Token revocation cannot be immediate; operators must wait for token expiry or rotate signing keys.
-
In-memory account/subscription store vs. persistent database
- Why: Low-latency message routing in real-time systems; subscriptions are ephemeral per connection.
- Consequence: Server restart loses all subscriptions; clients must reconnect and re-subscribe (acceptable for pub/sub semantics).
-
Minimal external dependencies (7 key imports in go.mod)
- Why: Reduces supply-chain risk and binary size for edge deployments.
- Consequence: Must implement or vendor non-trivial features (crypto, compression, LDAP DN parsing).
🚫Non-goals (don't propose these)
- Does not persist messages to disk; operates as an in-memory router (though JetStream (not in this file list) adds persistence).
- Does not implement relational databases or transactions; designed for publish/subscribe messaging, not OLTP.
- Does not handle client-side message ordering across multiple publishers; order is per-subject per-publisher.
- Does not support dynamic topic creation beyond string matching; subjects must be known or follow glob patterns.
- Does not provide query language or message filtering at the server level; filters happen at subscription level only.
🪤Traps & gotchas
- Configuration file includes (conf/includes/) are loaded relative to the config file location, not CWD—easy to miss path issues. 2) TLS configuration requires careful ordering in config (cipher suites, cert paths validated strictly). 3) JetStream requires persistent storage directory permissions and disk space monitoring. 4) MQTT protocol support (mqtt-test.yaml) is newer—may have edge cases vs. core NATS protocol. 5) The internal/antithesis/ package is for property-based testing and uses a no-op SDK by default—don't rely on it for correctness verification in unit tests.
🏗️Architecture
💡Concepts to learn
- Publish-Subscribe with Subject Wildcards — NATS core abstraction: subjects can use
>(multi-level) and*(single-level) wildcards for flexible message routing without broker awareness of client topology - JetStream (NATS Streaming) — Built-in durability layer in server/jetstream.go—enables message persistence, replay, and at-least-once delivery semantics for use cases beyond transient pub-sub
- Token Bucket Rate Limiting — NATS implements connection-level and subscription-level rate limiting to prevent resource exhaustion—critical for multi-tenant deployments and edge devices with constrained resources
- Lexical Analysis & Configuration Parsing — conf/lex.go and conf/parse.go implement hand-written lexer/parser for NATS config syntax—understanding this is essential for adding config directives or debugging configuration issues
- Zero-Copy Message Passing — NATS architecture avoids serialization-deserialization for message relay between subscribers—core to its sub-microsecond latency claim; see server/client.go connection handling
- HMAC with HighwayHash — Uses minio/highwayhash (not SHA-1) for authentication token validation—faster non-cryptographic hashing for protocol integrity checks; understand this for auth performance tuning
- Clustering & Gossip Protocol — NATS servers form clusters for HA; requires understanding of gossip-based discovery and route-level message forwarding visible in server/route.go—critical for multi-region deployments
🔗Related repos
nats-io/nats.go— Official Go client library for NATS—a typical consumer of nats-server; required for testing server behavior from Go clientsnats-io/jwt— JWT authentication and authorization library used by nats-server (imported as nats-io/jwt/v2 in go.mod)—understand auth flowsnats-io/nkeys— Cryptographic key handling library (nats-io/nkeys v0.4.15)—core to NATS authentication and identityliftbridge-io/liftbridge— Event streaming built on NATS—shows how to extend NATS for streaming use cases (precursor to JetStream integration)envoyproxy/envoy— Service proxy that integrates with NATS for observability and routing—ecosystem integration point
🪄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 comprehensive LDAP integration tests in internal/ldap/
The internal/ldap/ directory contains DN parsing logic (dn.go) with basic unit tests (dn_test.go), but there are no integration tests for LDAP authentication workflows. Given that NATS supports LDAP as an auth mechanism and this is a security-critical path, adding integration tests would validate real-world LDAP server scenarios, bind failures, and edge cases in DN parsing.
- [ ] Create internal/ldap/integration_test.go with mock LDAP server fixtures
- [ ] Add tests for LDAP bind scenarios (success, invalid credentials, connection failures)
- [ ] Add tests for DN parsing edge cases (special characters, unicode, malformed DNs)
- [ ] Reference existing auth test patterns from the server's test suite to maintain consistency
- [ ] Update internal/ldap/dn_test.go if gaps are found in unit test coverage
Add OCSP stapling validation tests in internal/ocsp/
The internal/ocsp/ directory contains OCSP certificate validation code (ocsp.go) but has no associated test file. OCSP is critical for certificate revocation checking in TLS connections. Adding comprehensive tests would validate OCSP response parsing, responder validation, and handling of revoked/unknown certificates.
- [ ] Create internal/ocsp/ocsp_test.go with test cases for valid OCSP responses
- [ ] Add tests for malformed/invalid OCSP responses
- [ ] Add tests for expired OCSP responses and cache behavior
- [ ] Add tests for revoked certificate detection
- [ ] Reference golang.org/x/crypto/ocsp patterns for test fixtures
Implement GitHub Actions workflow for dependency vulnerability scanning with Go tooling
The repo has a vuln.yaml workflow file listed, but examining the dependencies (google/go-tpm, klauspost/compress, crypto, etc.) reveals no dedicated Go vulnerability scanning. Adding a workflow using 'go list -json -m all | nancy' or 'go install github.com/sonatype-nexus-community/nancy@latest' would continuously check for known CVEs in dependencies and integrate with the existing security posture.
- [ ] Create .github/workflows/go-vuln-check.yaml using Nancy or Trivy for Go dependencies
- [ ] Configure workflow to run on: push to main, pull_requests, and schedule (daily)
- [ ] Add fail condition when HIGH/CRITICAL vulnerabilities are found
- [ ] Reference go.mod and go.sum in the workflow
- [ ] Integrate with existing .github/workflows/vuln.yaml or consolidate scanning logic
🌿Good first issues
- Add tests for conf/includes/ edge cases: test relative path resolution, missing include files, and circular include detection—currently only conf/*_test.go files exist with basic coverage.
- Document JetStream configuration options in the repository README beyond what's in docs.nats.io—add examples for retention policies, replication factors, and common missteps (seen in doc/README.md but thin on examples).
- Implement performance benchmarks for the internal/fastrand/ package vs. stdlib rand—add benchmarks to internal/fastrand/ directory to justify the custom implementation and track regressions.
⭐Top contributors
Click to expand
Top contributors
- @neilalexander — 49 commits
- @MauriceVanVeen — 39 commits
- @sciascid — 8 commits
- @nevivurn — 2 commits
- @wallyqs — 1 commits
📝Recent commits
Click to expand
Recent commits
758bc9d— MQTT: ReturnerrMQTTUnsupportedCharactersfor control characters on both pub and sub (#8112) (neilalexander)79ce525— MQTT: ReturnerrMQTTUnsupportedCharactersfor control characters on both sub and pub (neilalexander)b106455— [FIXED] Source consumer reschedule storm on leafnode reconnect (#8111) (neilalexander)7faace5— [FIXED] Source consumer reschedule storm on leafnode reconnect (MauriceVanVeen)522eac7— De-flake TestJetStreamConsumerStepDownResetsPendingAndRdc (#8110) (neilalexander)80c56f3— Allow certificates without subjects (#8100) (neilalexander)c1f22f4— Update to Go 1.26.3/1.25.10 (#8107) (neilalexander)fde292d— De-flake TestJetStreamConsumerStepDownResetsPendingAndRdc (MauriceVanVeen)702172b— Update to Go 1.26.3/1.25.10 (neilalexander)bac58c1— [FIXED] Dedupe map cleanup race on leader change (#8106) (neilalexander)
🔒Security observations
- Medium · Outdated Go Toolchain Version —
go.mod. The project specifies Go 1.25.0 with toolchain go1.25.10. Go 1.25 is a very recent version and may not have the maturity of LTS versions. Consider using a more stable, widely-tested Go version for production systems. Fix: Evaluate the necessity of Go 1.25. Consider using Go 1.23 LTS or waiting for a more stable release cycle. Ensure all dependencies are compatible with the chosen version. - Medium · Potential Credential Exposure in Configuration Files —
conf/includes/passwords.conf, conf/includes/users.conf. Configuration files exist that may contain sensitive data: 'conf/includes/passwords.conf' and 'conf/includes/users.conf'. If these files are committed to the repository or exposed, credentials could be compromised. Fix: Ensure these files are in .gitignore and never committed to version control. Use environment variables or secure credential management systems for storing sensitive data. Document the expected format without actual credentials. - Low · Dependency on External TPM Library —
go.mod - google/go-tpm dependency. The project depends on 'github.com/google/go-tpm v0.9.8' for TPM operations. While the library itself is from Google, verify that TPM operations are used securely and don't expose sensitive key material in logs or memory dumps. Fix: Review how TPM operations are implemented in the codebase. Ensure TPM secrets are never logged, and implement proper memory management for sensitive operations. Monitor for security updates to the google/go-tpm library. - Low · Cryptographic Library Version Check —
go.mod - golang.org/x/crypto dependency. The project uses 'golang.org/x/crypto v0.50.0'. While this is a relatively recent version, cryptographic libraries should be kept up-to-date for security patches. Fix: Regularly update golang.org/x/crypto to the latest version. Monitor the Go security mailing list and GitHub advisories for any reported vulnerabilities in cryptographic implementations. - Low · LDAP Implementation Present —
internal/ldap/dn.go, internal/ldap/dn_test.go. Custom LDAP DN parsing is implemented in 'internal/ldap/dn.go'. Custom LDAP implementations may be vulnerable to injection attacks or improper DN handling if not carefully implemented. Fix: Review LDAP DN parsing logic for proper escaping and validation. Ensure LDAP injection attacks are not possible. Consider using well-tested LDAP libraries instead of custom implementations. Add comprehensive test cases for edge cases and malformed DNs. - Low · OCSP Implementation Present —
internal/ocsp/ocsp.go. Custom OCSP implementation exists in 'internal/ocsp/ocsp.go'. OCSP handling involves certificate validation and should be carefully implemented to avoid bypassing certificate checks. Fix: Verify that OCSP stapling and responder validation are properly implemented. Ensure soft-fail mechanisms don't allow invalid certificates. Test with various OCSP responder failure scenarios. Consider using standard library implementations where possible. - Low · Authentication Callout Mechanism —
server/auth_callout.go, server/auth_callout_test.go. The 'server/auth_callout.go' file suggests external authentication callbacks. Network-based authentication can introduce latency, TOCTOU vulnerabilities, and potential SSRF issues if not properly validated. Fix: Review auth callout implementation for proper timeout handling, input validation, and secure URL parsing. Implement rate limiting on failed auth attempts. Validate all responses from external auth services. Ensure no sensitive data is logged during authentication. - Low · Syslog Integration Present —
logger/syslog.go, logger/syslog_windows.go. Syslog logging is implemented with platform-specific code ('logger/syslog.go', 'logger/syslog_windows.go'). Ensure sensitive information is not leaked through logs. Fix: Review logging implementation to ensure passwords, tokens, and other sensitive data are not logged. Implement log redaction where necessary. Verify that syslog connections
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.