The Next.js team recently released Next.js 9, featuring improved developer and user experience. The new Next brings built-in zero-config TypeScript support, file system-based dynamic routing, automatic static optimization, API routes, important production optimizations, and miscellaneous developer-oriented productivity features. An upgrade guide is available to support developers migrating to the new version.

Server-side rendering of web applications may improve the perceived performance (page load speed), and facilitate social sharing of application pages. Server-side rendering however comes with specific issues which makes it non trivial to implement. Additionally, while componentization may result in productivity gains through component reuse, it also introduces specific challenges (such as CSS scoping). Packaging an application for production and continuously adding or modifying features also requires specific care.

The necessity to manage the complexity of developing, releasing and maintaining web applications resulted in an ecosystem of libraries and frameworks trying to ease the path for developers, by offering features targeted at optimizing applications for production (like optimized build size), and developer productivity (like faster dev compilation, or zero setup configuration).

Next.js is a part of that ecosystem and describes itself as "The React Framework for production". InfoQ interviewed Tim Neutkens, co-author of Next.js, on the motivation and contents of the recent release, and the plans for the future.

InfoQ: Can you introduce the Next.js React framework to our readers who do not know it yet?

Tim Neutkens: Next.js is a framework for building websites and web applications with React. React is a very powerful and increasingly popular technology invented by Facebook. It was created to solve very advanced UI challenges and was later open sourced. To build complete applications with React many tools have to come together. For example, code has to be bundled using a bundler like webpack and transformed using a compiler like Babel. There are many other pieces needed to make a successful application, such as code-splitting, optimizations to code, and making sure your colleagues have an amazing experience while writing code, for example through hot reloading, which are live updates as you make changes without having to reload the page. Furthermore, there are many strategies in which websites and applications are being built today, for example statically pre-rendering, server-rendering and client-side only rendering. All of these problems need very specific solutions, and Next.js puts you and your team in the pit of success when building React applications.

InfoQ: There are currently various universal rendering frameworks organized around different UI frameworks: Next.js for React, Nuxt.js and Quasar for Vue, NestJS for Angular, Sapper for Svelte, and probably many more, this being JavaScript. Can you offer any thoughts on the main driver behind such frameworks? Developer experience? User experience? Time-to-feature? All of the above?

Neutkens: The main goal of this class of framework is to find the sweet spot of providing the best user experience to end-users while making your team more productive in creating features and deploying them to production. Next.js also helps with debugging and provides guardrails to prevent anti-patterns, ensuring your project scales from a small website to full-fledged web application. Besides that Next.js does many optimizations to your code and makes sure the development process stays fast as your project grows. There’s a lot of specific knowledge needed to make all these pieces play well together in delivering the best result to your customers. Furthermore, the ecosystem keeps evolving and complexity of projects only increases. Meaning that if you build something completely custom, you’ll have to maintain that library inside of your company, which requires resources that are taken away from project development.

InfoQ: The release note mentions that Next.js 9 ships with Built-In Zero-Config TypeScript Support, Dynamic Routing, API Routes, Automatic Static Optimization, and more. Together with Automatic Static Optimization, I found the features discretely gathered as ‘more’ to be actually pretty exciting for user experience: in-viewport prefetching, Optimized AMP, typeof window pre-evaluation. Can you tell us more about those? Do you have any empirical or hard measures on the UX improvement?

Neutkens: Automatic in-viewport prefetching has two benefits. First of all prefetching is now a default so all navigations that don’t explicitly declare they shouldn’t be prefetched are prefetched. This helps with being fast by default. This way developers can opt-out when needed. The second benefit is that we now only prefetch when the link is in the viewport, in previous versions Next.js would prefetch all links marked for prefetching at the same time and at the same priority. This would cause more JavaScript to be prefetched than needed for what is in the view. Besides prefetching we indeed added a typeof window transform that helps with eliminating those specific branches. We saw a returning pattern of users using this statement to try and figure out if the current execution would be server-side or browser-side. This transform ensures server-only code is not shipped to browsers. The mentioned AMP optimizations are incremental improvements on the existing solution for rendering AMP pages in Next.js. Previously, Next.js had to provide two versions of an AMP page, an optimized for users, and a normal AMP page for search-engines to index. This is no longer needed as optimized AMP pages are now valid AMPHTML.

InfoQ: Talking about static optimization, you are one of the authors of MDX, a format that lets you write JSX in your Markdown documents. MDX is used as input format for a number of frameworks for generating static apps. I am thinking in particular of the Zero Server. Do you plan to integrate MDX with Next.js in a future version?

Neutkens: The automatic static optimization is an interesting new feature, as it allows for building truly hybrid applications. Developers can now choose on a per-page basis if they want to server-render on-demand or statically export the page. As you pointed out this new feature works quite nicely with MDX, which in most cases is static content. It’s already quite easy to add MDX support to Next.js through the MDX plugin, so we’re not adding MDX by default in the short term. One of the reasons for this is that we closely guard our metrics with regards to installation size, this way Next.js stays fast to install for all use-cases.

InfoQ: Tell us more about API Routes. What is the motivation behind the feature? Do you receive a lot of developer requests to support GraphQL?

Neutkens: API Routes is a new feature that allows developers to build API endpoints inside of Next.js. It allows developers to take advantage of existing Next.js features like hot reloading and TypeScript support for their API. It can be used together with any Node.js HTTP framework, including most GraphQL server frameworks. However, in many cases, the defaults provided are enough to build fast, flexible, and highly scalable endpoint functions. The motivation started by listening to user feedback while researching how users are leveraging Next.js in the wild. This included anything from massive web properties like Hulu and Deliveroo to cool side-projects like Carbon. In most cases these projects used a custom server implementation that introduces some developer experience issues. For example, now you have to learn a separate functionality and set up specific tooling. Another example is using TypeScript required setting up a separate compilation process, adding to project complexity. With API routes we allow users to achieve most of the same functionality in a much more streamlined, easy to understand feature.

InfoQ: How easy is it to migrate a Next.js 8 codebase to Next.js 9?

Neutkens: We’re very committed to making upgrades mostly non-breaking. We do this in multiple ways, for example, we have an extensive integration test suite that tests almost every feature of Next.js. Fun fact, if you go back to the beginning of the Next.js project on GitHub you can see the very first readme which was an outline of the project. Almost all features are still here; some got replaced with better solutions, but fragments of the initial readme remain inside of the documentation today. In this release there’s a very small percentage of users that have to change certain parts of their app, for example, they might have been already been using TypeScript. For those cases we provide an upgrade guide that goes into all the steps required to upgrade.

InfoQ: Next.js has grown considerably in features since its inception. What is next for Next.js (pun intended)? Just like the Ionic framework started supporting only Angular and now supports non-Angular options, do you see a day when Next.js removes the dependency on React?

Neutkens: We’re continuously making improvements to Next.js. We’re going to continue to introduce features to make developers lives easier. However, we’re definitely improving the developer experience. We’re also optimizing the Next.js production runtime, meaning soon users will have even smaller bundle sizes by default for pages. Through our collaboration with the Google Chrome team, many optimizations are scheduled to be released very soon. For example, sending modern JavaScript code to browsers that support it but also better chunking (JavaScript bundling) logic so that less code is sent to browsers. At this point, we’re not looking into removing React from our stack, as it’s one of the integral parts of Next.js.

InfoQ: What is the best way for readers to get involved and contribute to Next.js?