A minimalist, multi-threaded web server written in Zig, designed to mimic the simplicity and application-serving nature of uWSGI.
- Multi-threaded: Handles multiple connections concurrently using Zig's
std.Thread. - Minimalist: Uses only the Zig Standard Library (
std.net,std.Thread). - Educational: Every line of code is commented to explain the concepts.
- Application Container: Simulates an application entry point, similar to how uWSGI runs apps.
- Zig (0.13.0 or later recommended)
-
Clone the repository:
git clone https://github.com/hepidad/zws.git cd zws -
Run in Debug mode:
zig build run
-
Build Release: To build a small, optimized release binary:
zig build -Doptimize=ReleaseSmall
The binary will be available at
zig-out/bin/zws.
Once running, the server listens on http://127.0.0.1:8080.
You can test it with curl:
curl http://127.0.0.1:8080ZWS is designed as a minimalist foundation. To deploy real-world frameworks, you need to extend the application_entry_point in src/main.zig. Here are conceptual guides for common scenarios.
To serve Python applications (like uWSGI does), you would implement the WSGI (Web Server Gateway Interface) protocol.
Strategy:
- Embed Python: Link your Zig application with
libpython(usingbuild.zig). - Initialize: Start the Python VM in
main(). - Bridge: In
application_entry_point:- Convert the raw HTTP request into a Python dictionary (the WSGI
environ). - Call your Flask app's entry point (e.g.,
app(environ, start_response)). - Convert the Python response back to Zig bytes.
- Convert the raw HTTP request into a Python dictionary (the WSGI
Single Page Applications (SPAs) or Static Site Generators (SSGs) typically compile to static files (index.html, .js, .css).
Strategy:
- Build: Run
npm run build(oryarn build) in your frontend project to generate adist/orout/folder. - Serve Static Files: Modify
application_entry_pointto map the request URL to a file path.
Example Implementation Plan:
fn application_entry_point(request: []const u8) []const u8 {
// 1. Parse the path from the request (e.g., "GET /index.js ...")
// 2. Open the corresponding file in "./dist"
// 3. Return the file contents
// 4. Set the correct Content-Type (text/html, application/javascript)
}To use ZWS as a backend API server:
Strategy:
- Parse the incoming JSON body using
std.json. - Perform your business logic.
- Return a JSON string.
// Example response
return
\\HTTP/1.1 200 OK
\\Content-Type: application/json
\\
\\{"status": "ok", "message": "Hello from ZWS API"}
;This project is licensed under the MIT License - see the LICENSE file for details.