Skip to content

I built a web server without installing a single package

Last week I needed a quick API for a side project. Nothing fancy — a few routes, a SQLite database, some JSON. The kind of thing you'd reach for Express or Flask for.

Instead I wrote it in Wyn. Here's the entire server:

wyn
fn handle(method: string, path: string, body: string, fd: int, db: int) {
    if method == "GET" && path == "/api/users" {
        var rows = Db.query(db, "SELECT id, name FROM users")
        Http.respond(fd, 200, "application/json", "{\"users\": \"${rows}\"}")
    } else if method == "POST" && path == "/api/users" {
        var doc = Json.parse(body)
        var name = Json.get(doc, "name")
        Db.exec(db, "INSERT INTO users(name) VALUES('${Db.escape(name)}')")
        Http.respond(fd, 201, "application/json", "{\"ok\": true}")
    } else {
        Http.respond(fd, 404, "application/json", "{\"error\": \"not found\"}")
    }
}

fn main() {
    var db = Db.open("app.db")
    Db.exec(db, "CREATE TABLE IF NOT EXISTS users(id INTEGER PRIMARY KEY, name TEXT)")
    var server = Http.serve(8080)
    println("Running on http://localhost:8080")

    while true {
        var req = Http.accept(server)
        var method = req.split_at("|", 0)
        var path = req.split_at("|", 1)
        var body = req.split_at("|", 2)
        var fd = req.split_at("|", 3).to_int()
        spawn handle(method, path, body, fd, db)
    }
}

That's it. HTTP server, JSON parsing, SQLite database, concurrent request handling with spawn. No npm install. No pip install. No go get. Zero dependencies.

What's happening here

Http.serve binds a socket. Http.accept blocks until a request comes in. spawn handle(...) fires off each request as a lightweight coroutine — so one slow request doesn't block the others.

Db.open opens a SQLite database. Json.parse parses JSON. These are all built into Wyn's standard library.

The compiled binary is about 200KB. You can scp it to a server and run it. No runtime to install, no Docker container needed (though we have one if you want it).

The comparison that matters

To build the same thing in Node.js:

npm install express body-parser better-sqlite3

That's 47 transitive dependencies. 12MB of node_modules. A package.json, a package-lock.json, and a Node.js runtime on the server.

In Go it's better — the stdlib has net/http and encoding/json. But you still need a SQLite driver (go get github.com/mattn/go-sqlite3), which requires CGO and a C compiler on the build machine.

In Wyn, you type wyn build main.wyn and get a binary. That's the whole story.

The honest tradeoffs

Wyn is v1.8. It's not Go. The ecosystem is small. If you need a Kafka client or a gRPC library, you're writing it yourself or waiting for someone else to.

The type checker catches most errors at compile time, but it's not Rust-level exhaustive. You'll occasionally hit a runtime error that a stricter type system would have caught.

And the community is tiny. You're not going to find Wyn answers on Stack Overflow.

But for the kind of project where you'd normally reach for Express + SQLite + a handful of npm packages? Wyn is genuinely faster to build with. Not because the language is magic, but because everything you need is already there.

Try it

bash
curl -fsSL https://wynlang.com/install.sh | sh
wyn run server.wyn

The server starts in under 300ms. The binary is 200KB. And you didn't install a single package.

MIT License