Build a Startup Cheatsheet
Frontend (React, Next.js, Tailwind)
Use this Build a Startup reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
What the Frontend Is
The frontend is everything the user sees and interacts with in the browser. In a modern web startup, it is almost always a JavaScript framework that renders UI components, manages state, and communicates with a backend API.
The dominant choices: React as the UI library, Next.js as the React framework, and Tailwind CSS for styling.
React
React is a JavaScript library for building user interfaces with reusable components. It does not handle routing, server rendering, or data fetching — those are framework concerns.
Core ideas:
- Everything is a component — a function that returns JSX (HTML-like syntax in JavaScript)
- State is data that, when changed, causes the component to re-render
- Props are values passed from parent to child components
- Side effects (data fetching, subscriptions) go in
useEffect
function Counter() { const [count, setCount] = React.useState(0); return ( <button onClick={() => setCount(count + 1)}> Clicked {count} times </button> ); }
React itself is not opinionated about routing or server rendering. That is why most teams use a framework on top of it.
Next.js
Next.js is the most popular React framework. It adds:
- File-based routing — a file at
app/dashboard/page.tsxbecomes the/dashboardroute - Server-side rendering — pages can be rendered on the server for SEO and performance
- API routes — backend endpoints live in
app/api/*/route.ts, eliminating a separate server for many use cases - Image optimization, font loading, and other performance defaults
App Router vs. Pages Router
Next.js has two routing systems. The App Router (current) is the right choice for new projects. It uses React Server Components by default, meaning components render on the server unless you add "use client" at the top.
app/ layout.tsx // shared layout (nav, footer) page.tsx // homepage (/) dashboard/ page.tsx // /dashboard layout.tsx // layout wrapping all /dashboard/* pages api/ users/ route.ts // GET/POST /api/users
Server Components vs. Client Components
| Server Component (default) | Client Component ("use client") | |
|---|---|---|
| Runs on | Server only | Browser (and server during SSR) |
| Can fetch data | Yes, directly | Via useEffect or SWR/React Query |
Can use useState | No | Yes |
| Can use browser APIs | No | Yes |
| Included in JS bundle | No | Yes |
Use Server Components for data fetching and layouts. Use Client Components only when you need interactivity, browser APIs, or local state.
Data fetching in the App Router
// Server Component — no useEffect needed export default async function UserList() { const users = await db.select().from(usersTable); return <ul>{users.map(u => <li key={u.id}>{u.name}</li>)}</ul>; }
Tailwind CSS
Tailwind is a utility-first CSS framework. Instead of writing custom CSS classes, you apply small utility classes directly in your JSX.
<button className="bg-black text-white px-4 py-2 rounded-lg font-medium hover:bg-gray-800">
Get started
</button>Why Tailwind for startups:
- No context switching between HTML and CSS files
- Consistent spacing and color system out of the box
- Unused styles are automatically purged (small bundles)
- Co-located with the component, easy to scan and change
- Works perfectly with component libraries like shadcn/ui
Tailwind v4
Tailwind v4 (the current major version) uses CSS-based configuration instead of a tailwind.config.js file. Theme tokens are defined in your global CSS file:
@theme {
--color-brand: #d4af37;
--font-sans: "Inter", sans-serif;
}These become utility classes automatically: bg-brand, text-brand, font-sans.
Component Libraries
Building every UI component from scratch is slow. These libraries give you accessible, styled components you can customize:
| Library | Style | Install complexity | Best for |
|---|---|---|---|
| shadcn/ui | Tailwind-based, copy-paste | Low | Most new projects; full control over code |
| Radix UI | Unstyled, accessible primitives | Low | Custom design systems |
| Mantine | Pre-styled, feature-rich | Low | Rapid prototyping with less custom CSS |
| Material UI | Google Material Design | Medium | Enterprise apps; very polished |
| Chakra UI | Accessible, composable | Low | Quick builds with decent defaults |
Recommendation: Start with shadcn/ui. It copies components into your repo (you own the code), built on Radix UI for accessibility, and styled with Tailwind. You can customize anything.
npx shadcn@latest init npx shadcn@latest add button card input dialog
State Management
For most startups, React's built-in state (useState, useContext) is sufficient. Add a library only when you have a specific problem.
| Need | Solution |
|---|---|
| Local UI state | useState |
| Shared state across a few components | useContext + useState |
| Server state (caching, refetching) | TanStack Query or SWR |
| Complex global state | Zustand (simple) or Jotai (atomic) |
| Large app with complex interactions | Redux Toolkit (only if you need it) |
Avoid Redux for new projects unless your state logic is genuinely complex and the team knows it well.
Forms
Forms are surprisingly tricky in React. Use a library rather than managing controlled inputs by hand.
- React Hook Form — minimal re-renders, great performance, works with Zod for validation
- Zod — TypeScript-first schema validation; validates form data, API inputs, environment variables
import { z } from "zod"; const schema = z.object({ email: z.string().email(), password: z.string().min(8), });
Performance Defaults to Follow
- Images: use
<Image>fromnext/image— it resizes, optimizes, and lazy-loads automatically - Fonts: use
next/font— loads fonts from Google Fonts at build time, zero layout shift - Code splitting: Next.js does this automatically per route
- Bundle analysis: run
ANALYZE=true npm run build(with@next/bundle-analyzer) to see what is large
Tooling
| Tool | Purpose |
|---|---|
| TypeScript | Type safety — use it from day one |
| ESLint | Code quality linting — included in Next.js by default |
| Prettier | Code formatting |
| Cursor / v0.dev | AI code generation for boilerplate |
npx create-next-app@latest my-app --typescript --tailwind --eslint --app
This one command sets up Next.js, TypeScript, Tailwind CSS, and ESLint together.