Official Runtimes
Runtimes are modules that transform your source code into Serverless Functions, which are served by our CDN at the edge.
Listed below are all official Runtimes from Vercel.
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
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 .js
, .mjs
, 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.
If you need more advanced behavior, such as a custom build step or private npm modules, see the Advanced Node.js Usage section.
Callback Function
When you have finished processing your request, you need to invoke the callback
function to emit a response and signal that your Function has completed its execution. The callback
method will automatically determine the data type of your response and serialize the output appropriately.
You must invoke the callback
method when your Function is done processing. Failure to invoke callback
will cause your Function to continue running up to the execution time limit. When your Function reaches the execution time limit, it will be terminated, and a 504 Gateway timeout error will be returned to the client.
module.exports = (request, callback) => {
someMethodThatReturnsPromise()
.then((result) => {
// executed after the someMethodThatReturnsPromise() resolves
console.log(result);
// Callback is placed inside the successful response of the request
return callback();
})
.catch((error) => {
console.error(error);
// Callback is also used in the catch handler to end execution on errors
return callback(error);
});
};
Callback and Asynchronous Limitations
It is important to note that when the callback
function is invoked, it will terminate all execution of your Function. This includes any asynchronous processes you may have kicked off during the execution of your exports
method.
For this reason, if you are using libraries that are natively asynchronous and/or operate using Promises, you must properly handle this asynchronous behavior. Structure your code to call callback within the correct callback
methods, .then
chains, or after await
in async
functions.
How do I return an error?
If you have encountered an exception in your code or otherwise want to indicate an error state, invoke the callback
method with the error object or intended message as a single parameter:
return callback(error);
How do I return a successful response?
To signal success and return a value, pass a falsy value such as null
or undefined
as the first parameter to callback
, and your intended response as the second parameter:
return callback(null, response);
Node.js Version
Whenever a new Project is created, the latest Node.js LTS version available on Vercel at that time is selected for it.
This selection will be reflected within the Node.js Version section on the General page of the Project Settings. If needed, you can also customize it there:
Selecting a custom Node.js version for your Project.
Currently, the following Node.js versions are available:
- 16.x (default since May 9th 2022)
- 14.x (introduced February 4th 2021)
- 12.x (deprecated since May 20th 2022)
- 10.x (disabled since April 20th 2021)
As you can see, only major versions are available. That's because Vercel will automatically roll out minor and patch updates if needed (for example in the case that a security issue needs to be fixed).
Defining the node
property inside engines
of a package.json
file will override the selection made in the Project Settings and print a Build Step warning if the version does not match. Please avoid greater than ranges, such as >14.x
or >=14
, because this will match semver major versions of Node.js once available which contains breaking changes.
For example, the range >14.2.0
would match the versions 14.2.5
, 14.2.8
, 14.3.0
, and 16.0.0
.
In order to find out which Node.js version your Deployment is using, run node -v
in the Build Command or log the output of process.version
.
Node.js Dependencies
For dependencies listed in a package.json
file at the root of a project, the following behavior is used:
yarn install
is used by default- If a
pnpm-lock.yaml
file is present in the project,pnpm install
is used. - If a
package-lock.json
file is present in the project,npm install
is used.
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 type { VercelRequest, VercelResponse } from '@vercel/node';
export default function (req: VercelRequest, res: VercelResponse) {
const { name = 'World' } = req.query;
res.send(`Hello ${name}!`);
}
An example serverless Node.js function written in TypeScript, using types from the @vercel/node
module for the helper methods.
The VercelRequest
and VercelResponse
imports in the above example are types that we provide for the Request and Response objects, including the helper methods with Vercel. These types can be installed from npm with the following command:
npm install @vercel/node --save-dev
Installing @vercel/node
for types when using Node.js on Vercel.
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
Vercel 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 |
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 |
res.redirect(url) | A function to redirect to the URL derived from the specified path with status code "307 Temporary Redirect". | Response |
res.redirect(statusCode, url) | A function to redirect to the URL derived from the specified path, with specified HTTP status code. | 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()
.
helpers
using advanced configuration.Request 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.
req.body
helper is set using a JavaScript getter. In turn, it is only computed when it is accessed.When the request body contains malformed JSON, accessing req.body
will throw an error. You can catch that error by wrapping req.body
with try...catch
:
try {
req.body;
} catch (error) {
return res.status(400).json({ error: 'My custom 400 error' });
}
Catching the error thrown by req.body
with try...catch
.
Go Beta
The Go Runtime is used by Vercel 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!</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.
HandlerFunc
signature type, but can use any valid Go exported function declaration as the function name.Go Version
The Go Runtime will automatically detect the go.mod
file at the root of your Project to determine the version of Go to use.
If go.mod
is missing or the version is not defined, the default version 1.16 will be used.
Go Dependencies
The Go Runtime will automatically detect the go.mod
file at the root of your Project to install dependencies.
Go Build Configuration
You can provide custom build flags by using the GO_BUILD_FLAGS
Environment Variable.
{
"build": {
"env": {
"GO_BUILD_FLAGS": "-ldflags '-s -w'"
}
}
}
An example -ldflags
flag with -s -w
. This will remove debug information from the output file. This is the default value when no GO_BUILD_FLAGS
are provided.
Python Beta
The Python Runtime is used by Vercel to compile Python Serverless Functions, that defines a singular 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 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 Vercel use Python version 3.9.
You can specify the version of Python by defining python_version
in Pipfile
, like so:
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
flask = "*"
[requires]
python_version = "3.9"
An example Pipfile
generated withpipenv install flask
.
Currently, the following Python versions are available:
python_version
must exactly match one of the options above or it will be ignored.Python Dependencies
You can install dependencies for your Python projects by defining them in requirements.txt
or a Pipfile
with corresponding Pipfile.lock
.
Ruby Beta
The Ruby Runtime is used by Vercel to compile Ruby Serverless Functions that define a singular 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 thedo |req, res|
signature.Handler
class that inherits from theWEBrick::HTTPServlet::AbstractServlet
class.
For example, define a index.rb
file inside a /api
directory as follows:
require 'cowsay'
Handler = Proc.new do |req, res|
name = req.query['name'] || 'World'
res.status = 200
res['Content-Type'] = 'text/text; charset=utf-8'
res.body = Cowsay.say("Hello #{name}", '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 cowsay
as a dependency.
Ruby Version
New deployments use Ruby 2.7.x as the default version.
You can specify the version of Ruby by defining ruby
in a Gemfile
, like so:
source "https://rubygems.org"
ruby "~> 2.7.x"
When defining a Ruby version, the following Ruby versions can be selected:
- 2.7.x (default)
- 2.5.x (disabled since November 30th 2021)
2.7.1
it will be ignored and assume the latest 2.7.x
.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 Vercel.
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 Vercel does not support by default, you can use a Community Runtime by setting the functions
property in vercel.json
:
{
"functions": {
"api/test.php": {
"runtime": "vercel-php@0.1.0"
}
}
}
The following Community Runtimes are recommended by Vercel:
Runtime | Runtime Module | Docs |
---|---|---|
Bash | vercel-bash | |
Deno | vercel-deno | |
PHP | vercel-php | |
Rust | now-rust |
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
, .mjs
, 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
Add an Environment Variable with name NODEJS_HELPERS
and value 0
to disable helpers.
Private npm Modules for Node.js
To install private npm modules, define NPM_TOKEN
as an Environment Variable in your Project.
Alternatively, define NPM_RC
as an Environment Variable with the contents of ~/.npmrc
.
Custom Build Step for Node.js
In some cases, you may wish to include build outputs inside your Serverless Function. You can run a build task by adding a vercel-build
script within your package.json
file, in the same directory as your Serverless Function or any parent directory. The package.json
nearest to the Serverless Function will be preferred and used for both Installing and Building.
For example:
{
"scripts": {
"vercel-build": "node ./build.js"
}
}
An example package.json
file with a vercel-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 Vercel 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
, add an Environment Variable named GIT_CREDENTIALS
.
The value should be the URL to the Git repo including credentials, such as https://username:token@github.com
.
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.
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 theBaseHTTPRequestHandler
class.app
that exposes a WSGI or ASGI Application.
Reading Relative Files in Python
Python uses the current working directory when a relative file is passed to open().
The current working directory is the base of your project, not the api/
directory.
For example, the following directory structure:
├── README.md
├── api
| ├── user.py
├── data
| └── file.txt
└── requirements.txt
With the above directory structure, your function in api/user.py
can read the contents of data/file.txt
in a couple different ways.
You can use the path relative to the project's base directory.
# api/user.py
from http.server import BaseHTTPRequestHandler
from os.path import join
class handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/plain')
self.end_headers()
with open(join('data', 'file.txt'), 'r') as file:
for line in file:
self.wfile.write(line.encode())
return
Or you can use the path relative to the current file's directory.
# api/user.py
from http.server import BaseHTTPRequestHandler
from os.path import dirname, abspath, join
dir = dirname(abspath(__file__))
class handler(BaseHTTPRequestHandler):
def do_GET(self):
self.send_response(200)
self.send_header('Content-type','text/plain')
self.end_headers()
with open(join(dir, '..', 'data', 'file.txt'), 'r') as file:
for line in file:
self.wfile.write(line.encode())
return
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 vercel.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</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.
Developing Your Own Runtime
Extending the feature-set of a Vercel 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.:
@vercel/go@0.0.1
).
The cache will be invalidated if any of those items changes. The user can bypass the cache by running vercel -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 a glob of files 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 vercel.json configuration file.