Skip to content
Open source · MIT License

The C framework
for the web

A high-performance Linux server: HTTP/1, HTTP/2 and HTTP/3 (QUIC), WebSockets, databases and ORM out of the box — no reverse proxy, no runtime

cwfr — bash live
$
0 req/s p99 0.00 ms0 conn
3HTTP protocolsHTTP/1.1 · HTTP/2 · HTTP/3
4database driversPostgreSQL · MySQL · Redis · SQLite
~100 µsper requesttypical latency under load
MITopen sourcesource code freely available on GitHub
Quick Start

Run the server in a couple of commands

Clone the repository, build the project with the database drivers you need and launch the server with a single command.

bash
git clone https://github.com/fraxer/C-web-framework.git
cd C-web-framework/backend

mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=Release \
  -DINCLUDE_POSTGRESQL=yes \
  -DINCLUDE_MYSQL=yes \
  -DINCLUDE_REDIS=yes \
  -DINCLUDE_SQLITE=yes
cmake --build . -j$(nproc)

./exec/cwfr -c /path/to/config.json
Route — config.json
{
  "/": {
    "GET": {
      "file": "handlers/libindexpage.so",
      "function": "index"
    }
  }
}
Handler — handlers/indexpage.c
#include "http.h"

void index(httpctx_t* ctx) {
  ctx->response->send_data(
    ctx->response,
    "Hello world!"
  );
}

A handler is just a function — Each route loads a handler from a .so library. Read the request, build the response — nothing else to wire up.

Build & run guide →
Capabilities

Everything you need in one framework

A complete toolkit for modern web services — protocols, databases, security and utilities out of the box.

HTTP/3 · QUIC

A hand-written QUIC stack (RFC 9000) over UDP: TLS 1.3 handshake in one RTT, no head-of-line blocking, connection migration across networks — switch from Wi-Fi to LTE and the connection survives.

  • Parallel request streams over one connection
  • QPACK header compression
  • Trailers, 103 Early Hints, 100 Continue
  • Auto-advertised via Alt-Svc — clients upgrade themselves
Learn more →

HTTP/2

Up to 100 multiplexed streams, HPACK and Rapid Reset protection.

  • WebSocket over h2 (Extended CONNECT)
  • Trailers and 103 Early Hints
  • h2c upgrade for plaintext
Learn more →

WebSocket

Real-time channels with broadcasting and named groups.

  • Named channels and recipient filtering
  • permessage-deflate compression
  • Runs over HTTP/1.1 and HTTP/2 (Extended CONNECT)
Learn more →

HTTP/1.1

Full server and client: routing, vhosts, TLS.

  • Routes with dynamic parameters
  • Virtual hosts, regex domains, IDN
  • multipart/form-data and file uploads
Learn more →

Databases

Four drivers behind one unified API with ORM and migrations.

PostgreSQLMySQLRedisSQLite
  • ORM models and prepared statements
  • Schema migrations out of the box
  • Transactions and connection pools
Learn more →

Security

Authentication, sessions and RBAC without external services.

  • PBKDF2-HMAC-SHA256 password hashing
  • Sessions: files, Redis, DB (AES-256-GCM)
  • Rate limiting and data validators
Learn more →

Storage & Email

Local FS and S3 plus transactional email with DKIM.

  • S3-compatible services
  • multipart uploads into storage
  • SMTP client and email templates
Learn more →

Tooling

Template engine, i18n, JSON, JWT and the task scheduler.

  • gettext i18n: plurals, fallback
  • Scheduler: interval, daily, weekly
  • str_t with SSO, HashMap, JSON parser
Learn more →

And that is not all

Hot reload of handlers, logging, the HTTP client, scheduled tasks and more — in the docs.

Open the docs →
Performance

Measured on the same machine

Real container measurements: JSON processing, PostgreSQL queries and static file serving. Choose a workload to see its results and conditions.

Parse JSON and count top-level keys

POST /count · 1,048,576 bytes · 4,097 keys · nested objects and mixed types. One application worker, eight execution threads, identical nginx gateway and resource limits.

Medians of five 15-second runs.
Frameworkreq/sp99, msCPU/request, µsRSS median, MiB
cwfr (C)1,90846.133,35284.82
Spring Boot (Java)1,72743.924,124579.70
facil.io (C)8281,896.616,80237.80
Laravel (PHP)823112.999,082315.58
Fiber (Go)679493.5611,145200.59
Fastify (JavaScript)595568.0012,648540.44
Ruby on Rails (Ruby)267295.044,350241.94
Kore + Jansson (C)210448.1621,97673.18
Django (Python)179517.216,00088.33

p99 is the 99th percentile of request latency as seen by the load client: 99% of responses arrived faster. It covers the full round trip through the gateway, including queueing, not only application CPU time.

CPU covers application containers; gateway CPU is reported separately. Server: 8 logical CPUs on 4 physical cores, 2 GiB per container. Client: separate cores, 8 threads.

RSS is the sum of resident memory of application processes, including supervisors, sampled every 200 ms during load. The table shows the median of five run medians.

Testing

Tested, fuzzed and checked against the RFCs

There is more test code than framework code. Each layer catches what the others miss: unit tests pin down behaviour, fuzzers throw garbage at every parser, and integration suites restart, reload and overload a live server.

2,872unit tests

108,104 checks in 137 files, about 5 s under AddressSanitizer; separate runners keep HTTP/2 and HTTP/3 visible.

295checks on a real database

Real SQL against PostgreSQL, each run in its own schema; suites for MySQL, Redis and SQLite too.

47fuzz targets

HTTP/1–3, HPACK, QPACK, QUIC, WebSocket, JSON, JWT and templates. The last audit ran ~183M inputs.

20live-server suites

Hard and soft reload, QUIC migration, 0-RTT, IPv6, memory limits and soak runs against a real process.

147/147 · 49/49h2spec · h3spec

Every HTTP/2 and HTTP/3 conformance case passes; h2load pushed 300K requests without an error.

ASan · TSanplus UBSan and LSan

Not one memory error or data race reported under a 400K-request load.

Line coverage of the core by subsystem

46,007 executable lines, gcov. Sorted by test coverage.

Tests (unit + DB)Fuzzing
QUIC88.2%78.6%
WebSocket87.7%77.9%
HTTP/3 · QPACK85.2%71.0%
SMTP · mail73.8%50.8%
HTTP/1.1 · client72.9%54.8%
Utilities70.9%68.9%
Views, forms, sessions59.3%35.4%
Databases & ORM51.5%27.2%
HTTP/2 · HPACK50.7%73.6%
Server runtime41.3%21.2%

Who reaches which lines

Fuzzing alone reaches lines no test touches; together the layers cover more than either one.

70.0%of the core together · tests 65.1% · fuzzing 51.0%
  • Tests only19.0%
  • Tests and fuzzing46.0%
  • Fuzzing only5.0%
  • Not reached30.0%

Test code vs core code

Lines of C, shell and Python, counted the same way on both sides.

Core106,213
Tests109,877
  • Unit tests81,396
  • Fuzzing14,886
  • DB, integration, harnesses13,595

How it was measured — October 1, 2026: a --coverage build of the core, the unit and DB runners, then every fuzz target for 60 s. One script, ci.sh, runs all 24 stages — from the ASan and TSan builds to h3spec.

The test suite on GitHub →
Use Cases

What you can build

REST API

High-performance APIs for mobile and web applications

Real-time

Chats, notifications and live updates via WebSocket

Microservices

Microservices and monolithic applications

API Gateway

Request routing and proxying between services

Admin panels

Authentication, RBAC and CRUD operations

File uploads

Local and S3-compatible cloud storage

Email services

Transactional email sending with DKIM

i18n

Multilingual content with gettext and pluralization

Get started

Build fast web services in C

Read the introduction, browse the examples, or open the source on GitHub.

Released under the MIT License.