This note is for people who use AI to write code but do not yet have a stable map of frontend engineering.
It is not a computer science course, and it is not a full React, Vue, Tailwind, or Next.js tutorial. It is a practical engineering map: when you ask an AI agent to edit a page, build an interface, connect an API, fix a bug, or deploy a project, you should at least know what you are looking at, what to ask, and how to verify the result.
After reading it, the goal is not to hand-write a complex app from scratch. The goal is to do three things:
- Place common terms into layers: HTML/CSS/JavaScript, React/Vue, Tailwind, Vite, Next.js, npm/pnpm.
- Open a frontend project and find the entry points:
package.json,src/,components/,app/,pages/,public/, and config files. - Review AI-generated frontend changes: did the agent read real files, connect real data, handle states, and run a build, or did it only create a page that looks plausible?
1. A software project is a chain, not a pile of code
A project can be viewed like this:
Code files
-> interpreted, compiled, or bundled
-> run inside a browser, Node.js, Python, Java, Go, or a shell
-> become processes managed by the operating system
-> use files, ports, environment variables, permissions, and networks
-> connect to databases, APIs, object storage, third-party platforms, or cloud services
A web app is one common shape of this chain:
User
-> browser
-> frontend page
-> API request
-> backend service
-> database, file storage, or third-party service
So when debugging, do not only ask whether a line of code is correct. Many bugs look like code bugs, but the real cause is a path, permission, port, environment variable, dependency version, runtime mismatch, network issue, or deployment setting.
A useful layered checklist:
| Layer | First question |
|---|---|
| Files | Where is the file? Is the current working directory correct? Is this an absolute or relative path? |
| Runtime | Who executes this code: browser, Node, Python, or a server process? |
| OS | Are permissions, processes, ports, environment variables, and files as expected? |
| Network | Where does the request start? What host and port is it targeting? Which machine does localhost refer to? |
| Services | Are the backend, database, and third-party APIs actually reachable? What status and logs do they return? |
The value of this map is that it removes the magic from "AI-generated code." Code needs a runtime. The runtime runs on a system. The system needs the right files, ports, and services.
2. The web basics: HTML, CSS, and JavaScript
All complex frontend frameworks eventually come back to three things:
| Technology | Responsibility | Intuition |
|---|---|---|
| HTML | Page structure | What exists on the page |
| CSS | Page style | How it looks |
| JavaScript | Page behavior | What happens after clicks, input, loading, and state changes |
Minimal example:
<button id="save">Save</button>
button {
background: black;
color: white;
padding: 8px 12px;
}
document.querySelector("#save").addEventListener("click", () => {
alert("Saved");
});
You can read it as:
HTML says: there is a button.
CSS says: the button has a black background, white text, and padding.
JavaScript says: when the button is clicked, show a message.
React, Vue, Svelte, Next.js, Nuxt, and Tailwind do not replace this foundation. They organize HTML, CSS, and JavaScript in ways that scale better for real applications.
3. DOM: the page structure the browser sees
The browser does not treat HTML as a plain string. It parses HTML into a tree called the DOM.
<main>
<h1>Notes</h1>
<button>Save</button>
</main>
You can imagine:
main
-> h1
-> button
JavaScript can modify the DOM:
document.querySelector("button").textContent = "Saved";
Traditional frontend code often manipulates the DOM directly. Modern frameworks more often let you describe what the page should look like for the current state, and the framework updates the DOM for you.
This is why React and Vue keep talking about state, render, and components: they manage how the UI changes when state changes.
4. Components: reusable pieces of UI
A component is a function or module that produces one piece of UI.
For example, instead of hand-writing the same button style everywhere, you can define a Button:
function Button({ label }: { label: string }) {
return <button className="rounded px-3 py-2">{label}</button>;
}
Then use it:
<Button label="Save" />
<Button label="Cancel" />
Why components help:
| Benefit | Meaning |
|---|---|
| Reuse | The same UI pattern does not need copy-paste |
| Composition | A page can be built from Header, Sidebar, Card, and Button |
| Local understanding | Read small components before reading the full page |
| State isolation | Modals, forms, and dropdowns can manage their own state |
Common component names:
Button
Card
Navbar
Sidebar
Modal
Dropdown
Form
Table
PostList
UserAvatar
In a frontend project, components/ is usually where these reusable UI pieces live.
5. What React is
React is a JavaScript library for building user interfaces. Its core idea is to organize UI with components, pass data with props, and represent change with state.
Minimal React component:
function Greeting({ name }: { name: string }) {
return <h1>Hello, {name}</h1>;
}
Three core words:
| Word | Meaning |
|---|---|
| component | A reusable piece of UI |
| props | Data passed from a parent component to a child component |
| state | Data a component remembers and updates over time |
Example with state:
import { useState } from "react";
function Counter() {
const [count, setCount] = useState(0);
return (
<button onClick={() => setCount(count + 1)}>
Count: {count}
</button>
);
}
This code is not manually editing the DOM. It says:
Display the current count in the button.
When the user clicks, update count to count + 1.
React re-renders the relevant UI.
The daily React concepts introduced in the official learning path are exactly this kind of material: creating and nesting components, JSX, styles, displaying data, conditional rendering, lists, events, state, and sharing data between components.
6. JSX and TSX: why JavaScript looks like HTML
React code often contains this:
return <h1>Hello</h1>;
It looks like HTML, but it is JSX. JSX is a syntax for describing UI inside JavaScript or TypeScript.
Common extensions:
| File | Meaning |
|---|---|
.js | JavaScript |
.jsx | JavaScript + JSX |
.ts | TypeScript |
.tsx | TypeScript + JSX, common for React components |
Browsers usually cannot directly understand a full TSX project. Tools like Vite, Next.js, webpack, SWC, Babel, and TypeScript transform the code into JavaScript that browsers can load.
When you see .tsx, think:
This is usually React UI written in TypeScript.
It may be a component or a page.
It needs tooling before the browser can run it.
7. Vue, Svelte, and React solve the same class of problem
React is not the only frontend framework. You will often see Vue and Svelte too.
| Framework | Rough understanding |
|---|---|
| React | Organizes UI with JavaScript/JSX; largest ecosystem; Next.js builds on it |
| Vue | Organizes UI with templates, reactive data, and components; feels closer to HTML at first |
| Svelte | A compiler-oriented framework; many things happen at build time |
Vue component example:
<template>
<button @click="count++">Count: {{ count }}</button>
</template>
<script setup>
import { ref } from "vue";
const count = ref(0);
</script>
React version:
function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
They answer similar questions:
How do we split a page into components?
How does the UI update when data changes?
How do we handle user events?
How do we organize a large frontend project?
So when you first hear React, Vue, and Svelte, do not put them in three unrelated universes. Put them in the same drawer: frontend UI frameworks.
8. State: where many frontend bugs come from
State means "what is true right now."
Common state:
Whether the user is logged in
The selected tab
The text inside an input
Whether a list is loading
Whether an API request failed
Whether a modal is open
Items in a shopping cart
A list page is not only "show the list." It usually has:
initial
-> loading
-> success with data
-> success with empty list
-> failure with visible error
-> retry
Many AI-generated pages only handle the happy path:
The API always succeeds.
Data always exists.
The network is always fast.
The user always follows the perfect path.
Real products need loading, empty, error, and success states. When asking AI to edit frontend code, keep asking:
How does loading look?
How does empty data look?
How does API failure look?
What happens on repeated clicks?
Does state survive refresh?
Does this state come from the URL, server, local cache, or user input?
9. CSS: the foundation of styling
CSS controls how the page looks:
colors
fonts
spacing
layout
borders
shadows
animations
responsive behavior
Example:
.card {
border: 1px solid #e5e7eb;
border-radius: 8px;
padding: 16px;
background: white;
}
The hard part of CSS is not only syntax. It is scaling it:
| Problem | Example |
|---|---|
| Naming | Should this be .card-title or .primaryButton? |
| Scope | Will one page's styles affect another page? |
| Reuse | How do buttons, cards, and tables stay consistent? |
| Responsive design | How does the page adapt to phone, tablet, and desktop? |
| Design system | Are colors, fonts, spacing, and radius consistent? |
This is why the ecosystem has CSS Modules, Tailwind, Sass, styled-components, component libraries, and design systems. They all try to answer: how do we write styles without making a mess?
10. What Tailwind CSS is
Tailwind CSS is a utility-first CSS framework. In plain terms, it gives you many small single-purpose classes, and you compose them to create styles.
Traditional CSS:
.button {
display: flex;
align-items: center;
gap: 8px;
border-radius: 8px;
padding: 8px 16px;
}
Tailwind style:
<button class="flex items-center gap-2 rounded-lg px-4 py-2">
Save
</button>
Common Tailwind classes:
| Class | Meaning |
|---|---|
flex | Use flex layout |
items-center | Align items vertically |
gap-2 | Space between children |
rounded-lg | Larger border radius |
px-4 | Horizontal padding |
py-2 | Vertical padding |
text-sm | Small text |
bg-white | White background |
border | Border |
Responsive design can also be expressed in classes:
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3">
...
</div>
Meaning:
Default: 1 column.
Medium screens and up: 2 columns.
Large screens and up: 3 columns.
Tailwind does not mean you no longer need to understand CSS. It turns common CSS patterns into composable phrases. The more CSS you understand, the easier Tailwind is to read.
11. Component libraries, Headless UI, shadcn/ui, and design systems
Frontend projects usually do not build every button, modal, menu, and table from zero.
Common layers:
| Layer | What it solves |
|---|---|
| CSS / Tailwind | Atomic styling and layout |
| Component library | Ready-made Button, Modal, Table, etc. |
| Headless UI | Interaction and accessibility without forcing a visual style |
| Design system | Product-specific colors, typography, spacing, and component rules |
Examples:
Material UI
Ant Design
Chakra UI
Headless UI
Radix UI
shadcn/ui
Rough differences:
| Type | Intuition |
|---|---|
| Material UI / Ant Design | A full visual system and component set |
| Headless UI / Radix UI | Interaction logic and accessibility foundation; you style it |
| shadcn/ui | Component source copied into your project, often with Tailwind and Radix |
AI agents often introduce a new component library too casually. Ask the agent to inspect the project's existing UI system first instead of mixing in a new visual language.
12. TypeScript: JavaScript with types
TypeScript is JavaScript with types.
JavaScript:
function add(a, b) {
return a + b;
}
TypeScript:
function add(a: number, b: number): number {
return a + b;
}
Types catch some errors before runtime:
This value may be undefined.
This field does not exist.
This function needs a number, but you passed a string.
The API response shape does not match what the component expects.
In frontend projects, TypeScript appears as:
.ts
.tsx
tsconfig.json
types/
interface
type
When AI edits TS/TSX files, ask it to run typecheck or build. Many plausible-looking changes fail only when TypeScript or Next.js checks the project.
13. npm, pnpm, and yarn: package managers
Modern frontend projects depend on third-party packages. Package managers download dependencies, lock versions, and run scripts.
Common package managers:
| Tool | Lockfile |
|---|---|
| npm | package-lock.json |
| pnpm | pnpm-lock.yaml |
| yarn | yarn.lock |
| bun | bun.lock |
The key file is package.json:
{
"scripts": {
"dev": "next dev",
"build": "next build"
},
"dependencies": {
"react": "^19.0.0",
"next": "15.3.3"
}
}
Command intuition:
| Command | Meaning |
|---|---|
npm install | Install dependencies |
npm run dev | Start the development server |
npm run build | Build the production version |
npm test | Run tests, depending on scripts |
npx xxx | Temporarily run a command from a package |
Do not mix package managers. If the project has pnpm-lock.yaml, do not casually run npm install and create package-lock.json.
14. Vite, webpack, Babel, and SWC: build tools
Browsers do not directly understand every modern frontend project. Build tools transform source code into something browsers can load.
| Tool | Intuition |
|---|---|
| Vite | Modern dev server and build tool; fast startup |
| webpack | Classic bundler; powerful but often complex |
| Babel | JavaScript compiler, often used for new syntax and JSX |
| SWC | Fast Rust-based compiler, used by Next.js |
| esbuild | Fast Go-based build tool, used in the ecosystem around Vite |
Vite projects often look like:
vite.config.ts
src/main.tsx
src/App.tsx
Next.js projects often look like:
next.config.js
src/app/page.tsx
src/app/layout.tsx
You do not need to configure these tools on day one. But when an error comes from Vite, webpack, Babel, SWC, or TypeScript rather than your business code, recognize it as a build-layer issue.
15. ESLint, Prettier, and PostCSS: code quality and CSS processing
These tools also appear frequently:
| Tool | Responsibility |
|---|---|
| ESLint | Checks potential bugs and project rules |
| Prettier | Formats code automatically |
| PostCSS | Processes CSS; Tailwind often integrates through it |
ESLint is more like rule checking:
Unused variables.
Wrong React Hook usage.
Missing dependencies.
A pattern the project does not allow.
Prettier is more like automatic layout:
indentation
line breaks
quotes
semicolons
When AI edits a project, and the project has lint/typecheck/test/build commands, ask it to run the relevant ones. Do not only trust "fixed" in prose.
16. Next.js, Nuxt, and SvelteKit: full-stack frameworks
React, Vue, and Svelte focus mainly on UI. Next.js, Nuxt, and SvelteKit are fuller application frameworks.
| Framework | Built on | Intuition |
|---|---|---|
| Next.js | React | Full-stack React framework |
| Nuxt | Vue | Full-stack Vue framework |
| SvelteKit | Svelte | Full-stack Svelte framework |
Next.js is officially framed as a React framework for building full-stack web applications:
React handles components and UI.
Next.js adds routing, rendering, build behavior, server capabilities, and optimizations.
Typical Next.js App Router structure:
src/app/
layout.tsx
page.tsx
blog/
page.tsx
[slug]/
page.tsx
api/
route.ts
Meaning:
| File | Meaning |
|---|---|
layout.tsx | Page shell or shared layout |
page.tsx | Page for a route |
[slug] | Dynamic route parameter |
route.ts | API route, closer to backend code |
In Next.js, a .tsx file is not automatically browser-only. Some components render on the server; some need "use client" to use browser interaction.
17. Server and client components: an easy Next.js boundary to mix up
In the Next.js App Router, components are server-oriented by default. If a component needs browser interaction, it often starts with:
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}
Rough guide:
| Code needs | More likely belongs |
|---|---|
| Database access | Server |
| Secret environment variables | Server |
fs | Server |
useState | Client |
| Click and input events | Client |
localStorage | Client |
Key rules:
Secrets must not go to the browser.
Database connections must not go to the browser.
Interactive UI state usually lives on the client.
Data fetching and permission checks usually go back to the server.
AI can easily mix server and client code. When you see errors like window is not defined, document is not defined, fs not found, or useState only works in Client Components, think about runtime location first.
18. Real mapping: what this PRISM site uses
This personal site is a useful example.
Its stack is roughly:
| Layer | This site uses |
|---|---|
| Application framework | Next.js 15 |
| UI library | React 19 |
| Language | TypeScript |
| Styling | Tailwind CSS 4 |
| Animation | Framer Motion |
| Content | TOML config + Markdown body |
| State | Zustand for theme/locale |
Important directories:
content/
content_zh/
public/
src/app/
src/components/
src/lib/
src/types/
What they mean:
| Path | Role |
|---|---|
content/ | English content |
content_zh/ | Chinese content |
public/ | Static assets and agent-readable files |
src/app/ | Next.js routes and pages |
src/components/ | Reusable components |
src/lib/ | Helpers for reading config, content, and posts |
src/types/ | TypeScript types |
This note lives in:
content_zh/notes/vibe-coder-engineering-basics.md
content/notes/vibe-coder-engineering-basics.md
It appears in the Notes list because of:
content_zh/notes.toml
content/notes.toml
Those files contain an entry like:
[[items]]
title = "Engineering Basics for Vibe Coders"
slug = "vibe-coder-engineering-basics"
source = "notes/vibe-coder-engineering-basics.md"
Next.js then generates:
/notes/vibe-coder-engineering-basics/
That is the chain: content file -> TOML index -> page route -> static site.
19. Where to start when opening a frontend project
Do not immediately dive into a random component. A better order:
- Read
package.json: project name, dependencies, scripts. - Check the lockfile: npm, pnpm, yarn, or bun.
- Check framework config:
next.config.js,vite.config.ts,tailwind.config.js,tsconfig.json. - Read the directory structure:
src/,app/,pages/,components/,public/. - Find entry points: in Next.js,
app/page.tsxandapp/layout.tsx; in Vite,src/main.tsx. - Find routes: how URLs map to files.
- Find data: Markdown, TOML, API, database, or mock data.
- Run it with the real dev/build commands.
You can ask AI to produce a project map first:
Do not edit code yet. Read this frontend project and output:
1. Framework and package manager.
2. dev/build/test/lint commands.
3. Page entry points and route structure.
4. Component directories and major UI components.
5. Styling approach: CSS, Tailwind, component library, or mixed.
6. Data source: local files, API, database, or mock.
7. Which code runs in the browser and which runs on the server.
8. The easiest parts for an AI agent to break.
Answer from real files and include paths.
20. Frontend to backend: API, fetch, and JSON
Frontend code often talks to backend code through HTTP APIs.
const res = await fetch("/api/todos");
const todos = await res.json();
The chain is roughly:
Browser sends GET /api/todos
Backend receives the request
Backend reads the database or calls another service
Backend returns JSON
Frontend turns JSON into state
React/Vue renders UI from that state
JSON looks like:
{
"items": [
{ "id": 1, "title": "Learn React" }
]
}
A mature frontend request handles:
| State | What the UI should do |
|---|---|
| loading | Show loading state |
| success + data | Show data |
| success + empty | Show empty state |
| error | Show error and retry |
| unauthorized | Ask the user to log in or redirect |
AI often writes only:
const data = await fetch(...).then(r => r.json());
return <List items={data} />;
Real applications also need failure, empty data, permissions, repeated submit, and slow network handling.
21. CORS, cookies, tokens, and secrets
These security and network concepts belong together.
CORS
CORS is a browser cross-origin security rule.
For example, frontend:
http://localhost:5173
Backend:
http://localhost:3000
The ports differ, so the browser treats them as different origins. If the backend does not allow the frontend origin, the browser may block the request.
Important: CORS is a browser restriction. curl working does not mean the browser will work.
Cookie and token
After login, frontend requests usually carry some credential:
| Method | Intuition |
|---|---|
| Cookie + Session | Browser sends cookies automatically; backend checks session |
| Bearer Token / JWT | Frontend sends token in a header |
Secret
Secrets must not be exposed to users:
database password
API key
OAuth client secret
private token
Frontend code is shipped to the user's browser, so do not put secrets in frontend components.
In Next.js, environment variables beginning with NEXT_PUBLIC_ are usually intended to be exposed to the browser. Secrets without that prefix should stay on the server.
22. Deployment: local success does not mean users can use it
During development:
npm run dev
Before release:
npm run build
Some projects also use:
npm run start
Deployment concerns:
| Item | Common issue |
|---|---|
| Node version | Local Node 22, production Node 18 |
| Build command | dev works, build fails |
| Environment variables | .env.local exists locally, production config is missing |
| API URL | Production still points to localhost |
| Database | Migration not applied |
| Static assets | Image paths, base path, CDN cache |
| Logs | No one knows where failures appear |
For static sites and content sites, also pay attention to:
sitemap.xml
robots.txt
llms.txt
llms-full.txt
site.json
JSON-LD
These are not the main pages for human readers. They help search engines, AI agents, and retrieval tools understand the site.
23. Common mistakes when AI edits frontend code
Common issues:
| Issue | Symptom |
|---|---|
| Static fake page only | Looks nice but does not connect real data |
| Happy path only | No loading, empty, or error state |
| Mixed UI style | A restrained project suddenly gets a flashy unrelated component |
| Mixed package managers | Project uses pnpm, AI creates package-lock |
| Broken server/client boundary | Browser code uses secrets or fs |
| Did not read real files | Creates duplicate components from imagination |
| Did not run build | TypeScript or Next.js build would have caught the issue |
| Overwrites user changes | Rewrites files without checking git status |
A good instruction is not just "make it prettier." It is:
Read the real files and existing components first.
Preserve the current design language.
Reuse existing components and helpers.
Use real APIs or real content sources, not fake data pretending to be connected.
Handle loading / empty / error / success.
Explain which code runs in the browser and which runs on the server.
Do not mix package managers.
Do not overwrite existing uncommitted changes.
Finally run the relevant lint / typecheck / test / build commands.
24. Prompt templates for AI frontend work
Read a project
Do not edit code yet. Read this frontend project and output a project map:
1. Tech stack: framework, language, styling, package manager.
2. Scripts: what dev/build/test/lint do.
3. Routing: how URLs map to files.
4. Components: main component directories and reuse patterns.
5. Data: API, database, local files, or mock.
6. Runtime location: browser vs server.
7. Risk: what is easiest to break.
Answer from real files and include paths.
Edit UI
I want to modify this page: [page/path].
First read the existing components and styling system.
Preserve the current design language.
Reuse existing components and do not introduce a new UI library unless the project already uses it.
Handle mobile layout, long text, empty data, loading, and error states.
After editing, run relevant verification commands and summarize touched files.
Connect an API
I want to connect this page to a real API: [API description].
First confirm API path, method, request parameters, response JSON shape, and error states.
The frontend must handle loading / success / empty / error / unauthorized.
Do not put secrets in the browser.
If backend changes are needed, explain server files and permission checks.
Finally verify with real commands or browser Network evidence.
Fix a bug
This frontend has a bug: [symptom].
Do not guess the fix directly. First:
1. Find the related component, state, and data flow.
2. Reproduce with logs, tests, or browser behavior.
3. Explain the root cause.
4. Make the smallest fix.
5. Run relevant verification commands.
6. State what remains unverified.
25. System basics: how programs live on a machine
A frontend project may look like a pile of .tsx, .css, and .json files, but once it runs, it depends on the operating system.
You can think of the operating system as the foundation that keeps programs alive. It manages:
files
directories
processes
memory
permissions
environment variables
ports
networking
devices
Common systems:
| System | Common role |
|---|---|
| macOS | Local development, especially personal machines |
| Linux | Servers, containers, cloud machines, and CI |
| Windows | Desktop development, enterprise environments, games, and some toolchains |
Many "it works locally but fails online" problems are not pure code logic bugs. They come from system differences.
Files, directories, and paths
A path tells the system where a file is:
/Users/haoqing/Documents/Github/app/package.json
src/app/page.tsx
../shared/config.json
Terms to separate:
| Term | Meaning |
|---|---|
| absolute path | Full path from the filesystem root |
| relative path | Interpreted relative to the current working directory |
| cwd | Current working directory |
| home | User home directory, such as /Users/haoqing |
| hidden file | File beginning with ., such as .env or .gitignore |
The same command can behave differently in different directories:
pwd
ls
cd app
npm run build
When asking AI to run commands or debug paths, ask it to confirm pwd and whether the target files exist.
Processes: after code starts running
Code files sit on disk. Once they run, they become processes.
npm run dev
This may start a Next.js or Vite development server process.
Useful commands:
ps aux | rg node
lsof -i :3000
kill <pid>
Concepts:
| Concept | Meaning |
|---|---|
| process | A running program |
| PID | Process identifier |
| foreground | Process occupying the current terminal |
| background | Process running behind the scenes |
| stdout | Normal output |
| stderr | Errors and logs |
| exit code | 0 usually means success |
Common traps:
An old process is still using the port.
You thought the service restarted, but the old process is still running.
You killed the wrong process and broke another service.
A background process is still consuming CPU or a port.
Permissions: why Permission denied happens
Files and commands have permissions. You may see:
-rw-r--r-- file.txt
-rwxr-xr-x script.sh
Roughly:
| Letter | Meaning |
|---|---|
| r | read |
| w | write |
| x | execute |
If a script cannot run, it may need:
chmod +x script.sh
./script.sh
But do not blindly add sudo whenever you see a permission error. sudo uses administrator permissions, can change file ownership inside a project, and can hide the real deployment permission issue.
PATH: why command not found happens
PATH is the list of places where the system searches for commands.
If you see:
command not found: node
command not found: pnpm
command not found: python
Common causes:
The tool is not installed.
The tool is installed but not in PATH.
The current shell did not load its config.
The local terminal, desktop app, CI, and deployment environment have different PATH values.
The command name is wrong.
Checks:
which node
which pnpm
echo $PATH
node -v
pnpm -v
Environment variables: runtime configuration
Environment variables are configuration that is not directly written into code:
NODE_ENV=production
DATABASE_URL=postgres://...
OPENAI_API_KEY=...
NEXT_PUBLIC_SITE_URL=...
Common files:
.env
.env.local
.env.example
Basic rules:
Secrets do not go to the frontend.
Having .env.local locally does not mean production has the same variables.
Deployment platforms need environment variables configured separately.
Changing environment variables often requires restarting the process or redeploying.
Variables like NEXT_PUBLIC_ are usually exposed to the browser.
Local, remote, container, and CI are different worlds
The same word localhost points to different machines in different contexts:
| Context | localhost means |
|---|---|
| Terminal on your Mac | Your Mac |
| After SSH into a server | The remote server |
| Inside a Docker container | The container itself |
| GitHub Actions / CI | The CI runner |
| Browser | The machine running the browser |
This matters a lot. Many network and deployment bugs come from mixing up local localhost and remote localhost.
Prompt for system debugging
Please debug from the system layer first, not by guessing a code bug.
Confirm the current machine, current directory, Node/Python version, PATH, environment variables, running processes, port usage, and file permissions.
Distinguish local machine, remote server, container, and CI environment.
Show actual commands and outputs before judging root cause.
26. Network basics: how requests move between places
Networking is how programs talk to each other. Browsers opening pages, frontend code calling APIs, backend services connecting to databases, and platforms forwarding requests are all network activity.
URLs and links
A URL can be split into parts:
https://example.com:443/blog/post-1?ref=home#comments
| Part | Meaning |
|---|---|
https | Protocol |
example.com | Host / domain |
443 | Port |
/blog/post-1 | Path |
?ref=home | Query string |
#comments | Fragment, used inside the browser |
A link points to another URL:
<a href="/about">About</a>
In React/Next.js, you may see framework-provided links:
<Link href="/about">About</Link>
The framework can handle navigation without a full page reload.
Redirects: frontend navigation vs HTTP redirect
There are several kinds of navigation:
| Behavior | Example | Intuition |
|---|---|---|
| Normal link | <a href="/about"> | Browser visits another URL after a click |
| Frontend route navigation | Next.js Link / router | The frontend framework handles navigation |
| HTTP redirect | 301 / 302 / 307 / 308 | The server tells the browser to go to another URL |
| Login redirect | /login?next=/dashboard | After login, return to the original target |
Common redirect status codes:
| Status | Meaning |
|---|---|
| 301 | Permanent redirect |
| 302 | Temporary redirect, historically common |
| 307 | Temporary redirect while preserving the original method |
| 308 | Permanent redirect while preserving the original method |
When debugging redirects, ask:
Is frontend code navigating, or did the server return a redirect?
Did the browser address bar change?
What status code appears in Network?
Is there a redirect loop?
Did the query string get lost?
Was the login next/redirect parameter preserved?
IP, ports, and localhost
Server programs usually listen on a port:
localhost:3000
127.0.0.1:5173
0.0.0.0:8000
Do not mix up these addresses:
| Address | Meaning |
|---|---|
127.0.0.1 / localhost | This machine itself |
0.0.0.0 | Listen on all network interfaces |
192.168.x.x | Common LAN address |
10.x.x.x | Common private-network address |
| Public IP | Routable on the public internet |
Common ports:
| Port | Common use |
|---|---|
| 80 | HTTP |
| 443 | HTTPS |
| 3000 | Common Next.js / Node dev server |
| 5173 | Common Vite default |
| 5432 | PostgreSQL |
| 3306 | MySQL |
| 6379 | Redis |
| 8000 | Common Python / FastAPI dev server |
Checks:
lsof -i :3000
curl http://localhost:3000
DNS: how domains find machines
DNS translates domain names into IP addresses.
example.com -> some IP address
Common DNS records:
| Record | Meaning |
|---|---|
| A | Domain points to IPv4 |
| AAAA | Domain points to IPv6 |
| CNAME | Domain points to another domain |
| MX | Mail server |
| TXT | Text record, often used for verification |
Checks:
dig example.com
nslookup example.com
DNS has caches. After changing DNS records, the change may not be visible everywhere immediately.
One HTTPS visit: DNS, TCP, TLS, HTTP
When you visit:
https://example.com/dashboard
The chain is roughly:
1. Browser parses the URL
2. DNS resolves example.com to an IP
3. Browser opens a TCP connection to the server
4. TLS handshake negotiates an encrypted connection
5. Browser sends an HTTP request
6. Server returns an HTTP response
7. Browser downloads HTML/CSS/JS/images
8. Browser renders the page and runs JavaScript
Concepts:
| Term | Meaning |
|---|---|
| DNS | Domain-to-IP translation |
| TCP | Reliable transport connection |
| TLS | Encryption layer behind HTTPS |
| certificate | Proof of server identity |
| handshake | Negotiation before establishing a connection or encryption context |
| HTTP | Request/response protocol between browser and server |
Common errors fit into this chain:
| Error | Likely layer |
|---|---|
| DNS_PROBE_FINISHED_NXDOMAIN | DNS did not resolve |
| Connection refused | No service listening on the target IP/port |
| Connection timed out | Network blocked, firewall, or no response |
| SSL certificate error | TLS/certificate problem |
| 404 | HTTP layer: path not found |
| 500 | HTTP layer: server error |
HTTP requests and responses
An HTTP request includes method, path, headers, and body.
GET /api/todos HTTP/1.1
Host: example.com
Accept: application/json
A response includes status code, headers, and body.
HTTP/1.1 200 OK
Content-Type: application/json
{"items":[]}
Common status codes:
| Status | Meaning |
|---|---|
| 200 | OK |
| 201 | Created |
| 301/302 | Redirect |
| 400 | Bad request |
| 401 | Not logged in |
| 403 | Logged in but not allowed |
| 404 | Resource not found |
| 409 | Conflict |
| 500 | Server error |
Proxies, VPNs, tunnels, and CDNs
A request may not go directly from your machine to the target server. It may pass through layers.
| Term | Intuition |
|---|---|
| proxy | Request goes to the proxy first, then to the target |
| VPN | Your machine joins another network |
| SSH tunnel | A local port is connected to a remote port |
| reverse proxy | Receives public requests and forwards them to internal services |
| CDN | Caches static assets closer to users |
SSH tunnel example:
ssh -L 8080:127.0.0.1:3000 server
Rough meaning:
Visit localhost:8080 on your laptop
-> forward through SSH to 127.0.0.1:3000 on server
Reverse proxies are common with Nginx, Caddy, Cloudflare, Vercel, Netlify, and other platforms:
User visits https://example.com
-> proxy layer receives request
-> forwards to internal Node/Python/Go service
Common CDN issues:
Code changed, but the page is still old.
Image or JS asset returns 404.
Different regions see different results.
Cache was not purged.
CORS: why the browser blocks you
CORS is a browser cross-origin security rule.
For example, frontend:
http://localhost:5173
Backend:
http://localhost:3000
The ports differ, so the browser treats them as different origins. If the backend does not allow the frontend origin, the browser may block the request.
Important:
CORS is a browser restriction.
curl working does not mean the browser will work.
Backend logs may show the request arrived, while browser JavaScript is still not allowed to read the result.
Network debugging order
A practical order:
1. Is the URL correct?
2. Where does DNS resolve?
3. Can the target IP and port be reached?
4. Is the service listening on 127.0.0.1 or 0.0.0.0?
5. Is the request coming from local machine, remote server, container, CI, or browser?
6. What status code appears in browser Network?
7. Did the request reach backend logs?
8. Is the backend response correct?
9. Did the frontend handle loading/error/data correctly?
10. Is proxy, VPN, tunnel, CDN, or cache involved?
For AI network debugging, say:
Debug layer by layer; do not guess directly.
First confirm URL, DNS, IP, port, listening address, proxy/VPN/tunnel, HTTP status, browser Network, and server logs.
Distinguish local localhost, remote localhost, and container localhost.
Show actual commands and results before judging root cause.
27. The final map
Frontend engineering can be placed into one map:
Operating system
-> files, processes, permissions, environment variables, PATH, ports, network
URL / DNS / TCP / TLS / HTTP
-> links, domain resolution, connection, encryption, request and response
Proxy / VPN / tunnel / CDN
-> middle layers a request may pass through
HTML / CSS / JavaScript
-> what the browser ultimately understands
React / Vue / Svelte
-> organize UI with components and state
Tailwind / CSS Modules / Sass / component libraries
-> organize styling and visual systems
TypeScript
-> add types to JavaScript and reduce data-shape errors
npm / pnpm / yarn
-> install dependencies and run scripts
Vite / webpack / SWC / Babel
-> dev server, compilation, bundling
Next.js / Nuxt / SvelteKit
-> routing, rendering, server capabilities, build and deployment conventions
API / JSON / fetch
-> exchange data between frontend and backend
Git / lint / typecheck / test / build
-> make changes traceable, verifiable, and shippable
You do not need to master every layer immediately. First learn to ask: which layer is this term in, what problem does it solve, what is it similar to, and where should I look when it breaks?
The final thing to remember:
A page does not appear from nowhere.
It is made of structure, style, behavior, state, data, build tooling, and deployment.
The more clearly you can describe the layers of a problem, the less likely AI is to write random code.
The more you can demand real verification, the less likely the result is only pretending to work.