Hydrator - rehydrated static files

NPM version

Hydrator is a web application tool and hosting service for semi-static sites. It maps URL paths to files, compiling certain kinds of assets on-the-fly, as appropriate. Hydrator also allows for dynamic content, with JavaScript files that can be executed to generate a response. Think AWS Lambda meets Surge.sh.

Static files (.html, .js, .css, .jpg, …) are passed through. Compilable files (.md, .coffee, .sass) are compiled and returned. JavaScript files with a .hydrator.js extension are considered executable. Instead of being compiled and returned, they are executed inside a sandbox and given helpers for generating a response.

The bare minimum for a dynamic file is calling response.ok() with response text:

response.ok(`Hello, world! ${ new Date() }`)

CoffeeScript, JSX, and CJSX may also be used for executable files. For example, using JSX

View = (props) => (
        <h1>Hello, world!</h1>
        <p>{ props.date }</p>

response.ok(<View date={ new Date() } />);



  1. npm install --global hydrator
  2. mkdir my-project
  3. echo "response.ok('Hello, world! ' + new Date())" > my-project/index.hydrator.js
  4. hydrator deploy my-project --email user@example.com

The project is now deployed at sparkling-waterfall-62f644.rehydrated.site.


Hydrator works as a CLI, and is best used when installed globally:

$ npm install --global hydrator



Create a new Hydrator project.

$ hydrator create <project_name>

All this does is create a folder of the specified name. Optionally, the project can be filled out using a sample project:

$ hydrator create <project_name> --sample


Start the Hydrator server using the given current project.

$ hydrator serve <project_name>
Server listening at localhost:5000...

hydrator serve . or hydrator serve from inside the project folder also work.

By default, the server listens to hostname localhost and port 5000. To customize this, use the --host and --port options, eg hydrator serve --host --port 8000.


List the mapping of source file to URLs.

$ hydrator urls .
/Icon.png                      --> /Icon.png
/api/compare-dates.hydrator.js --> /api/compare-dates/*
/form-and-fetch.hydrator.cjsx  --> /form-and-fetch/*
/index.hydrator.js             --> /
/markdown-content.md           --> /markdown-content.md
/rich-app/api.hydrator.js      --> /rich-app/api/*
/rich-app/app-laf.scss         --> /rich-app/app-laf.css
/rich-app/app.jsx              --> /rich-app/app.js
/rich-app/app.scss             --> /rich-app/app.css
/rich-app/index.html           --> /rich-app/
/rich-app/loader.gif           --> /rich-app/loader.gif
/script.coffee                 --> /script.js
/style.scss                    --> /style.css


Hydrator has a companion hosting service. Simply run hydrator deploy from the project folder and it will be deployed to the world:

$ hydrator deploy
Creating host...done!
Uploading project...done!
Project successfully uploaded to sparkling-waterfall-62f644.rehydrated.site

The details of the deployment are stored in a .rehydrator.json file in the project folder. Don‘t lose or share it! It contains the key for deploying to that host. If you do, let me know and I’ll figure something out.

(The first deploy, an email address is required for verification in case of the above scenario. The address itself is not transmitted, only a bcrypt hash is. It will be saved and reused for all subsequent deployments, though it can be overridden using the --email option.)

Custom subdomain

By default, the hostname will be randomly generated. It can be customized using the --host <name> option:

hydrator deploy --host example will deploy to example.rehydrated.site (if available).

Fully custom host

hydrator deploy --host example.com will deploy to example.com (if available). This requires changing your DNS settings to point an ALIAS/CNAME record to rehydrated.site. CloudFlare and DNSimple provide CNAME or ALIAS support for apex domains.

Multiple hosts

A project can be deployed to multiple hosts by specifying a new host through the --host <hostname> option, or to another randomly generated subdomain using --auto. There is no limit to how many hosts a project can be deployed to.


List the hosts the project is deployed to.

$ hydrator hosts .

Project is deployed to:
* example.rehydrated.site
* sparkling-waterfall-62f644.rehydrated.site


Destroy the specified remote host. The --host <hostname> option is required for this.


A Hydrator project consists of a folder. No special files or directory structure need to be created. The URLs for the project will map onto the on-disk filenames.

For example, the following project structure maps to these URLs:

    index.html          - /
    about.md            - /about/
    api.hydrator.coffee - /api/*
    data.json           - /data.json
    _info.md            - 404
        index.md        - /some-path/
        info.md         - /some-path/info/
        script.coffee   - /assets/script.js
        style.sass      - /assets/style.css
        icon.png        - /assets/icon.png
        module.coffee   - /other-files/module.js
        library.js      - /other-files/library.js

A request to / is served by the /index.html file (could also be /index.hydrator.js or /index.md). /about/ is handled by the /about.md file, which is compiled into HTML on-the-fly. /assets/script.js matches the corresponding CoffeeScript source file, which is compiled to JavaScript and served. /api/, and any paths under that, are handled by /api.hydrator.coffee, which is compiled to JavaScript and executed inside a sandbox. The file /_info.md starts with an underscore, and is not visible externally.

URLs generally match the file by path. Non-compilable or -executable files are simply returned as-is. Files that can be compiled from Markdown or CoffeeScript match a URL suitable for their output (and cannot be served in raw form). Executable files will match anything in their subtree. The catchall.hydrator.js file can be used as a catch-all, and if present will handle any request if it’s not matched by something else. Like compiled files, these executable files cannot be served directly. Note: files and folders beginning with an underscore are considered private and will return a 404 if attempted to be reached directly. URLs that do not end in a trailing slash but should (as in not directed at a file) are redirected to the URL with a trailing slash. A URL like /about goes to /about/, while /script.js does not.


Executable files are run inside a sandbox that is given globals with information about the current request, functions to send a response, and various helpers and utilities. These files cannot require any modules.

The sandbox globals are:


Alec Perkins