We are very excited excited to announce the stable release of Next.js 3.0. Ever since our beta announcement, we have been using it to power zeit.co and have received lots of feedback and contributions from our community.

Let’s walk through what’s been improved and what’s altogether new, or fetch the latest version from npm!

New to Next.js? Next.js is a zero-configuration, single-command toolchain for React apps, with built-in server-rendering, code-splitting and more. Check out Learn Next.js to get started!

Static Export Support

This was the most request feature by the community on GitHub. And we have delivered!

All it takes to export your project to a directory with plain .html and .css files is to configure your project and run:

next export

The bonus? You can deploy statically to now.sh as many times as you want, for free!

The prolific Next.js community has already come up with some static blog generators for you to check out:

Dynamic Import Support

Next.js now fully supports TC39 dynamic import.

With dynamic imports, our codebase gets split into a set of chunks that can later be loaded dynamically. The developer gets full control to load code over time, depending on user interaction or the data itself.

It's pretty easy to use. Just import your module as a promise as shown below:

const moment = import('moment')
setTimeout(function() {
  moment.then(moment => {
    // Do something with moment
}, 15000)

The module will be downloaded when we starting to use it. In the above example, the moment module will be downloaded when the setTimeout callback runs (~15 secs after the page load.) This speeds up our main JavaScript bundle by loading code only when we need it.

Dynamic React Components

Additionally, Next.js comes with a powerful opt-in utility called next/dynamic which helps you to create dynamically loaded React Components easily.

Dynamic components can load React code on-demand, but the most interesting feature is that if they are included in the initial rendering, server-rendering still works!

Let's look at some examples!

import dynamic from 'next/dynamic'
const DynamicComponent = dynamic(import('../components/hello'))

export default () => (
    <Header />
    <DynamicComponent />
    <p>HOME PAGE is here!</p>

Loading a single component, dynamically.

import dynamic from 'next/dynamic'

const HelloBundle = dynamic({
  modules: (props) => {
    const components = {
      Hello1: import('../components/hello1'),
      Hello2: import('../components/hello2')
    // you can add / remove components based on props
    return components
  render: (props, { Hello1, Hello2 }) => (
      <Hello1 />
      <Hello2 />

export default () => (
  <HelloBundle title="Dynamic Bundle" />

Loading different components based on dynamic properties!

Until today, code splitting was based on routes, or the section of the application the user had loaded. Moving forward, you'll be able to load code as a function of the data the user is presented with.

We are excited about the apps people will create with this new paradigm.

More Beautiful Errors

Thanks to Krisztian Puska, we’ve updated our error color theme to be easier on the eyes and more accessible.

The gif shows a syntax error being hot reloaded with the new colors.

Improved Hot Module Replacement

We have addressed a variety of scenarios that would render HMR (hot module replacement) ineffective before, in particular around error recovery.

Moving forward, when an error of any kind occurs, you will be able to make changes to your code, save and see the error change, be substituted by another error or go away altogether!

HMR: Node.JS 8.0 Support

We have solved ERR_INCOMPLETE_CHUNK_ENCODING errors in the dev tools showing up when using Next.js with the new Node.js 8.x release line.

You won’t be seeing this one again!

HMR: Navigating to Errors

If you navigate to a page that had any kind of error, it’ll be handled appropriately now, rendering the error message and giving you the ability to correct it in realtime.

We navigate to the index page with errors, fix them and watch the page recover.

HMR: 404 to Error to Success

We have addressed a bug where you navigate to a missing page (correctly rendered as 404), but you make a mistake when populating it.

After we create the page, we introduce an error and then promptly fix it.

HMR: Better Bad Returns

If you happen to return the wrong type, we now handle that situation smoothly.

After the right type is returned, the page recovers successfully.

HMR: Undefined Can Be a Function

Any type of runtime error when evaluating the module is now correctly caught. Realtime debugging of undefined is not a function is right around the corner.

We first make a syntax error, which recovers to a runtime error, which recovers to the page.

Faster: Serverless Ready

Bootup time for a baseline Next.js app is now 5 times faster, down to about 200ms from 1000ms. Stay tuned for some exciting announcements about serverless Next.js with Now!

Smaller: Optimized Core Bundles

We have optimized the core Next.js bundle even further and it's now 10% leaner! Only the most crucial production code is included in your final bundles.

4.0 and Beyond

As we have done after other major releases, we will soon be publicly sharing our roadmap for Next.js 4.0.

The focus will be on an even leaner core, faster bootup time and rendering, integration with React 16 and better use of caching during development to avoid re-compilation.

As always, we recommend you join our Slack community and follow us on Twitter.