Understanding the File and Folder Structure of a Next.js Project

Learn how a modern Next.js project is organized. This guide explains the purpose of each file and folder in a setup using App Router, Tailwind CSS, TypeScript, ESLint, and Turbopack.

Running npx create-next-app@latest will allow you to create a Next.js Project. If it is your first time using Next.js to Folder structure could be understandably a bit overwhelming. Today I am hear to breakdown what exactly is inside a Next.js project when you accept all the defaults (TypeScript, ESLint, Tailwind, App Router, Turbopack).

What is your project named? … my-app

Would you like to use TypeScript? … No / Yes

Would you like to use ESLint? … No / Yes

Would you like to use Tailwind CSS? … No / Yes

Would you like your code inside a src/ directory? … No / Yes

Would you like to use App Router? (recommended) … No / Yes

Would you like to use Turbopack for next dev? … No / Yes

Would you like to customize the import alias (@/* by default)?No / Yes

What files & folders are in a Next.js project?

Upon initializing your project for the first time you will be presented with 12 files & folders inside of your root folder which is My-App by default.

  1. .next
  2. node_modules
  3. public
  4. src
  5. .gitignore
  6. eslint.config.mjs
  7. next-env.d.ts
  8. next.config.ts
  9. package-lock.json
  10. package.json
  11. postcss.config.mjs
  12. README.md
  13. tsconfig.json

Lets now break down the purpose of each file and folder.

The purpose of the node_modules folder explained

The node_modules folder contains all the requirements (aka dependencies required for your project to run). You won't ever be editing the files in this folder but it exists so that users like you and me can consistently build a Next.js project. The node_modules folder is where the actual code for your packages (broken up by folders) necessary to run a foundational Next.js project reside. The same way us humans have core arteries to keep us alive is exactly the same as the core folders and files that exist in the node_modules folder, which are critical to keeping the project running smoothly.

The purpose of the package.json and package-lock.json files

The package.json and package-lock.json files work together to manage dependencies in a Next.js project, but they serve slightly different purposes - almost like siblings, with one being a bit more specific than the other. Let me explain.

The package-lock.json file locks down the exact versions of each dependency used in your project. This file ensures consistency across installations, meaning that no matter who runs npm install, they will get the same versions of the packages. It helps keep your project running smoothly by ensuring no unexpected updates are introduced.

On the other hand, the package.json file is a bit more flexible. It defines the dependencies and their version ranges (i.e. "next": "^14.0.0"). This allows your project to install newer versions of dependencies, as long as they fall within the specified range. This gives some room for updates and new features, while still maintaining compatibility.

When you run npm install on a project, your computer will use the exact versions specified in the package-lock.json file - even if newer versions exist - as long as the lock file is in sync with the package.json file.

The package-lock.json file only updates if it is missing, out of sync, or if you force an update like npm update.

By out of sync I mean when a new dependency is added, a dependency is removed, or a dependency is out of the range specified in the package.json file.

The purpose of the public folder in a Next.js project

The public folder in a Next.js project is used to serve any files you'd like to publicly display in the browser at the root URL of your site. This includes static assets such as images, the robots.txt file, and the sitemap.xml file.

For example, if you add an image called logo.png to the public folder, it would be accessible in the browser at:

  • matthewseiwert.com/logo.png and not matthewseiwert.com/public/logo.png

The public folder is a great place to store images like a logo and other files that need to be directly accessible via URL, such as for SEO purposes. Whenever you want simplicity and reusability of an asset use the public folder.

However, if you import an image in a Next.js component and use it with the next/image component, the image will not have a public URL. Instead, it is handled internally by Webpack and Next.js, allowing for features like automatic optimization (converting images to more efficient formats like WebP or other formats suitable for the user’s browser), responsive loading (dynamically resized images), and cache busting (latest version of images is available) which makes it a better option for performance inside your app. If you use next/image best practice is to store images in a folder like src/assets/images/ or externally hosted in the cloud.

The purpose of the src folder in a Next.js project

The src folder is where you where you will build your Next.js application and directly manage your code. The src folder is like your workbench. The src folder also holds an important folder called app. Every folder inside the app folder will serve as a route with a url path in the browser. Ever folder inside the app folder has a page.tsx file and if needed a layout.tsx file. The page.tsx file is where you add the code to build out the component for a route. The layout.tsx file determines the structure or shell the wraps the main route and any children routes within a folder. Let us say you have a membership site with two interfaces:

  1. The public-facing site that promotes the membership
  2. The user dashboard that members see when they sign in

You can define the layout for all the urls of the public-facing site in one folder and then define the layout of all the urls for the member dashboard in another.

The purpose of the .next folder in a Next.js project

You'll notice that this is not initially visible in your project when you run npx create-next-app@latest to initialize your Next.js project. You'll need to run one of the following commands to create the .next folder

npm run dev - test development version locally to view in the browser at localhost (includes automatic refresh on code updates aka hot-reloading) npm run build - test production version locally and view in the browser at localhost

The .next folder is where your optimized next app is packaged up and resides.

The purpose of the .gitignore file

The .gitignore file is used to exclude any unnecessary bloat (like node_modules) and any sensitive information (like environment variables in a .env file). You don't want dependencies save directly in repository. That will make the file size enormous. You don't want sensitive information visible in the browser that information. That information should be stored server side when you deploy. You will only need the .env for local testing and should then exclude it in the .gitignore file. Any files added to .gitignore will not be included when you push your project to GitHub and it saves as a repository.

The purpose of the config files

  1. eslint.config.mjs - This is the ESLint configuration file and it can be adjusted to change how errors are spotted in your project (more strict or more lenient).
  2. next-env.d.ts - This is config file is for when you use Typescript with Next.js. It allows Typescript to better understand a Next.js project.
  3. next.config.ts - This is a Next.js config file if wish to modify any Next.js defaults
  4. postcss.config.mjs - This is a PostCSS config file, a tool that processes your CSS and allows you to use modern CSS features, polyfills (code that allows modern functionality to work in older browsers), and even JavaScript to enhance your styles
  5. tsconfig.json - This is the TypeScript config file and controls how TypeScript compiles your TypeScript code into JavaScript. You can customize TypeScript for your project in this file.

The purpose of the README.md

The README.md is a file that you can use to add important documentation about your Next.js project. Next.js includes this file to provide any users who initialize a Next.js app the information to understand a little bit more about the project. This can be deleted if desired.

No fluff. Just real projects, real value, and the path from code to cash — one useful build at a time.

Copyright 2025 Matthew Seiwert