Interview Next.js 12 is out with a range of new features including built-in middleware and support for ECMAScript (ES) modules.
"Next.js 12 reimagines the infrastructure of how we build for the web," says Guillermo Rauch, CEO of Vercel, the company maintaining the Next.js MIT-licensed open-source project, and owner of the copyright. Rauch is not one to understate his case, but there is plenty new in this update, launched at the virtual Next.js Conf yesterday.
"It's on two levels," Rauch tells The Register. "One is developer experience, and the other is the global execution model for compute."
The basis for these claims is, first, improvements to the Next.js tools including a new Rust compiler, and second, the addition of middleware to the framework, which Vercel hopes developers will run on the company's Edge Functions (now in beta), a content delivery network.
Next.js is based on React with the addition of options for both server-side rendering with Node.js and static site generation. Here is what is new in version 12 – though much is still in preview:
- Middleware (now in beta) which runs between the user's request and the main application code.
- Rust compiler which replaces Babel for compiling Next.js application, and improves build time by 5 times according to Vercel.
- Support for React 18 (even though React 18 is still in alpha), including the Suspense feature, which delays component state transitions until requested data has resolved. This is under an Experimental flag.
- Support for AVIF images which have 20 per cent better compression than WebP.
- Native support for ES modules as the default, though old-style CommonJS modules are still supported. This also means that Node.js 12.22 or higher is required.
- Experimental support for importing ES modules directly through an URL, rather than via a build process.
- Removal of webpack 4 in favour of webpack 5 (a breaking change).
Why the new compiler? "It's primarily motivated by the pace at which the size of front-end codebases have been growing," says Rauch. "It's not unusual to hear of companies with hundreds of Next.js developers with codebases with tens of thousands of components, if not hundreds of thousands of components."
Node has served us well until now, but it's starting to show its age when it comes to the performance needs of today
Rauch is referring to the Edge Runtime used by Middleware, which does not support Node.js APIs. Node modules can be used "as long as they implement ES Modules and do not use any native Node.js APIs," the docs say.
According to Rauch, developers can "eliminate entire categories of issues" by not using Node.js for these serverless functions. "Node has served us well until now, but it's starting to show its age when it comes to the performance needs of today."
- New Relic guzzles down CodeStream to help devs jump straight from app error telemetry to offending code
- It's heeere: Node.js 17 is out – but not for production use, says dev team
- Jamstack research: Typescript and serverless are the winners
The potential uses for Middleware are extensive, including authentication, bot protection, feature flags and A/B testing, server side analytics, logging, and any case where redirects and rewrites are required. At Next.js Conf an example showed how using a region-specific database server could improve latency.
Rauch observes that JAMStack, using static websites with dynamic data from microservices, has pros and cons. "The good part was the focus on pre-rendering. The bad part is that it was so static that sometimes we couldn't pre-render anything.
"What we're seeing now, especially with the introduction of React server components that we're announcing in beta form, we can move the vast majority of the code back to the server, but instead of that server being monolithic at a particular place in the world, we're making the code globally distributed. With that comes greater performance, and no single point of failure."
How is this different from just using a CDN with a conventional web application? "When CDNs looked at speeding up, their hammer was the cache," Rauch tells us. "They go to the origin, take the page, cache it. At that point they've already made it too static, especially for what we're seeing in media, ecommerce... we're seeing that you want to personalize everything, from the language to the currency to variations of components. In that world, the top-level cache of the legacy CDN vendors doesn’t work any more."
Rauch also believes that the web-centric development model of Next.js is a benefit. "There's nothing about Next.js that is not native to a web browser," he says. "When you look at designers, how they work today, they just open the web browser and point it to Figma. We asked ourselves, can we do the same, open the browser, point it to a Next.js project, and run the entire compiler and machinery inside the browser?"
This idea ended up as Next.js Live, a web-based development platform. "In our private beta we've been able to load production-grade applications directly in the web browser," Rauch says. The concept is similar to GitHub Codespaces or Gitpod, except that with Next.js Live everything is in the browser, there is no container back-end.
"Next.js is fundamentally a front-end framework," says Rauch. "The Next.js runtime is fundamentally serverless, so we don't need all that additional machinery to run and render a project. The web was designed from the outset to allow both reading and editing. We want to bring more people into the world of contributing to the web."
The editor in Next.js Live is based on Monaco, as in Microsoft's Visual Studio Code project.
Next.js Live uses WebAssembly in the browser for the compiler. "WebAssembly is now the new universal way of distributing applications," Rauch says. "We can take code written in Rust and make it entirely universal." However, he believes that it is "early days for WebAssembly in production" so this is currently only used for development – though it is something the team is looking at for the future.
Next.js 12 also improves the performance and stability of Hot Module Reload (HMR), Rauch tells us. This is where "you type, you save your file, and you see your change instantly without refreshing the web browser... It used to be the case that developers had to second guess and sometimes just hit refresh out of muscle memory as they wouldn't fully trust the technology. We've refined it a lot... we're seeing up to five times faster repaints on the screen, from what you're typing."
The technology behind the faster refresh is in part a benefit of ES modules because "we can become smart about only giving the web browser the specific change. We only load the part of the page that you are working on."
Why not just use React rather than Next.js? "I like to think of [React] as the engine," says Rauch. "What this engine does is on the one hand power rendering, and on the other hand supply the primitive abstractions that the developers are going to use. The component model is provided by React and the rendering engine is provided by React. But with Next.js folks are building websites and applications, and that's the layer of abstraction that Next.js introduced on top. We've raised the abstraction from component to page."