Next.js Project Structure
Explore the Next.js project structure by creating a new app and customizing configurations. Understand the roles of key directories like pages and public, how routing works, and how to organize components and utilities for scalable development.
We'll cover the following...
Now that we have some basic knowledge about Next.js use cases and the differences between client-side React and other frameworks, it’s time to look at the code. We’ll start by creating a new Next.js app and customizing its default webpack and Babel configurations. We’ll also see how to use TypeScript as the primary language for developing Next.js apps.
Default project structure
Getting started with Next.js is incredibly easy. The only system requirement is to have both Node.js and npm installed on our machine (or development environment). The Vercel team created and published the straightforward but powerful tool create-next-app for generating the boilerplate code for a basic Next.js app. The following command can be used to generate any application:
npx create-next-app <app-name>
It will install all the required dependencies and create a few default pages. At this point, we can just run npm run dev, and a development server will start on port 3000, showing a landing page.
Next.js will initialize our project using the npm package manager if installed on our machine.
npx create-next-app <app-name> --use-npm
We can also ask create-next-app to initialize a new Next.js project, downloading the boilerplate code from the Next.js GitHub repository. In fact, inside the Next.js repository, there’s a examples folder containing tons of great examples about how to use Next.js with different technologies.
Let’s say that we want to do some experiments with using Next.js on Docker. We can just pass the --example flag to the boilerplate code generator by using the following command:
npx create-next-app <app-name> --example with-docker
With this, create-next-app will download the code from GitHub and install the required dependencies for us. At this point, we only have to edit the downloaded files and customize them, and we’re ready to go.
We can find other great examples on GitHub. If you’re already familiar with Next.js, feel free to explore how Next.js can integrate with different services and toolkits.
Let’s say we have a project called my-first-next-app with the following structure:
- README.md- next.config.js- node_modules/- package-lock.json- package.json- pages/- _app.js- api/- hello.js- index.js- public/- favicon.ico- vercel.svg- styles/- Home.module.css- globals.css
If we’re coming from React, we may be used to React Router or similar libraries for managing client-side navigation. Next.js makes navigation even easier by using the pages/ folder. In fact, every JavaScript file inside the pages/ directory will be a public page, so if we try to duplicate the index.js page and rename it about.js, we’ll be able to go to the below link.
We’ll see an exact copy of our home page. We’ll look in detail at how Next.js handles client-side and server-side routes in the next chapter; for now, let’s just think of the pages/ directory as a container for our public pages.
The public/ folder contains all the public and static assets used on our website. For example, we can put our images, compiled CSS stylesheets, compiled JavaScript files, fonts, and so on there.
By default, we’ll also see a styles/ directory. While this is very useful for organizing our application stylesheets, it isn’t strictly required for a Next.js project. The only mandatory and reserved directories are public/ and pages/, so make sure not to delete or use them for different purposes.
That said, we’re free to add more directories and files to the project root because it won’t negatively interfere with the Next.js build or development process. If we want to organize our components under a components/ directory and our utilities under a utilities/ directory, we can add those folders inside our project.
If we’re not into boilerplate generators, we can bootstrap a new Next.js application by just adding all the required dependencies (as previously listed) and the basic folder structure that we just saw to our existing React application, and it’ll just work with no other configuration required.