deno-cgi provides an embeddable
Common Gateway Interface (CGI)
implementation for Deno.
It allows you to run shell scripts, CGI programs, or other executables directly from a Deno HTTP server.
import { executeCgi } from "jsr:@gapotchenko/deno-cgi";
const script = `echo "$SERVER_PROTOCOL 200 OK"
echo "Content-Type: text/plain;charset=UTF-8"
echo
echo "Hello CGI"`;
Deno.serve(async (request) =>
await executeCgi(request, "/bin/sh", ["-c", script])
);Start the server with deno run and visit http://localhost:8000 to see the
CGI output.
By default, deno-cgi runs the CGI program to completion, buffers its output,
and then sends the entire response at once. This is a simple mode that works
well for short responses.
For long-running scripts or continuous output, you can enable streaming mode.
The streaming mode allows to stream a CGI command response in chunks as soon as
they arrive. To accomplish that, the options object should be passed to
executeCgi function with streaming property set to true:
await executeCgi(
request,
"/bin/sh",
["-c", script],
{ streaming: true },
);This reduces latency and allows having extremely large responses without wasting RAM.
- Implements the CGI/1.1 spec (RFC 3875)
- Compatible with any executable: shell scripts, compiled binaries, or interpreters
- Automatically sets CGI environment variables (e.g.
REQUEST_METHOD,QUERY_STRING,SERVER_PROTOCOL) - Ensures that CGI responses are HTTP-compliant
- Supports both batch and streaming response modes
- Embedding legacy CGI scripts into a modern Deno server
- Running shell commands as HTTP endpoints (with proper sandboxing!)
- Prototyping HTTP services quickly without a full web framework
Running arbitrary shell commands or executables in response to HTTP requests can be dangerous. Make sure to:
- Validate and sanitize any user input passed to scripts
- Restrict access where appropriate
- Consider sandboxing (e.g. using bwrap or containers)
To assist you with user input validation, the module provides isReservedCgiEnvVar
function.
You can use deno-cgi from: