Getting a React Project Up and Running
You spend more time configuring your dev environment than you actually write application code. This is just the reality of modern frontend development. I'm going to walk through what actually works without the marketing spin. The standard approach starts with Node.js installed on your machine. Version 18 or later is recommended because older versions have known issues with the Vite build tool, which has largely replaced Create React App as the default initialization method. Run npx create-vite@latest my-app --template react and wait for it to scaffold the project. Then move into the directory, run npm install, and start the dev server with npm run dev. That's it. Your app should be live at localhost:5173 within about thirty seconds on a reasonable machine. The old way used Create React App with webpack baked in. It's still functional but takes roughly forty-five seconds to start the dev server compared to Vite's nearly instant reload. If you're starting anything new in 2025, there's no good reason to use CRA. The ecosystem has moved on and the maintainers have deprecated it.
Here's something most tutorials don't mention. When you initialize a Vite project, it comes with a handful of development dependencies that inflate your node_modules folder significantly. I had a project where the initial bundle size was over two hundred megabytes just for the dev dependencies. The workaround was running npm install with the production flag once and then pruning. That brought it down to under eighty megabytes. The difference matters when you're working on CI pipelines or deploying to containers with limited disk space. Another thing people run into constantly is the TypeScript setup. Vite prompts you during initialization whether you want TypeScript, but if you skip it, adding it later is not straightforward. You need to install @vitejs/plugin-react, configure tsconfig.json with the right compiler options, add type definitions, and update your vite.config.ts to reference the plugin. This process took me about twenty minutes on a fresh project last month, and I did it three times in one week because I kept forgetting to check the TypeScript box initially. The real challenge comes when you're working with server-side rendering or frameworks built on top of React like Next.js or Remix. The basic Vite setup doesn't handle SSR out of the box. You need to either configure it manually, which involves setting up a separate entry point for the server, creating a custom transform for your HTML, and managing dual build targets, or you switch to one of those meta-frameworks. I spent a full day debugging a hydration mismatch once because I was mixing client-only components with server-rendered content and didn't have Suspense boundaries set up correctly. The error message was completely unhelpful. It just said "hydration failed" without any indication of which component was the culprit. The fix was adding console.log statements to each component's render function and narrowing it down to a context provider that was conditionally mounted.
Hot module replacement in Vite is fast, but it has a known limitation with CSS modules. When you update a CSS module file, HMR doesn't always pick up the changes correctly on the first save. You typically need to save the file twice. It's a minor annoyance but it compounds when you're doing rapid UI iteration. The workaround is to restart the dev server occasionally, especially after making changes to your vite.config file or adding new dependencies. For production builds, run npm run build and you'll get an optimized bundle in the dist folder. The build uses Rollup under the hood, which tree-shakes unused code effectively. A typical React app with a few routes and components builds down to around two hundred kilobytes for the JavaScript bundle, depending on what libraries you've included. If your bundle is significantly larger, check whether you're importing entire libraries instead of specific components. Importing lodash as a whole adds over seventy kilobytes when you only need debounce. Using lodash/debounce cuts that to roughly three kilobytes. There are scenarios where this whole setup breaks down entirely. If you need to support Internet Explorer, forget about it. React dropped IE support years ago and Vite is built on modern JavaScript features that won't transpile down reliably. For legacy browser support, you'd need to use something like a Create React App project with Babel polyfills, though even that is a shrinking market. Another limitation is that Vite's dev server doesn't handle large-scale code splitting as gracefully as webpack's dynamic imports. If your application has dozens of routes with heavy components, you'll notice slower navigation between pages during development because Vite transforms modules on demand rather than caching the full chunk graph.
Get the Full Details

When you're ready to deploy, the simplest option is to upload the contents of your dist folder to any static hosting service. Vercel, Netlify, and Cloudflare Pages all support this directly. They'll run the build for you if you connect your Git repository, or you can build locally and push the artifacts. Automatic deployments take about two to three minutes from push to live site for a typical React application.