Join our growing community of developers and tech enthusiastsJoin Now
Back to blog

React Fundamentals with Vite for Modern Web Development

Frontend Architecture·December 30, 2025
React Fundamentals with Vite for Modern Web Development
Table of Contents

Modern frontend development moves fast, but understanding often lags behind.

Many developers learn React by copying code that works without fully understanding why it works. This creates a dangerous gap. Applications run correctly, but developers struggle the moment requirements change.

This guide is designed to close that gap.

You’ll learn React fundamentals using Vite, from project setup through real application structure, state management, events, and routing. Every concept is explained with clear reasoning and practical examples that you can apply immediately.

Why React + Vite in 2025?

React is a JavaScript library for building user interfaces using components. Instead of manually manipulating the DOM, React lets you describe what the UI should look like based on state.

Vite is the modern build tool that became the industry standard in 2025, especially after Create React App was officially deprecated. Together they provide lightning-fast development servers, minimal configuration, modern ES module support, and production-ready optimizations.

Vite 7 was released in June 2025 with faster builds and better React 19 support. React 19 stable was released in December 2024 with powerful new features like Server Components.

Creating Your First Project

Create a new React project using Vite:

bash
1npm create vite@latest my-react-app -- --template react
2cd my-react-app
3npm install
4npm run dev


A local development server starts at http://localhost:5173. The browser updates automatically when you change code. You’re ready to write React immediately.

Understanding the Structure

After setup, your project structure looks like this:

bash
1my-react-app/
2├── src/
3│   ├── App.jsx
4│   ├── main.jsx
5│   └── App.css
6├── index.html
7├── package.json
8└── vite.config.js


Two critical files are main.jsx (application entry point) and App.jsx (root component).

The Entry Point

bash
1// src/main.jsx
2import { StrictMode } from "react";
3import { createRoot } from "react-dom/client";
4import App from "./App";
5
6createRoot(document.getElementById("root")).render(
7  <StrictMode>
8    <App />
9  </StrictMode>
10);


React finds the #root element in index.html, renders the App component inside it, and every UI element originates from App. React applications have one root, but unlimited components.

Components

A component is a JavaScript function that returns UI.

bash
1// src/App.jsx
2function App() {
3  return <h1>Hello React</h1>;
4}
5
6export default App;


Components must start with a capital letter, return JSX, and allow you to split UI into small, manageable pieces.

Creating Components

Create a new component:

bash
1// src/components/Welcome.jsx
2function Welcome() {
3  return <h2>Welcome to React Fundamentals</h2>;
4}
5
6export default Welcome;


Use it inside App.jsx:

bash
1import Welcome from "./components/Welcome";
2
3function App() {
4  return (
5    <div>
6      <Welcome />
7    </div>
8  );
9}
10
11export default App;


This demonstrates composition, the foundation of React architecture.

Props

Props allow parent components to pass data to children.

bash
1// src/components/Greeting.jsx
2function Greeting({ name }) {
3  return <p>Hello, {name}</p>;
4}
5
6export default Greeting;


Use props:

bash
1import Greeting from "./components/Greeting";
2
3function App() {
4  return (
5    <div>
6      <Greeting name="Developer" />
7      <Greeting name="Engworks Team" />
8    </div>
9  );
10}


Props flow in one direction (parent to child), are read-only, and make components reusable.

State

State represents data that can change over time.

bash
1// src/components/Counter.jsx
2import { useState } from "react";
3
4function Counter() {
5  const [count, setCount] = useState(0);
6
7  return (
8    <div>
9      <p>Current count: {count}</p>
10      <button onClick={() => setCount(count + 1)}>
11        Increment
12      </button>
13    </div>
14  );
15}
16
17export default Counter;


When setCount is called, React re-renders the component and the UI updates automatically.

Events

Events allow user interaction.

bash
1import { useState } from "react";
2
3function Counter() {
4  const [count, setCount] = useState(0);
5
6  function handleIncrement() {
7    setCount(count + 1);
8  }
9
10  function handleDecrement() {
11    setCount(count - 1);
12  }
13
14  return (
15    <div>
16      <p>Count: {count}</p>
17      <button onClick={handleIncrement}>+</button>
18      <button onClick={handleDecrement}>-</button>
19    </div>
20  );
21}


User performs an action, event handler executes, state updates, and UI re-renders. This is the core React loop.

Conditional Rendering

React can render different UI based on state or props.

bash
1function LoginStatus({ isLoggedIn }) {
2  if (isLoggedIn) {
3    return <p>Welcome back!</p>;
4  }
5  return <p>Please log in.</p>;
6}


This keeps UI logic explicit and predictable.

Rendering Lists

bash
1function TodoList() {
2  const todos = [
3    { id: 1, text: "Learn React" },
4    { id: 2, text: "Build projects" },
5    { id: 3, text: "Master Vite" }
6  ];
7
8  return (
9    <ul>
10      {todos.map(todo => (
11        <li key={todo.id}>{todo.text}</li>
12      ))}
13    </ul>
14  );
15}


Always provide a unique key prop when rendering lists. Keys help React identify which items have changed.

Routing

Single-page applications need navigation. Install React Router:

bash
1npm install react-router-dom
2

Setup routing:

import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
import Home from "./pages/Home";
import About from "./pages/About";


bash
1function App() {
2  return (
3    <BrowserRouter>
4      <nav>
5        <Link to="/">Home</Link> | 
6        <Link to="/about">About</Link>
7      </nav>
8
9      <Routes>
10        <Route path="/" element={<Home />} />
11        <Route path="/about" element={<About />} />
12      </Routes>
13    </BrowserRouter>
14  );
15}

Create page components:

bash
1// src/pages/Home.jsx
2function Home() {
3  return (
4    <div>
5      <h1>Home Page</h1>
6      <p>Welcome to our React application</p>
7    </div>
8  );
9}
10
11export default Home;


Recommended Structure

bash
1src/
2├── components/
3│   ├── Welcome.jsx
4│   ├── Greeting.jsx
5│   └── Counter.jsx
6├── pages/
7│   ├── Home.jsx
8│   └── About.jsx
9├── App.jsx
10└── main.jsx


This provides clear separation of concerns, improved readability, and natural scalability.

Building for Production

When ready for deployment:

bash
1npm run build
2

This creates an optimized production build in the dist folder, minifies code, and optimizes assets.

Preview production build locally:

bash
1npm run preview


Final Thoughts

React is not difficult, but it is precise.

Understanding components, props, state, events, and routing gives you the foundation to build applications with confidence. Vite makes React faster. Understanding makes React powerful.

Master the fundamentals well, and modern frameworks will never intimidate you again.

Building production-ready applications goes beyond code. It requires security, scalability, and expertise. At Egnworks, we build secure web and mobile applications from the ground up. From custom development to penetration testing and secure coding practices, we ensure your applications perform flawlessly and stay protected.

Need a partner who understands both development and security? We’re ready to help.

Written By
Jacob Val

Jacob Val

Front-End Developer who views UI as an engineering problem, not just visual design. Focused on state management, data flow, and component clarity to keep applications stable as complexity grows. Experienced with React, Hooks, and modern CSS approaches to build scalable interfaces.

Share:
Contribute

Share your story.

Join our community of writers and reach thousands of readers with your insights.