nghttp2: the C library, client, server and proxy behind a lot of HTTP/2 traffic
nghttp2 - HTTP/2 C Library and tools
At a glance
- What is it?
- nghttp2 is a C implementation of HTTP/2 framing, plus the nghttp, nghttpd, nghttpx and h2load programs built on top of it. It is a good fit when you need HTTP/2 at the protocol level, and the wrong tool when you just want a web server.
- Who is it for?
- Adopt nghttp2 if you are writing an HTTP/2 client, server, proxy or load generator and want the framing layer as a library rather than a full web framework; the public test server at nghttp2.org lets you check behaviour before you build. Do not adopt it if you want a general purpose web server or an HTTP/1.1 stack, and do not expect the README to tell you how to upgrade a running nghttpx.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository received new commits within the last day.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What nghttp2 actually provides, and who needs it
The README describes the project as an implementation of HTTP/2 in C, with the framing layer packaged as a reusable C library. That is the centre of the project. Everything else is built on it: an HTTP/2 client (nghttp), a server (nghttpd), a proxy (nghttpx) and load test and benchmarking tools (h2load). An HPACK encoder and decoder are exposed as a public API as well.
The intended audience is people who need HTTP/2 at the framing level rather than through a web framework. If you are writing a client that has to speak h2 or h2c directly, or a proxy that terminates HTTP/2 and forwards it, the library gives you the frame handling and HPACK without dictating your I/O model. The README notes that the code base was forked from the spdylay project, which is where the design lineage comes from.
The project also runs a public test server. https://nghttp2.org/ supports h2 and http/1.1 via ALPN, requires TLSv1.2 for HTTP/2, and supports HTTP/3. The plain http://nghttp2.org/ endpoint supports h2c and http/1.1. Those endpoints exist so you can try the implementation without building anything, which is unusual and useful when you are evaluating whether a client's ALPN handling is correct.
The framing layer, HPACK, and where the applications sit
The architecture is layered. libnghttp2 handles HTTP/2 framing and HPACK; the applications in src/ (nghttp, nghttpd, nghttpx, h2load) sit on top. That split is why the README offers --enable-lib-only, which builds only libnghttp2 and avoids build errors related to the bundled applications. If your interest is the protocol layer inside another program, that flag is the one that matters.
The README states that development started from RFC 7540 (HTTP/2) and RFC 7541 (HPACK), and that the code is now being updated to implement RFC 9113. That is a meaningful detail: RFC 9113 obsoletes RFC 7540, so a library that is mid-migration between the two is worth checking against the specific behaviours you depend on, particularly around connection handling and field validation.
HTTP/3 is present but explicitly experimental. It is enabled for h2load and nghttpx with --enable-http3 and requires quictls, wolfSSL, LibreSSL (no 0RTT), aws-lc, BoringSSL at a specific commit, or OpenSSL >= 3.5.0, plus ngtcp2 >= 1.23.0 and nghttp3 >= 1.17.0. Note that this is the HTTP/3 support in the applications, not a claim that libnghttp2 itself speaks QUIC.
Installing nghttp2 and making a first request
The README points at Ubuntu 22.04 package installation for the required packages, and the build is autotools-based with a CMakeLists.txt also present at the top level. The dependency list is split by what you want to build. For libnghttp2 alone, pkg-config >= 0.20 is the only stated requirement. For the applications you additionally need OpenSSL >= 1.1.1 (or wolfSSL >= 5.7.0, LibreSSL >= 3.8.1, aws-lc >= 1.19.0, or BoringSSL), libev >= 4.11, zlib >= 1.2.3 and libc-ares >= 1.7.5.
If you only want the library, configure with the lib-only flag:
./configure --enable-lib-onlyThe README states that --enable-lib-only ensures only libnghttp2 is built, which sidesteps build errors from the bundled applications. If the applications are missing after a normal build, the README suggests passing --enable-app explicitly, because configure normally detects the dependencies and enables it automatically.
For the applications, the compiler requirement is the part people trip over. Compiling the C library needs a C99 compiler, and gcc 4.8 is described as adequate. The C++ sources need a C++23 compliant compiler, with g++ >= 14 and clang++ >= 19 known to work. That is a recent toolchain, and it is the first thing to check before starting.
Once built, the public server is the fastest way to confirm the client works against a real h2 endpoint. The README documents that this endpoint requires TLSv1.2 for HTTP/2 and negotiates h2 or http/1.1 via ALPN, so the negotiated protocol is what to look at in the output. For cleartext, http://nghttp2.org/ supports h2c and http/1.1.
nghttpx is configured through a sample file in the repository, nghttpx.conf.sample, which is the reference point for its options rather than the README prose.
Build options that change the security and memory profile
Several configure options exist for operational reasons, and they are worth reading before you pick a build recipe. nghttpx supports neverbleed, a privilege separation engine for OpenSSL that the README describes as minimising the risk of private key leakage when a serious bug like Heartbleed is exploited. It is disabled by default and enabled with --with-neverbleed. If you are terminating TLS in nghttpx, this is the option that changes your exposure to an OpenSSL memory-disclosure bug.
For long running servers, jemalloc is recommended to mitigate heap fragmentation in nghttpd and nghttpx. The README carries a caveat: Alpine Linux does not support malloc replacement because of musl limitations, referencing issue #762. So the memory advice does not apply on Alpine.
eBPF is a third operational knob. nghttpx can build an optional eBPF program to direct an incoming QUIC UDP datagram to the correct socket, via --with-libbpf, requiring libbpf-dev >= 0.7.0 and libelf-dev. The README states that nghttpx requires the eBPF program for reloading its configuration and hot swapping its executable. That means on a kernel or build without libbpf, those two operational capabilities are not available, which is a constraint on deployment rather than a footnote.
Where nghttp2 is the wrong choice
The clearest limitation is scope. nghttp2 is an HTTP/2 implementation with a proxy and a test server attached; it is not a general purpose web server with a module ecosystem, a configuration language for application routing, or a request lifecycle for application code. If your problem is serving a web application, nghttpx is a reverse proxy, and reaching for it as an origin server means writing your own logic against a tool that was not designed for it.
The README's own notes flag platform friction. macOS users may need --disable-threads to disable multi-threading in nghttpd, nghttpx and h2load to prevent crashes, and the README says a patch to make multi-threading work on macOS is welcome. That is an unresolved limitation, not a configuration preference.
HTTP/3 support is labelled experimental, and the dependency chain is long: a specific QUIC-capable TLS stack, ngtcp2 >= 1.23.0 and nghttp3 >= 1.17.0. LibreSSL does not support 0RTT in that list. If you need production HTTP/3 today, the README gives no stability guarantee for this path.
Finally, the C++23 requirement for the applications rules out older build images. A project that compiles its C library with gcc 4.8 but needs g++ >= 14 for the tools has a wide toolchain spread, and CI images built around older distributions will need updating before nghttpx or h2load will build.
nginx, curl and the difference between embedding and terminating
The realistic alternative depends on what you are doing. If you need a server that terminates HTTP/2 for a website, nginx is the comparison people search for, and the difference is structural: nginx is a full HTTP server where HTTP/2 is one protocol among several, configured through its own directive set. nghttp2 gives you the framing layer and a proxy, and leaves request handling to you. Choosing nghttp2 for a website means choosing to write the application layer yourself.
If you need a client, curl already speaks HTTP/2 and is built against nghttp2 in many distributions. The distinction is that curl is an application, while nghttp2's public API lets you drive the connection from inside your own program, including the HPACK encoder and decoder. If you only need to fetch URLs, curl is the shorter path; if you need to embed HTTP/2 in a program you control, that is what the library is for.
There is also an HTTP/3 split worth naming. nghttp3 is a separate project, listed in the README as a dependency for HTTP/3 support in nghttpx and h2load, alongside ngtcp2. nghttp2 handles HTTP/2 framing; HTTP/3 framing lives in nghttp3. They are not interchangeable, and the presence of nghttp2 in a dependency list does not imply HTTP/3 capability.
Maintenance, licence and upgrade cost
The repository is not archived, and the last push was on 2026-09-14. Releases are frequent: v1.70.0 on 2026-07-29, v1.69.0 on 2026-04-19, v1.68.1 on 2026-03-18. A project shipping releases at that cadence with a recent push is being worked on, and the RFC 9113 migration described in the README is consistent with that.
The licence field is reported as NOASSERTION, and the repository carries both a LICENSE file and a COPYING file at the top level. Because the automated classification is inconclusive, read those two files directly rather than relying on a package manager's licence metadata. I cannot give legal advice, and I cannot state the licence terms from the information here.
Upgrade cost has one concrete anchor: nghttpx requires the eBPF program for reloading its configuration and hot swapping its executable, and that program is built with --with-libbpf. A deployment that skipped libbpf does not have those capabilities, so an upgrade plan that assumes a reload will not work there. The README does not document a rollback procedure for nghttpx, so the upgrade path is something to establish from the sample configuration and your own deployment tooling rather than from the project's documentation. The go.mod file at the top level declares Go 1.26.0 and pulls in quic-go, gomemcache and golang.org/x/net, which indicates Go components in the repository that are separate from the C library.
Editorial conclusion
Adopt nghttp2 if you are writing an HTTP/2 client, server, proxy or load generator and want the framing layer as a library rather than a full web framework; the public test server at nghttp2.org lets you check behaviour before you build. Do not adopt it if you want a general purpose web server or an HTTP/1.1 stack, and do not expect the README to tell you how to upgrade a running nghttpx. Verify first that your toolchain has a C++23 compiler (g++ >= 14 or clang++ >= 19) if you need the applications, and check whether the HTTP/3 path you want needs --enable-http3 plus ngtcp2 and nghttp3.
Frequently asked questions
What is nghttp2?
It is an implementation of HTTP/2 in C. The framing layer is a reusable C library, and on top of it the project provides an HTTP/2 client, server and proxy, plus load test and benchmarking tools, with an HPACK encoder and decoder available as a public API.
What is nghttp2 dll?
The README does not describe a Windows DLL build. It documents a C library built with autotools or CMake on Unix-like systems, with pkg-config, OpenSSL, libev, zlib and libc-ares as dependencies for the applications.
nghttp2 vs nghttp3: what is the difference?
nghttp2 implements HTTP/2 framing and HPACK. nghttp3 is a separate project that the README lists as a dependency, together with ngtcp2, for the experimental HTTP/3 support in h2load and nghttpx. They are not interchangeable.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/nghttp2-nghttp2)