You have probably heard of this slick framework called Next.JS, but you wonder, what does it do? For starters, it's built on React, which means you can make React apps with it, but the important feature of it is that they can be rendered server-side.
Sometimes you're just making a toy or a casual app and whether it's rendered server-side or client-side doesn't matter. But if your app is very heavy, then server-side rendering makes a big difference in performance, since in the case of mobile devices you're no longer rendering using their limited performance and battery life. Babel compilations are expensive to do.
Server-side rendering (SSR) vs client-side rendering (CSR)
Let's talk for a minute about the network latency differences between SSR and CSR.
If your server is located in a geographically distant area several hundred miles away from a user, whose running the client part of the app, then each request can take potentially several hundred milliseconds to load. This results in a poor user experience, which might cause users to stop using the app, because most are willing to wait for only a few seconds maximum.
In both CSR and SSR, you still must wait for the React code to run before the page becomes intractable. But in SSR, the page becomes viewable immediately after it's fetched, without having to wait for React to run. Compare this to CSR, which must render the returned React code before the page even becomes viewable. When users are able to see the page, it gives them the impression that the page is ready to use. Interaction is an activity that takes touching to verify, so viewing is a quicker way for users to see the progress a page is loading. Not in percentages, but as a boolean condition: whether it's loaded or not.
Also in a CSR, the browser sends a blank page as a response when a particular page is queried (Remember that index.html file in your React project with a div of ID "root"?). In SSR, a blank page is not returned, it gets a page full of rendered content. That means SSR apps can retrieve the HTML page and JS libraries at the same time, without waiting for one of the requests to complete.
Now that I have explained what NextJS is, let's see how to create a NextJS project.
Going to the NextJS website, they have a neat tutorial that walks you through creating an example app. Let's break down that tutorial down in detail.
So first, it tells you to run
npm init next-app nextjs-blog --example "https://github.com/vercel/next-learn-starter/tree/master/learn-starter"
Here is what the different arguments to npm mean:
-
npm init
creates a package.json file in the current folder, which is how Node creates a "package", and an empty one at that: -
next-app
passes all the arguments toward the right tocreate-next-app
. create-next-app is an npm package that specifically creates NextJS projects.
And this means it is internally running create-next-app nextjs-blog --example "https://github.com/vercel/next-learn-starter/tree/master/learn-starter"
.
Before anything else runs, the first thing that's done is it runs npx to install create-next-app. NPX is similar to NPM but installs packages locally in your project (see below), and allows them to run as if they are global packages.
nextjs-blog
is the name of the npm package (and NextJS project) we are creating.--example
takes an argument that is the Github repository URL where it will pull project files from an initialize the project with a skeleton folder structure. It can also take a short name if the name is one of the NextJS examples collection listed here.
Once you run this command, you will get output like
npx: installed 1 in 1.609s
Creating a new Next.js app in /root/nodejs/nextjs/nextjs-blog.
Downloading files from repo https://github.com/vercel/next-learn-starter/tree/master/learn-starter. This might take a moment.
Installing packages. This might take a couple of minutes.
added 786 packages from 313 contributors and audited 788 packages in 18.305s
29 packages are looking for funding
run `npm fund` for details
found 0 vulnerabilities
Initialized a git repository.
Success! Created nextjs-blog at /root/nodejs/nextjs/nextjs-blog
Inside that directory, you can run several commands:
npm run dev
Starts the development server.
npm run build
Builds the app for production.
npm start
Runs the built app in production mode.
We suggest that you begin by typing:
cd nextjs-blog
npm run dev
create-next-app is telling us to enter the folder of the Node package we just created, nextjs-blog, and run npm run dev
on it to spin up a NextJS server. It will listen on localhost:3000, but to change the port number, use the -p PORT
option, and to change the host name, use the -H HOSTNAME
option. So a custom host name and port listened to on a TCP connection can be run like so:
npm run dev -- -H 42.42.42.42 -p 1234
Which will bind a NextJS server to TCP socket 42.42.42.42:1234. The two dashes --
are necessary to denote the end of options to npm and pass the remaining options to next
.
Top comments (3)
Thank you, this is an enjoyable intro. Also, the links are actually useful to better grasp the concepts.
Does
npx
actually installcreate-next-app
or it is a one-off run? I guess it is the second option, but I can be wrong about it.I admit it took me a while to find the answer to that question, but my reasoning for this is that since
npx
is meant to directly run packages that are not global, so local packages, it does indeed installcreate-next-app
, just in the project'snode_modules/
folder, not the global one.Scott Logic has a good article about how npx works, you should read that too.
Thank you for the reply. I believe you, I am also digging into it a bit and things are still not very clear.
In fact, what I (thought that I) knew is that
npx
can also run in a temporary way packages without the need to install them (globally/permanently).Point is, when using
npx
I do not find local installation of packages (neither innode_modules/
folder, cache, etc) that hadn't been previously installed.In my understanding,
npx
acts in different ways.First, as in the Scott Logic's article that you provide,
npx
can execute local packageswhen they are already installed
:I tracked down my first idea to Introducing npx: an npm package runner:
chaining the previous statement with the following
and with the npx(1) documentation
makes me think that there are not really clear and explicit explanations about how
npx
works in this determinate case (create-next-app
but also otherone-off commands
) but, yes, if a package is not already installed (saved inpackage.json
) it temporarily install the package, runs it, and then delete it (because for each creation of a specific project, the package will be used only once):in my system it temporarily install the package in
$HOME/.npm/_npx
, runs and then delete it. Solved :)npx
can do a lot more, as to run commands with different Node.js versions, but that's another question.Obviously, this is a personal curiosity :)