vercel/next.js / web framework

Next.js: read this before you install it

Next.js is not hard to create; it is hard to keep understandable after routing, rendering, caching, server actions, images, and deployment rules start interacting. I would use it carefully: one route, one data source, one deployment check before turning it into an entire product shell.

Project source: vercel/next.js
Author / organization: Vercel
This page is a private experience note, not official documentation.
Future ad placement. Separated from navigation and action links.

Do not start by choosing every option

I would not start Next.js by accepting every fashionable option. TypeScript, App Router, Tailwind, ESLint, and a src directory can all be good choices, but each adds structure the team now has to understand. I start with the app shape: do I need server-rendered pages, API routes, static content, or an interactive dashboard?

The first command is usually `npx create-next-app@latest`, but the first decision happens before that. If the project is a content site, I keep server logic minimal. If it is an app, I decide where data fetching happens and how auth will be handled before adding pages.

Next.js feels productive until caching and runtime boundaries surprise you. I would rather create one route and inspect the build output early than build ten pages and discover that the thing only worked in dev mode.

When Next.js is worth the framework surface

Next.js fits when the project needs a serious web surface: routing, layouts, SEO, server-rendered content, API handlers, and a path to deploy. It is a good default when the frontend is part of the product, not just a quick admin panel.

I would not use it for every tiny UI. If the whole project is a single static page, plain HTML or a lighter framework may be clearer. If the backend is doing almost all the work, a simple client app may be easier to reason about.

My fit test is whether I need both page structure and deployment discipline. If yes, Next.js is worth the surface area. If I only need a button that calls an API, I do not reach for it automatically.

Routing, rendering, and cache rules matter first

I read a Next.js app through three boundaries: route structure, rendering mode, and data access. Where is the page? Does it run on the server or client? Is data fetched at request time, build time, or behind an action? Most bugs I see come from mixing those boundaries without noticing.

The App Router encourages neat layouts, but it also hides complexity behind folders. I check `app/`, `components/`, `lib/`, and environment variables before judging the app. A clean folder tree is not proof of a clean runtime model.

I also check caching early. If a page shows old data, I do not immediately blame the database. I look at fetch caching, route segment config, revalidation, and whether I accidentally made a server component behave differently from what I expected.

Create a small app, not a full system

My setup path is to create the app, run it locally, add one route, and immediately run a production build. `npm run dev` proves almost nothing about deployment. `npm run build` is where missing environment variables, server-only imports, and type problems start talking.

Before adding auth or a database, I add one API route or server action that returns a harmless status object. Then I call it from the page. This shows me where server code lives and whether the app structure is understandable.

I keep `.env.local` small and named. If a variable is needed in the browser, I make that explicit with the right prefix. If it is a secret, it never goes to a client component.

My Next.js command path

Use the prep panel before scaffolding if you are not sure about Node, package manager, or project choices. This is where I check the runtime and choose the smallest app options that still match the product.

Use the verify panel after the first page and after every new boundary: API route, server action, auth provider, image config, or deployment target. Run the build before you trust the dev server.

Use the debug panel when local dev works but build or deployment fails. That is usually an environment, runtime, import, caching, or server/client boundary problem. Do not rewrite components until you know which boundary broke.

When dev works but production disagrees

If dev works and build fails, I read the first build error, not the last stack trace. Next.js often reports the real problem early: invalid import, missing env, incompatible runtime, or a component used on the wrong side.

If production shows stale data, I check caching before touching the database. A working query can still look broken if the page is cached longer than I think.

If a secret appears in the browser bundle, I stop and fix environment usage. That is not a styling bug; it is a deployment safety issue.

The first route I would ship

The first route I would ship is a public status or field-note page with one server-side data read and one metadata block. It tests routing, metadata, server code, build, and deployment without dragging auth into the first hour.

After that I would add one protected route, not a full dashboard. Auth changes the mental model, and I want to see the redirect and session behavior clearly.

Only after those two paths work would I build the rest of the app shell. Next.js is best when you respect its boundaries early.

How I would use the command panel

Use the Next.js commands by rendering boundary

choices matter — Before creating the app, confirm Node/npm and choose routing, TypeScript, linting, and package manager deliberately instead of accepting every option blindly.

dev is not enough — After each route or data boundary, run dev, build, and start. A page that works in dev can fail under build, cache, or server/client rules.

boundary failure — When production disagrees with local dev, isolate env vars, server/client imports, fetch cache, runtime settings, and deployment logs before rewriting UI.

Field commands I would keep beside this note

# Next.js prep

node -v
npm -v
npx create-next-app@latest --help

# choose options deliberately
npx create-next-app@latest field-notes --ts --app --eslint
# Next.js verify

cd field-notes
npm run dev
# open http://localhost:3000

npm run build
npm run start

# add one route, then build again
# Next.js debug

# build differs from dev
npm run build

# inspect env names
printenv | grep -E "NEXT_|DATABASE|API"

# stale data -> inspect fetch cache / revalidate settings
# client error -> check server/client component boundary