DEV Community

Ali Sherief
Ali Sherief

Posted on

Introduction to NextJS

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)

(Credits: [1] [2])

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"
Enter fullscreen mode Exit fullscreen mode

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 to create-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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

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)

Collapse
 
maxdevjs profile image
maxdevjs

Thank you, this is an enjoyable intro. Also, the links are actually useful to better grasp the concepts.

Does npx actually install create-next-app or it is a one-off run? I guess it is the second option, but I can be wrong about it.

Collapse
 
zenulabidin profile image
Ali Sherief

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 install create-next-app, just in the project's node_modules/ folder, not the global one.

Scott Logic has a good article about how npx works, you should read that too.

Collapse
 
maxdevjs profile image
maxdevjs • Edited

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 in node_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 packages when they are already installed:

Make sure you --save or --save-dev the package first. This keeps dependent packages listed in package.json, so that npx can use the local version instead of downloading it to the npm cache.

I tracked down my first idea to Introducing npx: an npm package runner:

npx can also execute one-off commands as in the case of npx create-react-app my-cool-new-app, which installs a temporary create-react-app and calls it, without polluting global installs.

chaining the previous statement with the following

By the time you run them again, they’ll already be far out of date, so you end up having to run an install every time you want to use them anyway.

and with the npx(1) documentation

If a full specifier is included, or if --package is used, npx will always use a freshly-installed, temporary version of the package. This can also be forced with the --ignore-existing flag.

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 other one-off commands) but, yes, if a package is not already installed (saved in package.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 :)