This is a Next.js project bootstrapped with create-next-app.
It is based on the React Router [Address Book](https://remix.run/docs/en/main/start/tutorial tutorial, but uses Next.js 16 with Server Actions, Tailwind CSS, and Prisma.
It no longer uses a global transition handler; instead, it utilizes local transitions and useFormStatus.
See branches react-hook-form and react-query for modified app versions.
- Installed Node.js
- Installed Visual Studio Code
First, install the dependencies:
npm installThen, run the development server:
npm run devOpen http://localhost:3000 with your browser to see the result.
You can start editing the page by modifying app/page.tsx. The page auto-updates as you edit the file.
This project uses next/font to automatically optimize and load Inter, a custom Google Font.
You need decide between prisma local development with sqlite or a real database with for example postgresql or sqlserver. Define it in the schema.prisma file.
Consider adding a .env file to the root of the project and use the environment variables inside schema.prisma with env("DATABASE_URL"), refer to .env.sample.
When using sqlite, initialize the database with:
npm run prisma.pushSeed prisma/seed.ts for initial data:
npm run prisma.seedTo view your data in the database, you can run:
npm run prisma.studioWhen using a real database with for example postgresql or sqlserver, you need to migrate the database schema with:
npm run prisma.migrateThe project uses ESLint for linting and Prettier for code formatting. The configuration for these tools is located in eslint.config.mjs and .prettierrc. The project is configured to run code formatting and linting on save in Visual Studio Code. Verify that code formatting and linting is executed on save as configured. Opening the .code-workspace file will ensure the correct extensions are set.
- Pascal case for components
- Kebab case for folders
- Camel case for other files
public- contains the static assets of the applicationapp- contains the pages of the application using file-based routingcomponents- contains shared components used across the applicationdata- contains server-side data fetching (data/services) and mutations (data/actions)validations- contains Zod schemas for form validationutils- contains shared utility functions- For each route, a local
_components-folder can be used to store components that are only used in that route. Same goes for_hooks,_utils, etc.
Every page folder should contain everything it needs to work. And every component or function should live at the nearest shared space in the hierarchy.
The project uses Next.js filesystem-based routing. To give a brief overview:
- Folders below the
app/-directory will be routes in the application. - For each folder inside
app/that is meant to be a route, there should be apage.tsxand alternativelylayout.tsxfor the route. - When using brackets
[]in the name of a folder, the folder will be a dynamic route. The name of the folder will be the name of the parameter in the route. - There are additional tools, such as ignoring folders from routing by prefixing with
_, and creating groups by wrapping with(). - Each route can also have a
error.tsxfile for handling application errors, and anot-found.tsxpage for handling 404 errors with notFound().
Please refer to the Next.js App Router documentation for more information.
The project uses Next.js built-in typedRoutes for type-safe navigation. Page and layout components use the globally available PageProps and LayoutProps type helpers for typed params and search params. In client components, useSearchParams from next/navigation is used to access search params.
The Next.js App Router uses React 19 Server Components, and by default all components are server components unless opted into client-side rendering with "use client". In addition, the project uses other React 19 features such as Server Functions, useFormStatus(), useOptimistic(), useActionState(), and async transitions with useTransition(). Please read the React docs on these features to understand how to use them. Read more about the use of Server Functions under Data Fetching and Mutation.
The project has cacheComponents enabled in next.config.ts. This enables the "use cache" directive and Partial Prerendering (PPR). With PPR, static page shells are prerendered at build time, and dynamic content is streamed in on request. Data that should be cached can use the "use cache" directive with cacheTag for targeted invalidation via updateTag in server actions.
The project uses the React Compiler to optimize the application. The React Compiler optimizes the application by skipping rerenders and expensive function calls, removing the need for much manual memoization. The compiler is enabled in the next.config.ts file. Pay attention to its behavior, and try to follow the eslint rules for it defined by eslint-plugin-react-compiler. Refer to the React Compiler documentation for more information.
The project uses Tailwind CSS for styling. Tailwind CSS is a utility-first CSS framework that allows you to rapidly build custom designs without leaving your HTML. The theme is configured in tailwind.config.js. Default styles are applied in /app/globals.css.
Use the cn util when merging conditional classes with other classes. Excess styling is applied in the components using Tailwind CSS utility classes. Tailwind also controls the responsive design of the application with a mobile-first approach. Refer to the Tailwind CSS documentation for more information.
The project uses Prisma for data fetching. Mutations are done using React Server Functions. Files are stored inside the data folder, where data/services are server-side data queries and data/actions are mutations. All data service functions are wrapped with React.cache() for per-render request deduplication. Take extra consideration when creating hidden endpoints with "use server" to avoid exposing sensitive data.
For more information, refer to the React Server Functions and Next.js Server Actions and Mutations documentation.
When using a form with an action, the loading state is included in the SubmitButton-component, and the form is disabled while the action is pending. For other cases, a loading state can be passed to to submit button or other components to handle the loading state.
The app can be built for production using the npm run build command. The built files will be generated in the .next folder.
The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.
Check out our Next.js deployment documentation for more details.