Getting React Set Up Without Losing Your Mind
I spent about three hours last year debugging a project that wouldn't start because someone had mixed Vite and Create React App configs in the same codebase. The error messages were misleading at best. This happened because I was following an outdated tutorial that didn't mention which bundler it actually targeted. Here is what I learned since then. The modern way to start a React project uses Vite. It is faster than Create React App, which still exists but is essentially in maintenance mode now. Open your terminal and run npm create vite@latest my-app -- --template react. That single command scaffolds everything you need. The --template flag tells Vite to set up React specifically. Without it, you get a generic project that requires manual configuration. Once the project folder is created, navigate into it with cd my-app and run npm install. This downloads all the dependencies listed in package.json. Do not skip this step. I have seen people try to run the dev server without installing packages first, which produces confusing errors about missing modules.
After installation completes, start the development server with npm run dev. Vite will output a local URL, usually http://localhost:5173. Open that in your browser and you should see the default React landing page. The dev server uses hot module replacement, so any changes you save to your files will reflect in the browser almost instantly without a full page reload.
Common Pitfalls During Setup
Node version matters more than most guides admit. React tooling generally requires Node 18 or newer. If you are running an older version, npm install might succeed but the build could fail later with cryptic syntax errors. You can check your version with node --version. If it is below 18, use nvm or fnm to switch to a newer release. Another issue I encountered involved CSS imports. By default, Vite supports CSS modules and regular CSS files. However, if you try to import a CSS file that contains @keyframes or certain vendor-prefixed properties without proper configuration, you might see warnings that do not actually break anything but clutter the console. These warnings are harmless but annoying during development. Setting css: { modules: { localsConvention: 'camelCase' } } in your vite.config.js can clean up some of this noise if you are using CSS modules. Port conflicts are surprisingly common. If port 5173 is already in use, Vite automatically tries 5174, 5175, and so on. This is convenient, but it can cause confusion when you think you are accessing one project but are actually hitting another. I once spent twenty minutes wondering why my changes were not showing up, only to realize the browser was pointed at a different project on a different port. Always verify the URL in the terminal output before assuming something is broken.
Get the Full Details

When to Use Create React App Instead
Vite is the default recommendation, but there are scenarios where Create React App still makes sense. If you are working in an enterprise environment that requires webpack-specific features like code splitting with specific chunk naming conventions, or if you rely on legacy browser polyfills that Vite handles differently, CRA might be more predictable. The trade-off is slower startup and rebuild times. A typical CRA dev server takes around 30 to 60 seconds to start on a modest machine. Vite starts in under 2 seconds regardless of project size. There is also the question of TypeScript support. Both tools handle TypeScript fine, but Vite requires you to add a vite.config.ts file and adjust your tsconfig.json settings slightly. The default Vite template includes these files already, so you do not need to configure anything manually unless you want to customize the build.
Building for Production
When you are ready to deploy, run npm run build. This produces an optimized production bundle in the dist folder. The output includes hashed filenames for cache busting, minified JavaScript, and optimized assets. The build process typically takes 10 to 30 seconds depending on your project size. Do not deploy the node_modules folder. This is a frequent mistake. The dist folder contains everything needed for production. If you are using a hosting platform like Vercel or Netlify, you can point them directly at the dist folder and they will handle the rest. For custom servers, you can serve the dist folder with any static file server. One thing that trips people up is client-side routing. If your application uses React Router and you deploy it to a static host, refreshing any route other than the homepage will return a 404 error. This happens because the server does not know how to handle the request. The fix is to configure your hosting platform to redirect all requests to index.html. On Netlify, you add a _redirects file with the rule /* /index.html 200. On Vercel, this is handled automatically if you use the vercel.json configuration file.
Dependency Management
Keep your package.json clean. Remove dependencies that you are not using. I once inherited a project with over 200 packages, half of which were transitive dependencies pulled in by unused libraries. Running npm audit after installation will flag known security vulnerabilities. Address high and critical severity issues immediately. Low severity warnings can often be ignored unless they affect functionality. Lock files matter. Always commit package-lock.json (or pnpm-lock.yaml if you use pnpm) to version control. This ensures that all developers and CI/CD pipelines install the exact same versions of every dependency. Without a lock file, a minor version update to a transitive dependency could introduce subtle bugs that are difficult to track down.

Environment Variables
Vite uses VITE_ prefixed environment variables. Create a .env.local file in your project root for local development values. Variables defined here are accessible in your React code through import.meta.env.VITE_MY_VARIABLE. Do not use process.env in Vite projects. That is a Create React App pattern that will not work here. I learned this the hard way when I copied a .env setup from an older project and spent an hour debugging why my API base URL was undefined. The variable existed in the .env file but lacked the VITE_ prefix, so Vite ignored it completely. Adding the prefix fixed the issue immediately.
Alternative Package Managers
pnpm is worth considering if you have large monorepos or multiple projects on the same machine. It uses symlinks instead of copying packages, which saves significant disk space and speeds up installation. Replace npm with pnpm in the commands above and everything works the same way. The only difference is that you will have a pnpm-lock.yaml file instead of package-lock.json. Yarn is another option, though its relevance has decreased since pnpm gained popularity. If you prefer Yarn, use yarn create vite my-app --template react instead. The rest of the workflow is identical.