Express Web Server
A small Express 5 blog app — JSON API (/api/posts, /api/posts/:slug, /api/runtime), server-rendered article pages, and a static HTML/CSS/JS frontend — running on GJS through @gjsify/http. Express imports unmodified from npm; gjsify’s Node compat layer serves every http.Server / IncomingMessage / ServerResponse API call Express reaches for.
What it exercises
Section titled “What it exercises”| Pillar | What Express needs |
|---|---|
@gjsify/http | http.createServer(), Server.listen(), full IncomingMessage (close-only-via-destroy per Node semantics) + ServerResponse API |
@gjsify/stream | req.pipe(res), body parsing |
@gjsify/events | EventEmitter with enumerable prototype methods (Express 5 requires this for some middleware) |
@gjsify/url | URL parsing in Express’s route matcher |
libsoup-3.0 | The TCP listener + HTTP/1.1 parser under @gjsify/http |
Run it on GJS
Section titled “Run it on GJS”gjsify showcase express-webserverStarts a Gtk.Application-less GLib mainloop with Express bound to http://127.0.0.1:3000. Open the page or hit the API with curl:
curl http://127.0.0.1:3000/api/posts# → {"count":…,"posts":[…]}
curl http://127.0.0.1:3000/api/runtime# → {"runtime":"GJS","platform":"linux","version":"…","time":"…"}The same Express app would behave identically under Node — there’s no GJS-specific branch in src/index.ts. That’s the load-bearing claim.
Run it under Node (for comparison)
Section titled “Run it under Node (for comparison)”cd showcases/node/express-webservergjsify run buildgjsify run start:nodeThe package ships both start (GJS) and start:node scripts; same src/index.ts, two bundles (dist/index.gjs.js, dist/index.node.mjs).
Source
Section titled “Source”showcases/node/express-webserver/
src/index.ts— the whole Express app: middleware, JSON API, server-rendered HTML pages,app.listen()(npmexpressimport, no@gjsify/*in the request path)src/data/posts.ts— in-memory blog post fixtures consumed by the API + HTML routessrc/public/— static frontend (index.html,style.css,app.js) served viaexpress.static()
Why Express specifically
Section titled “Why Express specifically”Express is the most-deployed Node web framework on the planet. If gjsify’s http package can carry Express 5 unmodified — including middleware composition, error handling, route matching — then arbitrary npm web apps targeting Node tend to “just work” on GJS too. This showcase is the canary.
Integration coverage for the broader npm web ecosystem (Socket.IO, axios, WebTorrent, …) lives under tests/integration/ — they all dovetail with the same @gjsify/http + @gjsify/stream surface.
Related
Section titled “Related”refs/socket.io/— Socket.IO useshttp.Serverdirectly; the integration suite undertests/integration/socket.io/is the multi-client validationrefs/undici/— Node’s fetch / HTTP client reference, separate from@gjsify/httpbut the same socket plumbing@gjsify/http— the package itself