Framework
boazsegev/facil.io avatar
boazsegev/facil.io

facil.io: a C micro-framework for HTTP and WebSocket servers

Your high performance web application C framework

2,407 stars151 forksCMIT

At a glance

What is it?
facil.io is an MIT-licensed C micro-framework that bundles an evented HTTP/1.1 and WebSocket server, dynamic types, JSON handling and a pub/sub cluster engine. It suits C developers who want to keep the network layer in C rather than delegate it to another runtime.
Who is it for?
Adopt facil.io when you want an evented HTTP and WebSocket server inside a C codebase and you are willing to pin a release tag rather than track master. Do not adopt it if you need HTTP/2, a built-in TLS stack, or a project that is documented as actively developed: the README says development happens in the facil.io C STL repo, the newest tagged release is 0.7.6 from 2022-02-19, and the last push to this repository was on 2026-04-14.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 170 days ago.
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 facil.io solves, and for whom

Writing a network server in C usually means assembling an event loop, a socket layer, an HTTP parser and a type system before you can answer a single request. facil.io packages those pieces together. The README describes it as "a C micro-framework for web applications" that includes a static file and application server speaking HTTP/1.1 and WebSocket, support for custom network protocols on both server and client connections, dynamic types (Strings, Hashes, Arrays), JSON parsing and formatting, a pub/sub process cluster engine, and optional connectivity with Redis.

The intended reader is a C programmer who wants to keep the serving layer in C. The framework targets Linux, BSD and macOS, and the README frames the design goal as providing "high performance TCP/IP network services" through an evented design with thread pool and forking support, aimed at the C10K problem. If your application is already C and you do not want to introduce a second runtime for the network edge, that is the case this project is built for. If you are not writing C, the framework has nothing to offer you.

The evented core and the http_s request object

The architecture visible in the README is a callback model. You register a handler when you start listening, and the framework calls it for each request. In the HTTP example, http_listen takes a port string, a binding (NULL means any available binding, which the comment equates with 0.0.0.0), and a struct of options including .on_request and .log. Then facil_start begins serving, with .threads controlling the thread count.

The handler receives an http_s pointer. From it you set cookies, set headers and send a body. The example uses http_set_cookie, http_set_header with HTTP_HEADER_CONTENT_TYPE, http_mimetype_find to look up a MIME type from a file extension, and http_send_body. Values passed around are FIOBJ objects, the dynamic type layer, allocated with fiobj_str_new and released with fiobj_free. The example deliberately allocates HTTP_X_DATA once in main and frees it at the end, which tells you the intended pattern: hoist values you reuse across requests instead of rebuilding them per request.

Around that core sit the other advertised pieces. The pub/sub process cluster engine handles local and WebSocket pub/sub, with Redis connectivity as an option. The examples folder points at concrete uses: examples/raw-echo.c for a telnet echo protocol, examples/raw-http.c for a simple hello world server, examples/http-chat.c for WebSocket pub/sub with optional Redis, plus http-hello.c, http_client.c, raw-chat.c and raw-client.c. Those file names are the fastest way to see the intended shape of a program before you commit to the framework.

Installing facil.io and serving a first request

facil.io is a source code library, and the README states it should be C99 compatible. GNU make is the default build system and CMake is also supported. There are three practical routes: generate a new project, copy the sources into an existing tree, or add the repository as a submodule.

The new-project route runs a script that creates a folder, downloads a copy of the stable branch, adds demo boilerplate and runs make clean, which the README says is required to build the tmp folder structure. Replace appname with your project name:

bash
bash <(curl -s https://raw.githubusercontent.com/boazsegev/facil.io/master/scripts/new/app) appname

After that, the README says to edit the makefile and remove generic features you do not need, naming DUMP_LIB, the DEBUG flag and the DISAMS disassembler as examples. Note the warning attached to that script: the master branch is the development branch, so for production you should select a release tag instead.

For an existing project, the makefile exposes two commands. make libdump writes the relevant files into a folder called libdump, which you can copy wholesale or split into headers and sources. make lib compiles the library separately.

bash
make libdump
make lib

If you prefer CMake, add the repository as a submodule and then reference it from your CMakeLists.txt:

bash
git submodule add https://github.com/boazsegev/facil.io.git
cmake
add_subdirectory(facil.io)

Meson users can install the wrap file and pull the dependency variable instead:

bash
meson wrap install facil
meson
facil_dep = subproject('facil').get_variable('facil_dep')

A minimal server follows the README example closely. Include http.h, define a handler that takes an http_s pointer, register it in http_listen with the port and .on_request, and call facil_start. The handler in the README sets a cookie named my_cookie with the value data, sets the content type from the txt extension, adds an X-Data header, and sends the body "Hello World!\r\n" with an explicit length of 14. Because the body length is passed explicitly, the string does not need to be null terminated for transmission, though the example's literal is.

Where facil.io is the wrong tool

The most important limitation is stated by the project itself: the master branch on the git repository is the development branch and is "likely to be broken at any given time", especially during major revisions. The README repeats the warning twice and tells you to select a release version for production. That is an unusual amount of emphasis, and it should shape how you consume the project. If your workflow is to track a default branch and rebuild continuously, this repository will fight you.

The protocol surface is another boundary. The README lists HTTP/1.1 and WebSocket. It does not claim HTTP/2 support; in the contributing section the author asks for help writing HPACK and HTTP/2 support, which tells you those are not present. There is also no built-in TLS in the advertised feature list. The same section asks for help writing a new SSL/TLS library or fitting an existing one into facil as source code, with the constraint that it must work in both client and server modes. If terminating TLS inside the process is a requirement, you are outside what the README documents.

Platform support is narrower than the phrase "high performance" might suggest. The framework targets Linux, BSD and macOS. The contribution section invites help adding Solaris or Windows support to evio and sock, which implies those platforms are not supported today. Finally, the release cadence visible in the release list is slow: 0.7.3 in 2019, 0.7.5 in 2020, 0.7.6 in 2022. The README also points elsewhere for ongoing work, saying development is currently performed in the facil.io C STL repo. The last push to this repository was on 2026-04-14, but the newest tagged release remains 0.7.6 from 2022-02-19.

How facil.io differs from libevent and libuv

The closest alternatives in spirit are libevent and libuv, and the difference is scope rather than speed. Those libraries give you an event loop and I/O primitives; you still bring your own HTTP parsing, your own type system and your own pub/sub layer. facil.io bundles all of that and fixes the programming model around it: an http_s request object, FIOBJ values, and a callback registered at listen time.

That bundling is the trade-off. You get a working HTTP and WebSocket server with far less assembly, and you inherit the project's choices about types, memory ownership and request handling. With libevent or libuv you keep full control of the data structures and can slot in a parser you already trust, at the cost of writing the HTTP layer yourself. There is also a category difference worth noting: Iodine, a Ruby HTTP and WebSocket application server, is powered by facil.io, so some users consume this project indirectly through a Ruby runtime rather than as a C library. If you are choosing between writing C and writing Ruby, that is a different decision than choosing between facil.io and libevent.

Licence, maintenance and upgrade cost

facil.io is MIT licensed. The repository carries both a LICENSE and a NOTICE file, and the README badge repeats the MIT identifier. In practical terms, MIT permits use in closed products, but the NOTICE file exists for a reason and should be read alongside the licence text; this is a description of what the repository contains, not legal advice, and your own counsel should confirm obligations for your distribution model.

Upgrade cost is dominated by the release model. Because master is a development branch, the sane upgrade path is to pin a release tag, read CHANGELOG.md between your pinned version and the target, and rebuild. The release titles give a rough sense of what patches carry: 0.7.6 is labelled a patch release with small bug fixes, 0.7.5 and 0.7.3 are labelled security and fixes. Two of the three visible releases carry security fixes, which is a reason to track releases rather than freeze indefinitely. The gap between 0.7.6 in 2022 and the last push in 2026 means you should check the changelog and the commit history yourself before assuming a given fix landed on the branch you build from.

There is also a build-system cost. If you take the new-project route, you are expected to edit the makefile and strip features you do not need, including DUMP_LIB, DEBUG and DISAMS. That is a small chore, but it means the generated makefile is a starting point rather than a finished configuration.

Editorial conclusion

Adopt facil.io when you want an evented HTTP and WebSocket server inside a C codebase and you are willing to pin a release tag rather than track master. Do not adopt it if you need HTTP/2, a built-in TLS stack, or a project that is documented as actively developed: the README says development happens in the facil.io C STL repo, the newest tagged release is 0.7.6 from 2022-02-19, and the last push to this repository was on 2026-04-14. Before writing application code, clone the repository, check out the release tag, run the new-project script or copy the libdump output, and confirm that your compiler is C99 compatible.

Frequently asked questions

Which platforms does facil.io support?

The README says facil.io provides high performance TCP/IP network services to Linux, BSD and macOS. The contribution section asks for help adding Solaris or Windows support to evio and sock, which implies those platforms are not supported today.

How do I start a new facil.io project?

Run the new-project script with your application name as the argument; the README shows bash <(curl -s https://raw.githubusercontent.com/boazsegev/facil.io/master/scripts/new/app) appname. The script creates a folder, downloads a copy of the stable branch, adds demo boilerplate and runs make clean.

Does facil.io support HTTP/2 or TLS?

The README lists HTTP/1.1 and WebSocket, and the contributing section asks for help writing HPACK and HTTP/2 support, so HTTP/2 is not advertised as present. The same section asks for help writing or fitting an SSL/TLS library, so no TLS stack is advertised either.

Can I use the master branch in production?

The README says the master branch is the development branch and is likely to be broken at any given time, and it tells you to select a release version for production needs. The newest release listed is 0.7.6 from 2022-02-19.

How do I add facil.io to an existing C project?

facil.io is a source code library, so you can copy the sources in. The makefile provides make libdump to write the relevant files into a libdump folder, and make lib to compile the library separately. CMake and Meson submodule routes are also documented in the README.

Official sources

  1. boazsegev/facil.io on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
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.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/boazsegev-facil-io.svg)](https://hysenlabs.com/projects/boazsegev-facil-io)