Serve Static Files

Static files are served directly.

For example, you can drop a photo into your content directory and it'll be accessible:

The photo.

Render Handlebars Templates

Handlebars templates are rendered at request time.

Templates can embed content from other files—even static files and executables—via {{get "/file"}}. For example, this content comes from a template, and here's a random number generated by an executable: 38

Templates are provided render data with information about the request, the server, etc.

Run Executables

Executables in the content directory are run at request time, with standard output piped out as the response body.

Any program that you can run from the command line will work (scripts, compiled binaries, etc). For example, this timestamp is the output of a shell script:

now.html.sh: 2024-06-25T18:27:23Z

Since executables are run as normal programs by your operating system, you can freely mix and match whatever languages you like:

foo.html.js: hello from node, my pid is 137769
bar.html.py: hi from python 3.9.2 running on linux
baz.html.awk: happy Tuesday the 25th from awk (in UTC)

Executables are provided render data encoded as JSON in an environment variable named OPERATOR_RENDER_DATA.

Content Negotiation

Content negotiation is performed based on the Accept header.

Multiple representations of the same content can be provided by creating files whose names differ only by extension. For example, if you have image.png and image.webp, the server will be able to satisfy GET /image as either image/png or image/webp. "Negotiation" means that Operator uses the representation which best fits the client's preferences. For example, your browser prefers Image in PNG or WebP format, depending on your browser..

Request URLs with file extensions override the Accept header. For example, you can GET /image.png or GET /image.webp to retrieve a specific type no matter which your browser prefers.


Operator sends chunks of the response body as soon as possible. It doesn't wait for the entire response to be generated.

For example, with a script that gradually emits its response body the client can begin processing the response while the script is still running. In this case the <style> elements are applied one at a time, creating a colorful effect.

Hidden Files

File/directory names which start with _ are hidden from routing, but are still accessible by other files in the content directory. This can be useful for partials, scripts, or other things which don't make sense out of context.

For example, this site has a file named _header.html.hbs in the root of its content directory, but requests for GET /_header will receive 404 responses instead of the HTML for the page header.

Additionally, file/directory names which start with . are always completely ignored by Operator. You can safely use them for whatever you want.

Error Handlers

You can specify a custom error handler for Operator.

For example, this site uses a custom error handler which presents a friendly message. You can see it in action by visiting a bogus URL.

Error handlers are configured via the --error-handler-route command-line argument. They receive an error-code variable in their input.