# CrowCpp/Crow: a header-only C++ microframework for HTTP and WebSocket services

> Crow is a header-only C++ framework that maps routes to typed handlers in a Flask-like style, with JSON, Mustache templating and WebSocket support built in. The trade-off is that HTTP/2 and async support are still listed as in development.

**CrowCpp/Crow** — A Fast and Easy to use microframework for the web.

- Repository: https://github.com/CrowCpp/Crow
- Website: https://crowcpp.org
- Stars: 4,990 · Forks: 561
- Language: C++
- License: NOASSERTION
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/crowcpp-crow

## The problem CrowCpp/Crow solves for C++ services

Writing an HTTP service in C++ usually means picking a socket or event library, wiring an HTTP parser to it, and then writing your own dispatch table. Crow removes that layer. The README describes it as a framework for creating HTTP or Websocket web services, and the routing style is explicitly modelled on Python's Flask: you declare a path and attach a handler to it. The intended audience is a C++ developer who wants a service in the same language as the rest of the codebase, without standing up a separate runtime for a few endpoints. Crow is not a general application server. It has no database layer, no ORM, no admin interface. What it gives you is routing, request and response objects, JSON, templating and WebSocket handling, and it expects you to bring everything else. The README also notes that the project is based on ipkn/crow and states plainly that CrowCpp is not associated with, endorsed by or supported by ipkn (Jaeseung Ha), though it uses that source under the BSD-3 clause licence.

## How routing, handlers and JSON fit together

The core mechanism is a macro that registers a route on an app object, with the handler written as a lambda. The README's Hello World example creates a crow::SimpleApp, registers a route on "/", and calls app.port(18080).multithreaded().run(). The multithreaded() call is what turns the server into a multi-threaded one; without it the app runs single-threaded. Handler arguments are typed and checked at compile time. The README shows a route "/hello/<int>" whose lambda takes an int, and notes that a mismatched handler produces a compile error reading "Handler type is mismatched with URL parameters". That is the framework's main design bet: push errors from runtime to build time. On the request side, crow::request carries the body, and crow::json::load parses it. If parsing fails, the README's example returns crow::status::BAD_REQUEST, which it notes is the same as crow::response(400). Responses can be built from strings, from crow::json::wvalue objects, or from crow::response with an explicit status. The README also lists middleware support for extensions, multi-part request and response support, and a Mustache-based templating library exposed as crow::mustache. HTTP parsing is handled by http-parser, which the attributions section says converts HTTP strings into crow::request objects; query strings are read with qs_parse, and TinySHA1 is used during the WebSocket handshake, with the README stating it is not for security.

## Installing Crow and serving a first route

Crow is header-only, and the README says a single header file is available, but it does not spell out the build steps inline: the Setting Up / Building section points to the setup page on crowcpp.org. What the repository does show is the shape of a project. The top level contains CMakeLists.txt, CMakePresets.json, vcpkg.json, BUILD.bazel and MODULE.bazel, so CMake, vcpkg and Bazel are all present as build entry points, and the include directory holds the headers. The examples directory contains helloworld.cpp and a CMakeLists.txt, which is the shortest path to something running. A minimal program following the README's Hello World looks like this:

```cpp
#include "crow.h"

int main()
{
    crow::SimpleApp app;

    CROW_ROUTE(app, "/")([](){
        return "Hello world";
    });

    app.port(18080).multithreaded().run();
}
```

The port is 18080 and the route is "/", both taken directly from the README. Once this is built and started, a request to that port should return the string "Hello world". To add a JSON endpoint, the README gives this handler, which constructs a wvalue from an initializer list and then adds a second key:

```cpp
CROW_ROUTE(app, "/json")
([]{
    crow::json::wvalue x({{"message", "Hello, World!"}});
    x["message2"] = "Hello, World.. Again!";
    return x;
});
```

One version detail is worth flagging before you start. The README carries a warning that if you are using Crow v0.3, you must put #define CROW_MAIN at the top of one and only one source file. That applies to v0.3 specifically, not to the current release line.

## HTTP/2, async and the limits of a header-only server

The README's own feature list contains the most important caveat. Under "Still in development" it lists async support and HTTP/2 support, both with links to tracking issues. If your service needs either, Crow is the wrong tool today, and no amount of routing convenience changes that. The header-only design has a second cost that the README does not discuss. Every translation unit that includes crow.h compiles the framework, and build times grow with the number of files that include it. The single-header option makes distribution easy and compile times worse. There is also a version-specific trap: the CROW_MAIN define rule for v0.3 means code copied from older tutorials can fail to link against a current checkout, and the README's warning is the only place that is stated. Finally, the README claims Crow is extremely fast and points to two external benchmark repositories, ipkn/crow-benchmark and guteksan/REST-CPP-benchmark. Those are the project's own citations, not an independent measurement, and the numbers depend entirely on the workload and hardware used there. Treat the claim as a pointer to methodology, not as a result.

## Crow compared with Drogon and plain Boost.Beast

The nearest alternative in the same language is Drogon, another C++ HTTP framework, which is a compiled library rather than a header you drop in, and which ships with its own ORM, its own CLI tooling and its own configuration file format. That is the real difference in approach: Crow gives you routing, JSON, Mustache and WebSocket handling and stops, while Drogon takes responsibility for the application structure around the service. If you want the framework out of your build system and inside your source tree, Crow fits better. If you want the framework to also own the database layer and the project scaffolding, it does not. At the other end, Boost.Beast gives you HTTP parsing over Boost.Asio and nothing else: no routing table, no JSON type, no templating. Choosing Beast means writing the dispatch layer Crow already provides, in exchange for direct control over the socket and the event loop. Crow sits between those two points, and the README's Flask comparison is the honest description of where: it is a microframework, and it behaves like one.

## Maintenance, licence and what upgrading costs

The repository is not archived, and the last push was on 2026-09-22, one day before this writing. Recent releases are v1.3.2 on 2026-03-29, v1.3.3 on 2026-06-29 and v1.3.4 on 2026-09-07, roughly one release per quarter. That cadence matters for upgrade planning: a header-only dependency that moves every few months means a rebuild is the whole upgrade, but it also means an API change lands in your source tree rather than behind a package boundary. The licence field is reported as NOASSERTION, which means the repository metadata does not declare a standard SPDX identifier. The LICENSE file exists at the top level, and the README's disclaimer says CrowCpp uses ipkn/crow's source under the BSD-3 clause licence. The attributions section lists three incorporated libraries with their own terms: http-parser, derived from NGINX and Joyent code under a permissive MIT-style grant; qs_parse, under a permissive grant from Bart Grantham; and TinySHA1, under a permissive grant from Saurav Mohapatra. Because the metadata does not resolve to a single identifier, anyone shipping Crow in a product should read the LICENSE file and the attributions section directly and have their own counsel confirm the terms. Nothing here is legal advice.

## Conclusion

Adopt Crow when you want a small C++ HTTP or WebSocket service built from a single header, with routing and JSON handled by the framework. Do not adopt it when you need HTTP/2 or async request handling today, since both are listed as still in development, and do not expect the README to walk you through the build: it points to the documentation site for setup. Before committing, verify on crowcpp.org that your compiler and C++ standard are supported, and check the examples directory for the middleware, SSL and websocket cases you actually need.

## FAQ

### What is Crow in C++?

Crow is a C++ framework for creating HTTP or WebSocket web services, using routing similar to Python's Flask. It is header-only, includes built-in JSON support and a Mustache-based templating library, and targets modern C++ (11/14).

### What is the best C++ framework for web development?

There is no single answer, and Crow's README does not rank frameworks. Crow is a microframework that handles routing, JSON, templating and WebSocket connections, while leaving database access and application structure to you, which makes it a fit only when that is the split you want.

### How do I install CrowCpp/Crow?

The README's Setting Up / Building section points to the setup page on crowcpp.org rather than listing steps inline. The repository includes CMakeLists.txt, CMakePresets.json, vcpkg.json, BUILD.bazel and MODULE.bazel at the top level, and the headers live in the include directory.

### Does CrowCpp/Crow support HTTP/2 or async handlers?

No. The README lists both async support and HTTP/2 support under "Still in development", each with a link to a tracking issue. The framework supports HTTP/1.1 and WebSocket.

### What licence does CrowCpp/Crow use?

The repository metadata reports NOASSERTION rather than a standard identifier, and there is a LICENSE file at the top level. The README's disclaimer states that CrowCpp uses ipkn/crow's source under the BSD-3 clause licence, and the attributions section lists http-parser, qs_parse and TinySHA1 with their own terms.

## Sources

- [CrowCpp/Crow on GitHub](https://github.com/CrowCpp/Crow)
- [Issues](https://github.com/CrowCpp/Crow/issues)
- [Project website](https://crowcpp.org)
- [README](https://github.com/CrowCpp/Crow/blob/master/README.md)
- [Releases](https://github.com/CrowCpp/Crow/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/crowcpp-crow
