Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
The fastest reliable way to start a Next.js project is to install Node.js 20.9 or newer, run create-next-app, start the development server, and build features inside the generated app directory. The current starter uses the App Router, TypeScript, Tailwind CSS, ESLint, Turbopack and the @/* import alias by default. This guide takes you from an empty machine to a production build, explains the App Router versus Pages Router, and shows how to structure, test and deploy the result.
What Next.js provides
Next.js is a React framework for building full-stack web applications. It handles lower-level bundling and compilation so you can concentrate on routes, components, data and shipping. The current App Router is file-system based and uses React Server Components, Suspense and Server Functions. Both the App Router and the older Pages Router are supported; a new project should normally start with the App Router unless an existing codebase or library requires Pages Router conventions.
Prerequisites
Install a supported Node.js runtime
The current installation guidance requires Node.js 20.9 or newer. Use the official Node.js installer or a version manager, then verify both tools:
node --version
npm --version
macOS, Windows (including WSL) and Linux are supported. If your version is older than 20.9, upgrade before creating the project; otherwise dependency installation or the development server may fail.
#1 Best Overall
Choose a package manager
The examples use pnpm because the official guide presents it as a quick path. npm, Yarn and Bun work with equivalent commands. Install pnpm first if it is not available:
corepack enable
corepack prepare pnpm@latest --activate
Create the project
- Run the generator from the directory where you keep source code:
pnpm create next-app@latest my-app --yes - Enter the new directory:
cd my-app - Start the development server:
pnpm dev - Open
http://localhost:3000in a browser. Edit a file and save it; Next.js will refresh the page during development.
The --yes flag accepts the recommended defaults. If you omit it, the interactive wizard asks about TypeScript, linting, Tailwind CSS, the App Router, Turbopack and the import alias. Selecting those options produces the same modern baseline.
Equivalent commands
npx create-next-app@latest my-app
# or
yarn create next-app my-app
# or
bun create next-app my-app
Understand the generated files
A fresh project contains more files than the minimum, but these are the important pieces:
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
| Path | Purpose |
|---|---|
app/layout.tsx |
Required root layout. Put shared HTML structure, metadata and site-wide UI here. |
app/page.tsx |
Renders the / route. |
app/globals.css |
Global styles imported by the root layout. |
public/ |
Optional static assets, referenced with root-relative URLs such as /logo.svg. |
next.config.* |
Optional Next.js configuration. |
package.json |
Dependencies and scripts for development, builds and production serving. |
tsconfig.json |
TypeScript compiler settings when TypeScript is enabled. |
Replace the starter markup in app/page.tsx with your own page. Keep reusable site chrome in app/layout.tsx, and create additional route segments by adding folders and a page.tsx file.
Add routes with the App Router
Static routes
To create /about, add app/about/page.tsx:
export default function AboutPage() {
return (
<main>
<h1>About</h1>
<p>Information about the project.</p>
</main>
);
}
The folder name becomes the URL segment. A nested folder such as app/blog/page.tsx creates /blog.
Rank #2
Dynamic routes
Use square brackets for a variable segment. app/posts/[slug]/page.tsx can read the slug from route parameters:
type Props = { params: Promise<{ slug: string }> };
export default async function PostPage({ params }: Props) {
const { slug } = await params;
return <article>Showing post: {slug}</article>;
}
Keep route data loading in server components when possible. This avoids sending unnecessary JavaScript to the browser.
Do these 3 things before closing this tab:
1Clear out junk files and repair common Windows errors2Scan for outdated or missing drivers - takes under a minute3Repair Windows errors before they cause bigger problemsLayouts and loading states
A layout.tsx file wraps its segment and descendants, so navigation can preserve shared UI. Add loading.tsx beside a route to provide an immediate loading state while that segment renders. Add error.tsx for a route-level error boundary when you need a tailored recovery message.
Server and client components
App Router components are server components by default. They can fetch data and render HTML without shipping their implementation to the browser. Add the 'use client' directive at the top of a component only when it needs browser APIs, event handlers or client-side state:
'use client';
import { useState } from 'react';
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Keep the client boundary as small as practical. A server page can render a client component, pass it serializable props and retain server-side data work.
Rank #3
App Router or Pages Router?
| Question | App Router | Pages Router |
|---|---|---|
| Best starting point | Modern default for new applications. | Useful when following an existing Pages-based project. |
| Routing model | Folders and files under app; layouts are built in. |
Folders and files under pages; uses the established Pages APIs. |
| React features | Server Components, Suspense and Server Functions. | Traditional client/server data-fetching APIs. |
| Migration concern | May require learning server-component boundaries. | Often the least disruptive choice for an existing application. |
The official documentation supports both routers. Choose based on your team’s existing APIs, compatibility requirements and preferred conventions rather than mixing patterns casually. You can migrate sections over time, but each router has its own file and data-fetching rules.
Static assets, styling and configuration
Serve files from public
Create public/images/hero.jpg and reference it as /images/hero.jpg. Do not include public in the URL. Keep cacheable, public resources there; private files should not be exposed from this directory.
Use the generated Tailwind setup or your own CSS
The recommended starter enables Tailwind CSS and imports global styles from the root layout. You can also write ordinary CSS modules or global CSS. Keep global rules in the global stylesheet and component-specific rules in a CSS module to reduce accidental cross-page effects.
Environment variables
Store local values in .env.local and never commit secrets. Variables intended for browser code must use the NEXT_PUBLIC_ prefix; unprefixed values remain server-side. Configure the same names in your deployment platform before building.
Build and run the production version
- Stop the development server if necessary.
- Run the production compiler:
pnpm build - Serve the generated build locally:
pnpm start - Open
http://localhost:3000again and test the production behavior, including navigation, forms, images, environment variables and error states.
The generated package.json normally contains these scripts:
Free tools Windows power users keep installed
One-click scans. No signup required.
| Script | Use |
|---|---|
next dev |
Development server with fast refresh; Turbopack is the current default bundler. |
next build |
Creates an optimized production build and reports compile or route errors. |
next start |
Serves that production build; run it only after a successful build. |
Deployment checklist
- Commit the project without
.env.local, build output or secret keys. - Set production environment variables in the hosting service.
- Run
pnpm buildin the deployment environment using Node.js 20.9 or newer. - Use the host’s start command, normally
pnpm start, unless it provides a managed Next.js runtime. - Verify every route, dynamic parameter, form action, image and external API from the deployed URL.
- Confirm that server-only code is not imported into client components and that browser-only APIs are behind a client boundary.
Troubleshooting common failures
“Node version is not supported”
Check node --version. Upgrade to 20.9 or newer, reopen your terminal, remove and reinstall dependencies, then retry the command.
Port 3000 is already in use
Stop the other process or select another port:
pnpm dev -- --port 3001
Changes are not appearing
Confirm you edited a file inside the project directory, check the terminal for compile errors and hard-refresh the browser. If the dependency tree is corrupted, stop the server, remove node_modules and the package-manager lockfile only if necessary, reinstall, and start again.
“useState” or window errors
The component is probably being treated as a server component. Add 'use client' at its top, or move the browser-only code into a small client component.
Production build fails but development works
Run pnpm build locally and read the first reported error. Common causes are missing deployment environment variables, invalid TypeScript, a server-only import in client code, or a route that relies on a development-only file.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Performance, reliability and cost considerations
Build with server components by default, limit client JavaScript, and use route-level loading and error files for predictable navigation. Test the exact production build rather than relying only on next dev. Hosting cost, caching behavior and regional latency depend on the provider and your application’s data services; Next.js itself does not prescribe one deployment platform.
Or skip the browser setup
If your Next.js workflow needs screenshots for previews, tests or documentation, ScreenshotNeo provides a single HTTP request instead of maintaining a browser automation stack. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and each response identifies the result with X-Page-Verdict and X-Billed headers.
API documentation is at https://screenshotneo.com/docs/. A basic call is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
const buffer = Buffer.from(await res.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', buffer));
ScreenshotNeo also offers an MCP server with take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. Options include full-page lazy-image capture, CSS-selector element capture, dark mode, device presets, custom viewports, retina scale, PDF page settings, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, selectable cache TTLs, signed links, asynchronous webhooks, bulk capture of up to 100 URLs per call, usage data and an OpenAPI specification. Existing parameter names used by other screenshot APIs are accepted to ease migration.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is included on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to get started.
Frequently Asked Questions
Can I use JavaScript instead of TypeScript in Next.js?
Yes. The generator can create a JavaScript project; choose JavaScript in the interactive prompts instead of accepting the TypeScript default.
Do I have to use Tailwind CSS?
No. Tailwind is a recommended default, but CSS modules, global CSS or another styling system can be used.
Can a Pages Router project and an App Router project coexist?
A migration can contain both directories, but their routing and data APIs differ. Keep each route’s conventions clear and migrate deliberately.
Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchPC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Why does my deployed app show an environment-variable error?
Local .env.local values are not automatically copied to a host. Add the required variables to the deployment provider and rebuild.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

