Now 2.0

Today we are proud to present Now 2.0 to the world. Our new platform simplifies the organization of your codebase, while dramatically improving the reliability and scalability of your deployments.

From the outside, the ease of use of now remains unchanged. Just write code in your favorite language or framework and push.

Behind the scenes, Now 2.0 works like an extensible build system and compiler, capable of transforming your sources into static files and serverless functions (lambdas) for production.

The Now 2.0 platform features include:

  • A unified deployment type: All deployments are one type, regardless of static or dynamic parts
  • Massive build parallelization: Each deployment can kick off many concurrent serverless builds.
  • Monorepo support: Define API endpoints in Go, PHP, Node.js, Next.js, and such, in just one repository.
  • Zero-instruction builds: Our open-source builders take the build and cache config burden away.
  • Universal Cloud: Our platform leverages the best cloud infrastructure, with no lock-in or config.

With the following pricing improvements:

  • Fully on-demand pricing: Pay exactly for what you use, starting at $0.
  • Per-100ms pricing for compute: Pay by the cycle of compute for dynamic workloads.
  • Free seats for small teams. Up to 5 included at no cost for paid customers.

Including a better free-tier for our community:

  • Private and secure sources at all times. No public vs private config.
  • No concurrency limits. 1,000 free lambda invocations per day.
  • Built in free Now CDN, with new locations being added regularly.

A Walkthrough

Let's start with a simple folder or GitHub repository with a simple contact form that gets received by a script and sent to Airtable:

Our sample project with some source files. One we intend to serve directly, one to invoke on-demand.

Our new CLI shows the generated outputs from a build. In this case, just our source files.

Let's navigate to /contact.php:

Our source code to handle the form submission being served statically, as plain text.

As you can see, we are leaking all our source code and it doesn't seem to work.

The reason, however, is that we deployed our source files without any build steps that can transform them into other static files or lambdas. Let's fix that.

{ "builds": [ { "src": "*.php", "use": "@now/php" }, { "src": "*.html", "use": "@now/static" } ]

Our now.json now defines two builds. One to create .php functions and one to carry over static files.

The deployment outputs a static file (index.php) and a lambda (contact.php)

As we can see in the updated Now CLI visual feedback, adding @now/php resulting in the processing of a build that outputted a lambda, identified with λ.
The @now/php identifier refers to an npm package whose purpose is to execute the build logic. We call it a Builder.
Builders operate on an abstract open-source API that gives us future-proofing, prevents lock-in and maximizes interoperability across all cloud infrastructure providers.
The best part? While we maintain official builders that make your life easier for popular languages and frameworks, you are free to write your own.

In the spirit of a true monorepo, let's now add a Node.js endpoint as /date.js:


The reason we started with PHP as our example is not coincidental. While it's true that PHP is the technology behind tremendous successes like Facebook, Box, Yahoo, Wikipedia, Flipkart, WordPress, and many other giants, it's not as popular of a choice as it once was.

In many respects, PHP has represented a unique and scalable marriage between programming language and execution model. The way it helped scale those companies is by imposing a fully serverless architecture:

  1. No servers to manage (infrastructure)
  2. No servers as an abstraction (code)

In line with the second point, the @now/node builder, therefore, presents you the following API:

module.exports = (req, res) => { res.end('The time is: ' + new Date())

We retain the fully standard Node.JS API, but reduce its surface.

By adding just one item to our builds config we can make our /date.js entrypoint come to life:

{ "src": "*.js", "use": "@now/node" }

Now de-duplicates your outputs, only re-deploying the ones that have changed.

Taking It to the Next Level

For a more exciting demonstration, let's take our favorite framework for server-rendering websites and applications: Next.js.

Next.js rose to popularity by distinguishing itself from SPA frameworks:

  • Not one entrypoint (e.g., index.html), but many.
  • Request and filesystem affinity (by default), yet flexible.
  • Zero-configuration (or minimal).

The main idea is that you create a pages directory, define files inside which become routes, each of which exports a React component.

My React Project Folder

Crucially, each entrypoint becomes a kind of sub-application. The compiler automatically code-splits to make sure that you don't ship extra code to users who are entering through only a certain part of your application.

This has a dramatic effect on scalability, both at the code and team levels. A page can accumulate complexity that doesn't impact other sections. This means teams being able to fearlessly evolve their own codebases without being encumbered.

Just like in our previous PHP example, Now allows you to build your Next.js application very easily:

{ "builds": [ { "src": "next.config.js", "use": "@now/next" } ]

The entrypoint for @now/next can be next.config.js or package.json.

Let's take a look at what happens when we deploy this:

Compiling an existing Next.js app, previously deployed as a container, to serverless functions. Zero code changes.

Notice the output: unlike our other builds, @now/next is yielding static files as well as multiple lambdas. This translates into:

  • Reduced cold bootup times
  • Per-route scaling and resource allocations
  • Increased security due to reduced surface

With zero changes whatsoever in how you were writing your application until today.

Now 2.0 brings symmetry to the cloud, by also code-splitting your backend

The Majestic Monorepo

Instead of having one large build process and one large process per project, you instead get user-definable parallel builds.

A build is a piece of code that takes an entrypoint sourcefile (like contact.php) and transforms it in some way. In the case of our example, @now/php is the build that turns contact.php into a cloud function that executes on demand.

Builds can also transform static files into other static files, or yield new ones. They are written in Node.js (LTS versions only), published to npm and open-sourced on GitHub.

As an example, we can optimize PNGs with a massive degree of parallelism by using the @now/optipng builder.

A basic static site, whose sources get transformed to become ready for production.

Most interestingly, Now 2.0 enables what we will call The Majestic Monorepo, inspired by a similarly named essay by DHH, creator of Ruby on Rails (The Majestic Monolith).

We don't agree that you should be orchestrating a big server abstraction (a monolith), but we believe you should be able to collocate your APIs and your business logic in a single place, with a cohesive deployment story.

It looks, feels and deploys like a monolith, with none of its downsides

As an example, Now Lambdas now enable the following:

An example of how you can organize your source code. Any structure works.

With a now.json file that looks like this:

{ "builds': [ { "src": "api/*/index.js", "use": "@now/node" }, { "src": "api/*/index.php", "use": "@now/php" }, { "src": "api/*/", "use": "@now/python" }, { "src": "api/*/index.go", "use": "@now/go" }, { "src": "index.html", "use": "@now/static" } ]

Code Snippet

Just with this, we get a fully static website (index.html) deployed to our CDN, with dynamic /api/ routes defined in 4 different programming languages. No servers to be seen.

Serverless Static Builds

Since handlers can turn a set of static files into other static files, they are a great fit for performing static builds, even more easily than it was possible before.

As an example, consider the mdx-deck project. You define your slide deck as a markdown file (with the .mdx extension), but the build process outputs index.html and main.js.

To make things interesting in this example, we will define not one but four decks.

My Decks Folder

When we execute now, they all build concurrently in independent lambdas:

Statically generated websites being built concurrently. Each mdx-deck build uses webpack + Babel + React

For this example, we built a tiny shim over the mdx-deck project. For a more generic solution to build anything (like create-react-app, hugo, gatsby, etc) check out @now/static-build builder.

Serverless Servers: An Incremental Migration Path

Earlier, we discussed the benefits of giving up on the server abstraction as a way of minimizing the surface for errors, speed up cold boot-up times and increase security.

Consider an Express server in Node.js. The entrypoint to it tends to be not a function or a specific request handler, but an app.js file that defines the route map for the entire application.

app.get('/a', () => { /* route a */ });
app.get('/b', () => { /* route b */ });
app.get('/c', () => { /* route c */ });

Example pseudo-code of how most servers define multiple entrypoints in one place.

While this works and is even deployable inside a serverless environment, it comes at a great cost: every single route defined within will spawn the entire server with all its dependencies.

Not only does this begin to erase many of the isolation benefits, but over time will inflate our bundle size to the detriment of performance.

Yes, it is possible to deploy a server inside a lambda. But should you?

Our recommended approach to making this serverless is to break the server down into individual entrypoints. If you have advanced routing needs, you can hand those to us:
{ "builds": [ /* … */ ], "routes": [ { "src": "/a/new(/route)?", "dest": "src/another-route.js" } ]

Our routes spec gives you complete flexibility to answer dynamic routing needs.

However, we recognize that a lot of you have existing, working codebases that might take some time to migrate. To that end, we created the @now/node-server builder, which can embed your entire server in a cloud function, provided that it fits within our limits.
{ "builds": [ { "src": "api/server.js", "use": "@now/node-server" } ]

The @now/node-server builder only requires that you listen on a port, just like Now 1.0.


The following systems have been upgraded to support Now 2.0:

  • API
  • Now CLI
  • Now Desktop
  • Now + GitHub
  • now.json specification

The /docs and /api sections now have a toggle to switch between platform versions. They default to v2 for all users.

The Universal Now client capabilities are being removed from the client side, in favor of our new architecture that incorporates these benefits directly at the platform level.
The legacy server-oriented and long-running workloads (v1) will remain operational and deployable but will be de-prioritized once Now 2.0 reaches feature parity for all the detailed customer use-cases.

Getting Started

If you haven't tried Now yet or are a new user, click here to get started. We have updated our examples for you to pick your favorite language or technology as a starting point.


Now 2.0 is a major step forward in reducing the friction and barrier to entry to the universe of serverless cloud functions.

The scalability properties and low costs of this architecture are unprecedented.

However, for most, its benefits were hard to marry with the workflows, tools, and practices that have been in development for the past decade.

In alignment with ZEIT's mission, we are confident Now 2.0 re-affirms our trajectory to bring the serverless cloud to everyone in the world.