Skip to content

Web Apps from Natural Language ​

You have an idea for a web application. A dashboard for tracking freelance projects. A searchable recipe collection. A tool that converts a CSV into a formatted report. In a traditional workflow, you would spend the first hour setting up a project: framework, build tool, routing, state management, CSS pipeline. Before you wrote a single line of application logic, you would have written a hundred lines of boilerplate.

In a vibe coding workflow, you describe the application in a paragraph. The agent scaffolds the project, builds the first page, and has something running in the browser before you finish your coffee. This lesson walks through that process end to end, with real prompts and real outcomes. The example is a project dashboard, but the pattern applies to any web application you want to build.

What you'll learn

  • Scaffolding a web project is one prompt: describe the stack, the framework, and the first page
  • Each subsequent page or feature is another prompt, building on the work the agent already did
  • The agent handles boilerplate: routing, state management, build configuration, CSS setup
  • Your job is describing what the user should see and do, and reviewing the output to make sure it matches

The problem: from idea to running app without writing boilerplate ​

You want a web app. You know what it should do. You do not want to spend two hours configuring Vite, setting up React Router, choosing a CSS framework, wiring up state management, and creating a folder structure before you write the first line of actual application code.

Traditional development treats boilerplate as a necessary evil. Vibe coding treats it as something the agent handles while you focus on the application. The skill is not knowing which npm packages to install. The skill is describing the outcome clearly enough that the agent produces a working scaffold on the first try.

Options & when to use each ​

FrameworkWhat it is good forWhat it costs youWhen to pick it
React + ViteMost LLM training data, widest ecosystem, largest community for troubleshootingHeavier than necessary for simple pages; JSX can be verboseAny interactive application; when you want the agent to have the most reference material to draw from
Next.jsServer-side rendering, file-based routing, built-in API routesMore opinionated; agent needs to understand the Next.js conventions to produce consistent outputApps that need SEO, server-rendered pages, or built-in backend endpoints
Vue + ViteSimpler learning curve, single-file components, good LLM supportSmaller ecosystem than React; fewer community examples in training dataWhen you prefer Vue or when the app is primarily forms and data display
Plain HTML/CSS/JSZero build step, runs anywhere, smallest possible outputNo component model; gets unwieldy past a few pagesStatic sites, prototypes, anything that does not need a framework

Build it: a project dashboard from one paragraph ​

Step 1: Scaffold the project ​

Open Claude Code in an empty directory and describe what you want:

> Create a React project with Vite and TypeScript. It is a freelance project
  dashboard. Users see a list of their active projects with client name,
  deadline, budget, and status. They can add new projects, edit existing ones,
  and mark projects as complete. Use Tailwind CSS for styling. Use React Router
  for navigation: a home page listing projects, a detail page for each project,
  and a form page for adding/editing. Use localStorage for persistence so data
  survives page reloads. Do not add a backend. Make it look professional: clean,
  modern, good use of whitespace and color.

The agent will:

  1. Run npm create vite@latest with the React TypeScript template
  2. Install dependencies: react-router-dom, tailwindcss, @tailwindcss/vite
  3. Configure Tailwind and the Vite plugin
  4. Create the folder structure: /src/components/, /src/pages/, /src/hooks/
  5. Build a ProjectList component with mock data
  6. Set up React Router with routes for /, /projects/:id, /projects/new, /projects/:id/edit
  7. Add basic Tailwind styling that looks clean out of the box

Review the output. The agent will show you the files it created. Look for: routing setup in App.tsx, the project list component, and the Tailwind configuration. If anything is missing, describe it: "Add a navigation bar with links to Home and New Project." The agent adds it.

Step 2: Build the landing page ​

The scaffold has a basic project list. Now make it real:

> Replace the mock project data with a custom hook that reads and writes to
  localStorage. The hook should expose: projects array, addProject(),
  updateProject(), deleteProject(), toggleComplete(). Use TypeScript types for
  the Project interface. The landing page should show a card for each project
  with: client name (bold), deadline (formatted date), budget (formatted as
  currency), status badge (colored by status: active=green, completed=blue,
  overdue=red). Add a search bar that filters projects by client name. Add a
  sort dropdown: sort by deadline, budget, or status. Use Tailwind utility
  classes for all styling.

The agent builds:

  • A useProjects hook in /src/hooks/useProjects.ts with full CRUD over localStorage
  • A Project TypeScript interface
  • A ProjectCard component with status badges
  • A search bar with filtered results
  • A sort dropdown

Step 3: Add the detail page ​

> Build the project detail page at /projects/:id. It shows: full project
  information (client, deadline, budget, status, description), a button to
  edit the project (links to /projects/:id/edit), a button to mark as complete
  (calls toggleComplete), a delete button with a confirmation dialog, and a
  back button to the project list. Handle the case where the project ID does
  not exist: show a "Project not found" message with a link back to the list.

Step 4: Add the form page ​

> Build the add/edit project form at /projects/new and /projects/:id/edit.
  Fields: client name (text), project description (textarea), deadline (date
  picker), budget (number with dollar sign), status (dropdown: active, on hold,
  completed). Validate: client name required, budget must be positive number,
  deadline must be in the future. Show validation errors inline below each
  field. On submit, save to localStorage and redirect to the project detail
  page. If editing, pre-fill the form with existing project data.

Step 5: Polish and deploy ​

> Audit the app for visual consistency. All cards should have the same padding
  and border radius. All buttons should use the same style (primary blue,
  secondary gray, danger red). The nav bar should be fixed at the top. Add a
  footer with a link to the GitHub repo. The app should be fully responsive:
  project cards in a single column on mobile, two columns on tablet, three on
  desktop. Build for production and tell me how to deploy to a static host.

The agent runs npm run build, produces a dist/ folder, and tells you to deploy it to Netlify, Vercel, or GitHub Pages.

What goes wrong ​

MistakeHow you notice itThe fix
Describing too much in one promptThe agent produces a scaffold that has routing, state, styling, and data management but none of them work correctly because it tried to do everything at onceBreak it into steps. Scaffold first. Then data. Then pages one at a time. Each step builds on working output from the previous step
Not specifying the CSS frameworkThe agent picks a default (often plain CSS or a framework you did not want). Styling is inconsistent or hard to modifyName the CSS framework in your first prompt. "Use Tailwind CSS" or "Use vanilla CSS modules"
Letting the agent invent a component architectureComponents become deeply nested, props drilling gets out of hand, and editing one component breaks three othersSpecify the component tree early: "Use these components: App > Layout (nav + footer) > Page components. Each page component is self-contained."
Not handling empty and error statesThe app works perfectly with data but shows a blank page or crashes when the project list is empty or an ID is invalidExplicitly ask for empty states and error states in every prompt. "Handle the case where there are no projects." "Handle invalid project IDs."
Building without testing in the browserThe agent says it is done. The code looks right. You deploy it and the first user finds a broken buttonRun npm run dev after every major step. Click through the app. Confirm each feature works before moving to the next prompt

Confirm it worked ​

Run npm run dev and open the browser. You should see a project dashboard with a search bar, sort dropdown, and a grid of project cards. Click "New Project" and fill out the form. Submit it. The new project appears in the list. Click it to see the detail page. Edit it. Mark it complete. Delete it. Refresh the page: the data persists in localStorage.

Then open Claude Code again and ask it to add a new feature: "Add a project statistics bar at the top of the dashboard showing total projects, active projects, total budget across all projects, and number of overdue projects." The agent should add this feature without breaking existing functionality. If it does, you have a working vibe-coded web app that can survive feature additions. If it breaks something, re-read the prompting patterns from Day 1: your system prompt or context management needs adjustment.

Next: Working with APIs & External Services -- connect your app to real external services the same way you built this one.