js-cgi is a lightweight CGI engine for running modern JavaScript on your server. Write .js files, drop them on your server, and they just run — no bundler, no framework, no node_modules.
const name = request.query.name || "World";
const time = new Date().toLocaleTimeString();
response.setHeader("X-Powered-By", "js-cgi");
print(`<h1>Hello, ${name}!</h1>`);
print(`<p>Server time: ${time}</p>`);
Full ES2023+ support. Modules, async/await, destructuring, template literals, classes — all of it.
No build step, no framework boilerplate. Run js-cgi --serve, save your file, hit refresh. That's it.
Shared library extensions add SQLite, MySQL, sessions, file I/O, crypto, and HTTP. Write your own in C.
~1.3MB binary. No runtime dependencies. No package manager. Just JavaScript and your web server.
Memory limits, execution time limits, and no I/O unless explicitly enabled. Safe for shared hosting.
Use import/export to organise your code. Paths resolve relative to your script automatically.
response.setHeader("Content-Type", "application/json");
const db = sqlite.open("/var/www/data/app.db");
const users = db.query("SELECT id, name FROM users LIMIT ?", [20]);
db.close();
print(JSON.stringify({ users }));
if (request.method === "POST") {
const data = JSON.parse(request.body);
const hash = crypto.sha256(data.password);
const db = sqlite.open("/var/www/data/app.db");
const user = db.queryOne(
"SELECT * FROM users WHERE email = ? AND password = ?",
[data.email, hash]
);
db.close();
if (user) {
session.start();
session.set("user_id", user.id);
print(JSON.stringify({ success: true }));
} else {
response.setStatus(401);
print(JSON.stringify({ error: "Invalid credentials" }));
}
}
const payload = JSON.parse(request.body);
const signature = crypto.hmac("sha256", "secret", request.body);
if (request.headers["x-signature"] !== signature) {
response.setStatus(403);
print("Forbidden");
} else {
file.append("/var/log/webhooks.log", JSON.stringify(payload) + "\n");
print("OK");
}
const res = http.get("https://api.example.com/data", {
"Authorization": "Bearer " + request.cookies.token
});
response.setHeader("Content-Type", "application/json");
response.setStatus(res.status);
print(res.body);
One static binary. No runtime to configure, no service to babysit. Currently available for Linux (x86_64, arm64). macOS and Windows coming soon.
$ curl -sSL https://js-cgi.com/install.sh -o install.sh
$ sudo bash install.sh
# Or try instantly with the built-in dev server:
$ js-cgi --serve 8000
| Extension | Global | Description |
|---|---|---|
| sqlite.so | sqlite | SQLite database with parameterised queries and transactions |
| session.so | session | Cookie-based sessions with file storage |
| file.so | file | Filesystem read, write, append, delete, list |
| crypto.so | crypto | MD5, SHA, HMAC, random bytes, UUID generation |
| http.so | http | Outbound HTTP client (GET, POST, PUT, DELETE) |
| mysql.so | mysql | MySQL database with parameterised queries and transactions |
| smtp.so | smtp | Send emails via SMTP with TLS support |
js-cgi is currently in beta. While we have taken every precaution to ensure stability and correctness, this software is provided as-is without warranty of any kind. We are not liable for any damages or issues arising from its use.
If you encounter bugs, unexpected behaviour, or have feature requests, please report them on GitHub Issues. Community feedback is essential to making js-cgi production-ready.