Official Runtimes

Runtimes are modules that transform your source code into Serverless Functions, which are served by our CDN at the edge.

Warning: In most cases, advanced Runtimes usage with configuration is not necessary. See the ZEIT Now Introduction documentation or the Serverless Functions documentation for more information.

Listed below are all official Runtimes from ZEIT.

Runtime
Description
The Node.js Runtime takes an entrypoint of a Node.js function, builds its dependencies (if any) and bundles them into a Serverless Function.
The Go Runtime takes in a Go program that defines a singular HTTP handler and outputs it as a Serverless Function.
The Python Runtime takes in a Python program that defines a singular HTTP handler and outputs it as a Serverless Function.
The Ruby Runtime takes in a Ruby program that defines a singular HTTP handler and outputs it as a Serverless Function.

Node.js

Status: Stable

The Node.js Runtime, by default, builds and serves Serverless Functions within the /api directory of a project, providing the files have a file extension of either .js or .ts.

A Node.js Serverless Function must export a default function handler, for example:

module.exports = (req, res) => {
  const { name = 'World' } = req.query
  res.send(`Hello ${name}!`)
}

An example serverless Node.js function using the Request and Response objects.

Note: The Node.js Runtime also supports asynchronous functions.

If you need more advanced behavior, such as a custom build step or private npm modules, see the Advanced Node.js Usage section.

Node.js Version

The default Node.js version used is 10.x but can be changed to 12.x by defining an engines property in a package.json file like in the example below:

{
  "engines": {
    "node": "12.x"
  }
}

Defining the engines property in a package.json file.

When defining an engines property, there are two different values that can be supplied, 10.x - the default if the property is not defined - or 12.x.

The .x portion of the engines value is required by our upstream providers and cannot be changed.

Warning: The only options that can be passed are 10.x or 12.x, passing any other value will cause your build to fail.

Node.js Dependencies

For dependencies listed in a package.json file at the root of a project, the following behavior is used:

  • If a package-lock.json file is present in the project, npm install is used.
  • Otherwise, yarn is used, by default.

Using TypeScript with the Node.js Runtime

The Node.js Runtime supports files ending with .ts inside of the /api directory as TypeScript files to compile and serve when deploying.

An example TypeScript file that exports a default Node.js function and takes in the standard Node.js Request and Response objects is as follows:

import { NowRequest, NowResponse } from '@now/node'

export default function(req: NowRequest, res: NowResponse) {
  const { name = 'World' } = req.query
  res.send(`Hello ${name}!`)
}

An example serverless Node.js function written in TypeScript, using types from the @now/node module for the helper methods.

The NowRequest and NowResponse imports in the above example are types that we provide for the Request and Response objects, including the helper methods with ZEIT Now. These types can be installed from npm with the following command:

npm install @now/node --save-dev

Installing @now/node for types when using Node.js on ZEIT Now.

You can also use a tsconfig.json file at the root of your project to configure the TypeScript compiler. Most options are supported aside from "Path Mappings" and "Project References".

Node.js Request and Response Objects

Each request to a Node.js Serverless Function gives access to Request and Response objects. These objects are the standard HTTP Request and Response objects from Node.js.

Node.js Helpers

ZEIT Now additionally provides helper methods inside of the Request and Response objects passed to Node.js Serverless Functions. These methods are:

method
description
object
req.query
An object containing the request's query string, or {} if the request does not have a query string.
Request
req.cookies
An object containing the cookies sent by the request, or {} if the request contains no cookies.
Request
req.body
An object containing the body sent by the request, or null if no body is sent.
Request
res.status(code)
A function to set the status code sent with the response where code must be a valid HTTP status code. Returns res for chaining.
Response
res.send(body)
A function to set the content of the response where body can be a string, an object or a Buffer.
Response
res.json(obj)
A function to send a JSON response where obj is the JSON object to send.
Response

The following Node.js Serverless Function example showcases the use of req.query, req.cookies and req.body helpers:

module.exports = (req, res) => {
  let who = 'anonymous'

  if (req.body && req.body.who) {
    who = req.body.who
  } else if (req.query.who) {
    who = req.query.who
  } else if (req.cookies.who) {
    who = req.cookies.who
  }

  res.status(200).send(`Hello ${who}!`)
}

Example Node.js Serverless Function using the req.query, req.cookies, and req.body helpers. It returns greetings for the user specified using req.send().

Note: If needed, you can opt-out of Now providing helpers using advanced configuration.

req.body

We populate the req.body property with a parsed version of the content sent with the request when possible.

We follow a set of rules on the Content-type header sent by the request to do so:

Content-Type header
Value of req.body
No header
undefined
application/json
An object representing the parsed JSON sent by the request.
application/x-www-form-urlencoded
An object representing the parsed data sent by with the request.
text/plain
A string containing the text sent by the request.
application/octet-stream
A Buffer containing the data sent by the request.

With the req.body helper, you can build applications without extra dependencies or having to parse the content of the request manually.


Go

Status: Alpha

The Go Runtime is used by Now to compile Go Serverless Functions that expose a single HTTP handler, from a .go file within an /api directory at your project's root.

For example, define an index.go file inside an /api directory as follows:

package handler

import (
  "fmt"
  "net/http"
)

func Handler(w http.ResponseWriter, r *http.Request) {
  fmt.Fprintf(w, "<h1>Hello from Go on Now!</h1>")
}

An example index.go file inside an /api directory.

For advanced usage, such as using private packages with your Go projects, see the Advanced Go Usage section.

Note: The exported function needs to include the HandlerFunc signature type, but can use any valid Go exported function declaration as the function name.

Go Version

Go version 1.x is used for Go projects deployed with ZEIT Now.

Go Dependencies

The Go Runtime will automatically detect a go.mod file to install dependencies at the root of a project.


Python

Status: Beta

The Python Runtime is used by Now to compile Python Serverless Functions, that defines a singlular HTTP handler variable, inheritting from the BaseHTTPRequestHandler class, from a .py file within an /api directory at your project's root.

For example, define an index.py file inside a /api directory as follows:

from http.server import BaseHTTPRequestHandler
from cowpy import cow

class handler(BaseHTTPRequestHandler):

    def do_GET(self):
        self.send_response(200)
        self.send_header('Content-type','text/plain')
        self.end_headers()
        message = cow.Cowacter().milk('Hello from Python from a ZEIT Now Serverless Function!')
        self.wfile.write(message.encode())
        return

An example index.py file inside an /api directory.

Inside requirements.txt define:

cowpy==1.0.3

An example requirements.txt file that defines cowpy as a dependency.

For advanced usage, such as using WSGI or ASGI for your Python projects, see the Advanced Python Usage section.

Python Version

Python projects deployed with ZEIT Now use Python version 3.6.

Python Dependencies

You can install dependencies for your Python projects by defining them in a requirements.txt or a Pipfile.lock file.


Ruby

Status: Alpha

The Ruby Runtime is used by Now to compile Ruby Serverless Functions that define a singlular HTTP handler from .rb files within an /api directory at your project's root.

Ruby files must have one of the following variables defined:

  • Handler proc that matches the do |req, res| signature.
  • Handler class that inherits from the WEBrick::HTTPServlet::AbstractServlet class.

For example, define a index.rb file inside a /api directory as follows:

require 'cowsay'

Handler = Proc.new do |req, res|
    res.status = 200
    res['Content-Type'] = 'text/plain'
    res.body = Cowsay.say('hello world', 'cow')
end

An example index.rb file inside an /api directory.

Inside a Gemfile define:

source "https://rubygems.org"

gem "cowsay", "~> 0.3.0"

An example Gemfile file that defines cowpy as a dependency.

For advanced usage, such as using a Rack Interface for your Ruby projects, see the Advanced Ruby Usage section.

Ruby Version

Ruby 2.5.5 is used.

Ruby Dependencies

This Runtime supports installing dependencies defined in the Gemfile. Alternatively, dependencies can be vendored with the bundler install --deployment command (useful for gems that require native extensions). In this case, dependencies are not built on deployment.

Advanced Usage

By default, no configuration is needed to deploy Serverless Functions to ZEIT Now.

For all officially supported languages (see below), the only requirement is creating a api directory and placing your Serverless Functions inside.

File Extensions
Language
.js, .ts
Node.js
.go
Go
.py
Python
.rb
Ruby

In order to customize the Memory or Maximum Execution Duration of your Serverless Functions, you can use the functions property.

Community Runtimes

If you would like to use a language that ZEIT Now does not support by default, you can use a Community Runtime by setting the functions property in now.json:

{
  "functions": {
    "api/test.php": {
      "runtime": "now-php@0.0.7"
    }
  }
}

The following Community Runtimes are recommended by ZEIT Now:

Note: If you would like to create a Community Runtime, see the Developing Your Own Runtime section.

Advanced Node.js Usage

In order to use this Runtime, no configuration is needed. You only need to create a file inside the api directory.

The entry point for src must be a glob matching .js or .ts files that export a default function. For more information on using this Runtime, see the Node.js Runtime section.

Disabling Helpers for Node.js

Within a now.json configuration file at your project's root, use the following build environment variable to disable helpers.

{
  "build": {
    "env": {
      "NODEJS_HELPERS": "0"
    }
  }
}

An example now.json file that will turn off the default helpers for your Node.js Serverless Function.

Private npm Modules for Node.js

To install private npm modules, define NPM_TOKEN as a build environment variable in now.json.

Alternatively, define NPM_RC as a build environment variable with the contents of ~/.npmrc.

Custom Build Step for Node.js

You can run build tasks by creating a now-build script within a package.json file at the entry point's level or higher. For example:

{
  "scripts": {
    "now-build": "node ./build.js"
  }
}

An example package.json file with a now-build script to execute in the build step.

Along with build script named build.js:

const fs = require('fs')
fs.writeFile('built-time.js', (module.exports = '${new Date()}'), err => {
  if (err) throw err
  console.log('Build time file created successfully!')
})

An example Node.js file, executed by the above package.json build script.

And a .js file for the built Serverless Functions, index.js inside the /api directory:

const BuiltTime = require('./built-time')
module.exports = (req, res) => {
  res.setHeader('content-type', 'text/plain')
  res.send(`
    This Serverless Function was built at ${new Date(BuiltTime)}.
    The current time is ${new Date()}
  `)
}

An example Node.js Serverless Function, using information from the created file from the build script.

Legacy Serverful Behavior

A Node.js Runtime entrypoint can contain one of the following to retain legacy serverful behavior:

  • Default export server, such as module.exports = http.createServer((req, res) => { res.end('hello') }).
  • Server listens on a port, such as http.createServer((req, res) => { res.end('hello') }).listen(3000).

AWS Lambda API

The Node.js Runtime provides a way to opt into the AWS Lambda API. This is useful if you have existing Serverless Functions you wish to deploy to ZEIT Now but do not want to change the API.

exports.handler = async function(event, context, callback) {
  return {
    statusCode: 200,
    headers: {},
    body: 'Hello world'
  }
}
{
  "build": {
    "env": {
      "NODEJS_AWS_HANDLER_NAME": "handler"
    }
  }
}

The value of the environment variable needs to match the name of the method that is exported from your Serverless Functions.

Advanced Go Usage

In order to use this Runtime, no configuration is needed. You only need to create a file inside the api directory.

The entry point of this Runtime is a global matching .go files that export a function that implements the http.HandlerFunc signature. For more information on using this Runtime, see the Go Runtime section.

Private Packages for Go

To install private packages with go get, define GIT_CREDENTIALS as a build environment variable in now.json.

All major Git providers are supported including GitHub, GitLab, Bitbucket, as well as a self-hosted Git server.

With GitHub, you will need to create a personal token with permission to access your private repository.

{
  "build": {
    "env": {
      "GIT_CREDENTIALS": "https://username:token@github.com"
    }
  }
}

An example now.json file containing a build environment variable with the value of GitHub credentials.

Advanced Python Usage

In order to use this Runtime, no configuration is needed. You only need to create a file inside the api directory.

The entry point of this Runtime is a glob matching .py source files with one of the following variables defined:

  • handler that inherits from the BaseHTTPRequestHandler class.
  • app that exposes a WSGI or ASGI Application.

Web Server Gateway Interface

The Web Server Gateway Interface (WSGI) is a calling convention for web servers to forward requests to web applications written in Python. You can use WSGI with frameworks such as Flask or Django.

Instead of defining a handler, define an app variable in your Python file, when using now.json config. For example, define a index.py file inside your project as follows:

from flask import Flask, Response
app = Flask(__name__)

@app.route('/', defaults={'path': ''})
@app.route('/<path:path>')
def catch_all(path):
    return Response("<h1>Flask on Now</h1><p>You visited: /%s</p>" % (path), mimetype="text/html")

An example index.py file, using Flask for a WSGI application.

Inside requirements.txt define:

flask==1.0.2

An example requirements.txt file, listing flask as a dependency.

Asynchronous Server Gateway Interface

The Asynchronous Server Gateway Interface (ASGI) is a calling convention for web servers to forward requests to asynchronous web applications written in Python. You can use ASGI with frameworks such as Sanic.

Instead of defining a handler, define an app variable in your Python file.

For example, define a index.py file inside a folder as follows:

from sanic import Sanic
from sanic.response import json
app = Sanic()


@app.route('/')
@app.route('/<path:path>')
async def index(request, path=""):
    return json({'hello': path})

An example index.py file, using Sanic for a ASGI application.

Inside requirements.txt define:

sanic==19.6.0

An example requirements.txt file, listing sanic as a dependency.

Advanced Ruby Usage

In order to use this Runtime, no configuration is needed. You only need to create a file inside the api directory.

The entry point of this Runtime is a glob matching .rb or .ru (for Rack) source files with one of the following variables defined:

  • Handler proc that matches the do |req, res| signature.
  • Handler class that inherits from the WEBrick::HTTPServlet::AbstractServlet class.

For more information on using this Runtime, see the Ruby Runtime section.

Alternatively, a .ru Rack config file will serve the Ruby application it contains.

Rack Interface

Many Ruby frameworks interface with Rack for forwarding HTTP requests to web applications written in Ruby. You can use Rack with frameworks such as Sinatra or Rails.

Instead of defining a handler, write the application as usual, like this Sinatra application:

require 'sinatra'

get '/*' do
    'Hello world'
end

An example Sinatra application.

Inside Gemfile define:

source "https://rubygems.org"

gem "sinatra", "~> 2.0"
gem "rack", "~> 2.0"

An example Gemfile file.

Add a Rack config file at index.ru to start the application:

require './app'

run Sinatra::Application

An example index.ru file.


Developing Your Own Runtime

Extending the feature-set of a ZEIT Now deployment is as simple as creating a Runtime that takes a list of files and outputs either static files or dynamic Serverless Functions.

A full API reference is available to help with creating Runtimes.


Technical Details

Caching Data

A runtime can retain an archive of up to 100mb of the filesystem at build time. The cache key is generated as a combination of:

  • Project name.
  • Team id or user id.
  • Entrypoint path (e.g., api/users/index.go).
  • Runtime identifier including version (e.g.: @now/go@0.0.1).

The cache will be invalidated if any of those items changes. The user can bypass the cache by running now -f.

Limits

  • Runtimes can run for a maximum of 5 minutes before the execution times out.
  • The maximum cache archive size of a Runtime is 100mb.
  • The cache TTL is 7 days.

Including Additional Files

Most Runtimes use static analysis to determine which source files should be included in the Serverless Function output based on the build src input. Any unused code or assets is ignored to ensure your Serverless Function is as small as possible.

For example, the Node Runtime looks at calls to require() or fs.readFile() in order to determine which files to include automatically.

// index.js
const { readFileSync } = require('fs');
const { join } = require('path');
const file = readFileSync(join(__dirname, 'config', 'ci.yml'), 'utf8');

This /index.js file reads the contents of /config/ci.yml.
The use of __dirname is necessary to read a file relative to the current file.

In some cases, you may wish to include templates or views that are not able to be statically analyzed. Runtimes provide a configuration for includeFiles that accepts an array of globs that will always be included in the Serverless Functions output.

{
  "functions": {
    "api/test.js": {
      "includeFiles": "templates/**"
    }
  }
}

Using the default Node.js language and configuring the includeFiles within a now.json configuration file.