Published on: Tue Oct 19 2021
If you are using React.js, Next.js is the framework to be using today on your team. That is unless you have a very good reason to rolling your own solution.
In this analysis, we start by understanding the evolution of React.js, Next.js and how they come together.
Then, I go into the details about the pro and cons of the framework. Of course, nothing is perfect so take the good with the bad.
I personally think the pros outweigh the cons. With that said, every project is different which is why I included a few more sections to discuss some of the stand out or missing features.
Beyond that, we also analyze what using a framework, like Next.js, means for a growing team. As your team grows, communication tends to become the bottle neck. Then you start to consider issues like hiring and on-boarding, it becomes even more complicated. If the proper strategy is not in place to address these growing issues then it‘ll affects the productivity of the teams, existing and new.
Finally, we glimpse into the future of some exciting direction the team is taking. Also, we take a look at the current landscape and some of the competing frameworks and plaforms available in the market.
Next.js was created to address various gaps in the existing solutions within the React ecosystem.
With the rise of React.js, one of the single page application (SPA) web framework, much of the website is rendered on the client side.
Single page applications serves to provide a seamless end-user experience on the website and web application.
It has shifted the way the site gets loaded, by providing everything that is needed to run the application upfront, then as the user interacts with the site, it gathers new data from the server as the user navigates through it.
Now constrast that with a traditional website where you’d need to reload each page for new content. Can you imagine going through a shopping cart experience where every click reloads the whole page ?
To further complicate the situation, add in different languages, currencies and managing content.
This makes SPA a great fit to address most of the issues related to having a dynamic website but with those trade-offs introduced other problems like SEO and customers using low end devices.
Everything up to this point sounds great. However, with this optimization comes a huge trade-off, which is SEO. Now that most of the interactions has been delegated to the client side, the site information is no longer available to the search engines. Many of the engines are designed to crawl and index the information of the sites.
So, that means the html content needs to be served on the server some how.
A common solution is to provide a server to perform “Server side rendering” (SSR) which is just a fancy way of saying the client side app is rendered as html on the server, and it gets served to the client who requested the page.
Prior to Next.js, if SEO was important to the business then this required many software teams to develop a SSR solution in order to achieve this. So, in a way many teams built their own internal framework.
There are pros and cons to that, over the long term, it becomes a “build versus buy a solution“ analysis. With the extra flexibility you get in the internal framework, you also take on some risk as the solution grows which requires upkeep and further maintenance (especially on a large team).
Additionally, Next.js provides many comprehensive features to build a modern a website or web application. This is why I believe Next.js is the leading React.js framework for any software teams building a particular type of website and web application today.
It makes it especially suitable for any content heavy, marketing, and ecommerce websites. However, with many of the other benefits the framework provides, it may still make sense to adopt it depending on goals of the team or the business.
My overall impression of Next.js from start to finish is solid. The setup from start to feature development was very streamlined.
You can almost treat the Next.js framework like a blackbox. Basically, you can just rely on the great documentation, and community available for anything related to the framework, even for any custom configurations.
Here are just some of the pros and cons that I have gathered from the framework:
npx create-next-app@latest
to create a new projectnext.js
in their exampleswebpack
, swc
)react-router
(yet ? maybe ?)
So, as I mentioned earlier Next.js solves various issues beyond just the SEO. The Next.js team really thought about the framework end-to-end and streamlined it. Especially if you are using their cloud platform, Vercel.
Below are just a few more details I noticed.
This is achieved through Next.js’s filesystem routing where each page is automatically code splitted so the page only loads what is needed per page.
The setup would look something like this:
pages/
├── index.tsx
└── blog
├── [id].tsx
└── index.tsx
This folder structure contains routes for
/
,/blog
and/blog/:id
This comes with their convention for handling data fetching:
getStaticProps()
(SSG / ISR)getServerSideProps()
(SSR)getInitialProps()
(CSR)In addition, Next.js provides image optimization through the framework as well.
<Image
alt="My image"
placeholder="blur"
blurDataURL={imageUrl}
src={imageUrl}
width={950}
height={500}
/>
It is slightly an opinionated setup but many teams would appreciate all these capabilities if they need it. Otherwise, these are likely features they would need build themselves if the choose to build their own framework.
Next.js supports various ways to serve your content.
Methods:
They all have their trade-offs but fundamentally the approach chosen comes down to how frequently does your content change and the type to experience you’d like to provide.
Or said in another way, it depends how up-to-date your content need to be on your website. An election poll site has very different requirements than a blog.
An extra call out for ISR, which is in between SSG and SSR. essentially, it generates the page statically but re-generates the page based on an cache expiry time as new request comes in. This expiry time is configurable.
References:
Next.js works seamlessly if you use their cloud platform, Vercel. However, if you choose to bootstrap your own infrastructure on something like AWS, it takes more work.
Which makes sense, my understanding is that Vercel is their core business. So, much of the tooling with infrastructure, CI/CD is to be handled by your own team if they choose to roll their own infrastructure.
Interestingly, Next.js also offers built-in convention for deploying api as functions through Vercel.
You define a function inside api/*
and when you deploy it, this endpoint will be available on a serverless function with no extra work or configuration required.
If you were to set this up your self, it would take a lot of work just setup the infrastructure alone!
react-router
If you have been using React.js on your site for sometime then likely you are using react-router for the site’s routing solution.
Unfortunately, as of today, Next.js does not support this natively (yet). They have opted out to have their own router and link, next/router
and next/link
.
My guess is that as of now, with their file based routing, supporting react-router and the nested routes will be just too complicated. So, they decided to go with their own solution for now. Who knows ?
However, remaining hopefully, there is a dicusssion on an github issue #1632 which goes into this discussion.
There are comments that the teams have added that they do intend to support it in the longer term. It just does not seem like a priority at the moment though.
One of the big gotchas with the framework was the way it handled environment variables. It seemed to be a common area of confusion. I had many team members ask about what is the deal with the configuration and how to safely expose variables.
The documentation is quite clear but you can get a little paranoid if you don’t understand how things work behind the scenes.
The convention used by Next.js for Environment Variables are as follows:
NEXT_PUBLIC_*
- Is public (replaced at build time)process.env.*
- Is server and build only (run time - loaded via .env*
)Next.js also provides another way to “expose“ the config through the next.config.js
(replaced at build time):
// next.config.js
module.exports = {
env: {
MY_PUBLIC_SECRET: process.env.MY_PUBLIC_SECRET
}
};
Generally, when using webpack, best practice is to ignore node_modules/*
as it is assumed we will use the distribution files provided by the package.
Sometimes you want to make some minor changes at build time to the different packages in your node_modules/*
folder (ie changing imports).
If so, this can be achieved through the package next-transpile-modules.
Here is an example with @mui/material@5.x
using styled-components
:
// next.config.js
const withTM = require('next-transpile-modules')([
'@mui/material',
'@mui/system',
'@mui/icons-material',
]);
module.exports = withTM({
webpack: (config) => {
config.resolve.alias = {
...config.resolve.alias,
'@mui/styled-engine': '@mui/styled-engine-sc',
};
return config;
}
});
For a growing framework like Next.js, I believe it has already won as the go-to framework to build React.js sites and web applications.
The community growth is just tremendous. Many popular React.js based library has an example using Next.js for their library (styled-components, emotion, material-ui etc).
The information available on Next.js and the talented people working on the framework is ever growing. These include core-contributors from webpack, swc and many other.
I believe this makes it a great framework to adopt.
As with any growing teams, communication and knowledge sharing becomes more and more important. If the intention is many people are going to use this framework, the process should be in place to ensure individuals involved have enough context and details to perform their duties.
Next.js has solved many of these issues.
These may include and not limited to:
Having these processes in place also improves team morale, and reduces friction when using the framework. It takes work to build and grow a framework.
Even more so to foster of a community, and provide on-going support. If this type of work isn’t contributing to the main value proposition of your business then I think its best to start delegating it. There is no need to re-invent the wheel.
It becomes even more important when it comes to hiring, and on-boarding new engineers to the team.
Engineers want to work on interesting problems and exciting technologies. It is always easier to sell an engineer to come work with in-demand technology than a legacy or lesser known one.
Among the frontend frameworks, React.js still dominates the market. Within a year, Next.js has seen massive adoption.
A comparison between number of downloads of gatsby (React.js), next (React.js), nuxt (Vue.js) framework , source
Since the pandemic, the Next.js framework has seen almost an 4x increase in number of downloads. The stats are only of downloads but I think this is a good signal that many people are using it or actively experimenting with it.
I only see this figure growing because Next.js is the best solution of this scale in this space right now. From a hiring perspective, this means that more and more talent are gravitating towards Next.js.
With Shopify announcing that they are working on their own Next.js like framework and platform (Hydrogen + Oxygen), this is a clear sign Next.js is moving in the right direction.
Do keep in mind, React.js has a total download numbers of ~11M. So, there is a big total addressable market - source.
The Next.js team has recently announced exciting optimization improvements to their framework with webpack and swc.
Based on the pull requests, the team seems to be really betting on Rust for much of the tooling for the framework (Like many other projects).
I believe only more exciting things will come of this.
That said, there many similar, and competing platforms and frameworks that are also emerging all addressing similar needs:
They all overlap in features and offering. I still believe Next.js is ahead in terms of the community adoption, it is the framework that offers the most versatility at this time.
Hydrogen and Remix may steal some of its market share in the future. However, Hydrogen was only recently announced, and Remix was closed source for the longest time until recently. So, we will see how things play out.
One thing is for sure though, it is an exciting time to be working in the React.js space right now. It is THE ecosystem to be in.
With various teams evolving and innovating on the meta frameworks, I am sure there will be more exciting things to come of this. Things like computing at the edge, developer experience improvements, optimizations, tooling and more!
References:
Then consider signing up to get notified when new content arrives!