Florian Herlings.

Next.js: The big picture

This article is part of a series called "Next.js".

  1. Next.js: The big picture
  2. Pages and routing in Next.js
  3. Static files, styled-jsx and CSS modules in Next.js
  4. Generating static sites with Next.js

The React framework Next.js quickly became everybody’s darling in creating well structured and scalable full stack web applications. This article aspires to give you a big picture overview over what Next.js tries to achieve, and in which way you could benefit from it.

This article is first in a series of Next.js related posts. If you want to be updated when the next articles arrive, follow me on Twitter or subscribe via RSS.

In this article, I will talk about the history that lead to next.js, which problems it tries to solve, static compilation of code and which projects might benefit from using next.js. I close with a recap of the article, including a few external links allow you to dig deeper.

History

Looking back into the early 2000s, almost all web applications heavily relied on dynamically rendering pages on the server, using PHP, Python or Java. Users navigated through these web apps by clicking links or submitting forms (both of which generated a new request/response cycle1). A little bit of Javascript and AJaX2 where helpful spiced up those pages to make them feel faster and more responsive.

The Javascript portion of a regular web application grew more and more over the years, in order to make websites more dynamic and user friendly. Once the Javascript part reached a tipping point, SPA3 frameworks like Angular and React.js[^react] emerged and quickly became popular to help build more robust and maintainable applications.

A few benefits from the times of the more classic „links and forms” era were lost in this transition: Today’s SPA focussed approaches do not offer a complete story to build your whole application: Even though they are very helpful in structuring your in browser code, they usually treat the server side of things as “something different” that should be separated from your precious SPA. One of the downsides of this approach that I have seen in my teams is a separation between “API devs” and “SPA devs”, which is one of the many instances of Conway’s law:

Any organization that designs a system (defined broadly) will produce a design whose structure is a copy of the organization’s communication structure.

Second, this separation of browser and server code, made it harder to pre-render4 your Javascript app. This caused all kinds of unhappiness from search engine crawlers5, to screen readers and users who’s devices only have slow CPUs like mobile phones or older tablets. It certainly is possible to setup any software system to pre-render a HTML page, but it usually involves a lot of effort, a lot of knowledge about the stack and plenty of server power. The result of this high demand on resources is that most SPA based pages, do not pre-render.

Which problems does next.js solve?

This is where Next.js comes in: It tries to address these problems (structuring and pre-rendering) in a very convenient and well thought-through way. It also makes it extremely easy to distribute the workload to different stages of your application in order to achieve great performance benefits (I will talk about those benefits in this article).

At the same time, it comes with many wonderful features that every developer knows they should do, but never actually gets around to doing them. Browser based routing with proper fallback and static page generation on build time are just two of those.

Formal structure

One of the many things developers love about frameworks is the structure they provide. Next.js does this by introducing a few simple but powerful concepts (more on that later), which guide developers in structuring their code think about certain problems in a certain way. Higher maintainability and developer happiness are results not only loved by developers but also their managers.

Next.js puts a lot of energy into bringing code in the browser and on the server (like business logic and data management) closer to each other, while still ensuring a separation of concerns6.

Diagram of a browser, server and database including a box surrounding the browser and half of the server, indicating that this is the part that next.js takes care of.

Pre-rendering dynamic content on the server

Once you get used to building web based applications with React.js (or any other SPA framework), building applications without it starts to feel a little old fashioned (not in a good hipster way, though). Encapsulating complex HTML and CSS structures into simple and reusable components becomes your second nature. As a downside of the SPA approach, your users often need to wait until all (or most7) of the Javascript code is downloaded and executed.

Pre-rendering4 is a solution to this problem: The server will already run the Javascript code, and render everything it can into static HTML. The users’ browsers will receive the HTML so they can quickly show the user the page, and only in a second stage download and run the Javascript code, that is necessary to make the website interactive.

Next.js does pre-rendering out of the box and hides most of the complexity that is usually involved in setting it up. You as a developer get the best of both worlds: A convenient way to structure your frontend application in React.js as well as a fast loading website, which are also loved by search engine crawlers8.

Static compilation

Next.js offers three ways to think about your dynamic content:

  1. Pre-rendering dynamic code on the server
  2. APIs
  3. Static compilation at build time

We already talked about the pre-rendering part: You build your website using React.js components, and the framework will allow you to load and generate data that can be used as properties in your components. In this way, you can easily render a list of products from your database or fetch the current stock information for each product.

If you want to build a more dynamic application, that does not need the server to pre-render any content, your second option for dynamic content are APIs. Next.js includes a simple and easy way build REST APIs, just like you would using for example express.js. You can also use external APIs in your Next.js application. You could either make AJaX calls to the API from your browser based React.js code, or call the API from one of your APIs and forward the data to the browser, if you have reasons to do that.

Third, but certainly not least, Next.js allows you to pre-render static content at build time. This means, that you have the option to generate your pages’ content when you build your application (which will most likely happen when you deploy). These staticaly compiled pages, are the fastest and least resource intense pages you can think of. The build script, will generate those pages, and from this point in time, your web server will serve those pages as static files: No additional computation needed. Most websites have a lot of content, that only changes every day anyway (think of a product import in an eCommerce system). Building the new pages once a night will make your website insanely fast.

Diagram multiple files, generated into uniform HTML files by next.js

Doing all the things you meant to do, but…

Additionally to the formal structure, the handling of dynamic data and the static compilation, the framework will help you do the things that you know you should do, but often times do not fit into the scope (money, time and energy) of the project.

Some of those are: a unified way to setup a project[^create-react-app] with simple build and run scripts to prepare your app for production. Next.js also comes with a predefined webpack9 stack that you can change and optimize, but will run great out of the box.

You will also find a proper way to organize your pages and routes, including browser based routing, with a server based routing fallback to get the combined benefits of fast switching times between pages as well as fast initial loading times, when a users visits a URL for the first time.

Next.js also comes with a slightly opinionated way to do CSS and component stying, which you can definitely change, but will at least be a great start for when you don’t have a strong opinion one way or the other.

Other benefits include the convenient build time pre-rendering, allowing for extremely fast websites, many plugins to extend it’s ability and a proper deployment story.

How does this fit into your project?

Probably the most interesting questions when it comes to technology is: Who should use it to build which kind of product. Let’s look at a few examples of projects and how they could benefit from using Next.js as a basis for their development efforts.

Static website or blog

It is very simple to create a static website or blog (like this one) using Next.js’s ability to generate static HTML pages. You simply create new pages as React components and have the framework compile them into static HTML and CSS pages. This way you end up with a super fast loading and extremely cheap to host website, that you can create using the convenience of abstraction that React.js provides. The data for your site can either come from simple Javascript files, a folder of markdown10 posts or an spreadsheet file, a simple database or whatever you can think of.

eCommerce website

When thinking about an online shop, the most important pages probably are the many many product pages. Many eCommerce companies run nightly updates to their product catalog, so it Next.js can be a great choice, to statically generate all of those pages once the product catalog has been updated. You can pull data from a big database, enrich it with information from your PIM11 or a spreadsheet containing the latest price updates.

You can also generate a blog to generate important content for your marketing and SEO efforts. You can use as many sources for content as you want, like your Wordpress site12, a headless CMS13 or simply a directory of PDF, provided by the products’ manufacturers.

The parts of your page, that have to be dynamic (like search, checking stock information and the ordering process) can simple be handled by the framework’s ability to dynamically render pages. Next.js will help you find a well structured and maintainable approach to those parts of your page.

This way you can build a fast loading and super scalable solution to your eCommerce needs, which will help with SEO and conversion.

The interactive web app

The more dynamic your website will be, the less benefit you can gain from using Next.js as a foundation. A super interactive web app, where almost every page is built using up-to-date information from the database, which is also very specific to your user is not a great fit.

If you – for example – build a web app that users can use to generate invoices, do their taxes or handle their many todos, all the static generation and pre-rending will not help enhance the user experience, because the user will visit your app to spend a lot of time with it. The upfront loading time is well worth the wait for most users.

The only benefit you can really gain from this is being able to show a result to the user more quickly, so they perceive your application as more responsive. The help that Next.js will provide in structuring your application can just as well be achieved using server code frameworks like express.js.

Recap and Further reading

So, why should you consider Next.js for a project? It will help you to build a React.js based application by combining the full advantages of browser and server based code, instead of treating both as completely separate entities.

You will benefit from a well structured application, super fast loading times, happy developers and ways to include almost any data source that you can think of.

I hope this article helped you learn something about the Next.js framework and allows you to make more informed decisions. This article is part of a series of posts in the making, and I will update it with links to the new articles as soon as those are done. Let me know what you think about Next.js and how you liked the article. Feel free to get in touch with me via twitter or email.

Furter reading

  1. The request and response cycle is a core concept in networking, that does not only but also apply to HTTP(s). The basic idea is that, communication happens as a series of requests being made by one system (the client), which are answered with replies by another system (the server). This protocol ensures a secure way for two systems to communicate, but usually only allows one system (the client) to start a communication. One of the many upsides is, that it is very scalable if you manage to allow multiple servers to generate the required response. If you want to read more on this, check out Wikipedia’s article on “Request–response

  2. AJaX is an acronym for “Asynchronous Javascript and XML” and is one of the core concepts in web development. It basically boils down to code in the browser making calls to the server, without reloading the page. As soon as the code receives an answer from the server, it can dynamically change the content of the page. 

  3. SPA stands for Single Page Apps. In an SPA, the server will send one page to the browser, which includes HTML and CSS, but also a lot of Javascript code. This Javascript code will take over the navigation and data handling in the browser. This way, the application does not rely on page reloads or forms to communicate with the server, and more quickly show updates to the user. 

  4. Pre-rendering describes a process, in which the Javascript code, which is supposed to run in the user’s browser, is already run on the server. The server will try to generate the HTML code that a browser would create, but does so way earlier in the process. The resulting HTML code will then be sent to the browser, which only needs to display the HTML code. The server will also send the Javascript code, so that once the browser displayed the pre-rendered code to the user, it can still run the dynamic Javascript code. This way, the user get’s the best of both worlds: the pre-rendered code allows the browser to very quickly show the page, while the dynamic Javascript code can still enhance the website’s usability.  2

  5. Actually, Google’s crawlers will run Javascript code when they access a site. This means, that even a page that does not have pre-rendering will be indexed by Google’s crawlers including it’s full text. Google even has a series of recommendations to make this more easy. Keep in mind though, that Google is in fact not the only search engine and that other search engine’s crawlers behave differently. 

  6. Separation of Concerns is a simple but powerful concept, which asks the developers to split up an application’s code into groups of feature that belong together. The Wikipedia article about SoC does a wonderful job of going deeper into this topic. 

  7. Modern packaging systems (also known as bundlers or sometimes compilers) like webpack.js9 analyze your project’s code and try to find out how to group or bundle it in the best way possible. If the bundling works out perfectly, the user will only receive the code she or he needs at the time they need it. A system that does not use code splitting, will send the user one big package with all your code in it. This means that the user has to download the code for all your apps functionality, even if they only want to see the homepage for now. 

  8. Search engines (like duckduckgo or Google) use special applications called crawlers (or spiders) that visit every website they find on the internet, try to get all the content and store it in the search engine’s search index. 

  9. Webpack.js is currently (Summer of 2020) the most frequently used solution, to build, bundle and package your frontend application. Webpack will allow you to configure the way your code is pre-compiled for different browsers, how your assets are distributed and compressed and which Javascript language extensions you want to use. Webpack is so sophisticated, that it usually takes either a lot of knowledge or trial and error to set it up correctly, which is why many people are currently working on a way to create a bundling system that is more easy to use.  2

  10. Markdown is a very simple text format, which helps you to write code for the web, without having to put all those distracting HTML-Tags like <strong>this one</strong> into your text. Markdown is usually compiled into HTML and is loved by many many people, including the author of this post who is using markdown right now to write this footnote. 

  11. Product Information Management is super important for companies with a big product catalog. PIMs are systems, that are used throughout the whole company to create, updated or get information about products. 

  12. Wordpress is the most widely used Content Management System. Most websites you visit are probably running on Wordpress, or have a Wordpress based component. Wordpress also offers an API, which can be used to get a website’s information out and into other systems, like Next.js. 

  13. A headless CMS is a reduced CMS, that focusses on two things: Providing a useful backend for administrators and content people to enter the content they want to distribute. The second powerful feature is the API, which allows developers to build a website or mobile app based on the information in the headless CMS. 


This website does not use any tracking or feedback mechanism. Instead, I would love for you to get in touch with me to let me know if you liked it or if you have any suggestions or questions.