Project Structure
Vite generates a minimal starting structure. For a real app like ZeroBudget you will add more folders. Getting this right before you build saves time refactoring later.
The Vite starting point
Section titled “The Vite starting point”src/├── assets/├── App.css├── App.jsx├── index.css└── main.jsxThis works for a counter demo. It does not scale to an app with 10+ components, custom hooks, shared data, and a context layer. Before writing any ZeroBudget code, set up a structure that will grow cleanly.
The structure ZeroBudget will use
Section titled “The structure ZeroBudget will use”src/├── components/│ ├── MonthNav/│ │ ├── MonthNav.jsx│ │ └── MonthNav.css│ ├── IncomeSection/│ │ ├── IncomeSection.jsx│ │ └── IncomeSection.css│ ├── CategoryCard/│ │ ├── CategoryCard.jsx│ │ └── CategoryCard.css│ ├── TransactionForm/│ │ ├── TransactionForm.jsx│ │ └── TransactionForm.css│ └── TransactionList/│ ├── TransactionList.jsx│ └── TransactionList.css├── context/│ └── BudgetContext.jsx├── data/│ └── defaults.js├── hooks/│ ├── useBudget.js│ └── useLocalStorage.js├── App.css├── App.jsx├── index.css└── main.jsxWhy this structure
Section titled “Why this structure”components/ holds every UI component. Each component gets its own folder containing the JSX file and its CSS. Co-locating styles with the component that uses them means you never wonder which CSS file controls a given element.
context/ holds the React Context provider and the useBudgetContext hook. Separating context from components keeps the data layer distinct from the rendering layer.
data/ holds static data that does not change at runtime — in ZeroBudget’s case, the default category list. Keeping it separate makes it easy to find and change without touching component logic.
hooks/ holds custom hooks. Any logic you extract out of a component that uses React hooks lives here. useBudget handles all state and actions; useLocalStorage handles persistence.
Naming conventions
Section titled “Naming conventions”React components use PascalCase for both the file name and the function name: CategoryCard.jsx exports function CategoryCard. This is not enforced by JavaScript but is a universal React convention.
Custom hooks use camelCase starting with use: useBudget.js exports function useBudget. The use prefix is required — React’s linter uses it to identify functions that can contain hook calls.
Utility files and data files use camelCase: defaults.js.
Exercise
Section titled “Exercise”- In your Vite project, create the folder structure above inside
src/. - Create an empty
MonthNav.jsxinsidesrc/components/MonthNav/that exports a placeholder component:export default function MonthNav() {return <div>Month Nav</div>;} - Import and render
MonthNavinsideApp.jsx. Confirm it appears in the browser. - Think about ZeroBudget: which component do you expect to be the most complex? Why?
- Vite’s default structure is minimal — add folders before building to avoid later refactoring.
- Each component gets its own folder with a
.jsxfile and a co-located.cssfile. - Separate
context/,data/, andhooks/folders keep different concerns distinct. - Component files and function names use PascalCase. Custom hooks use camelCase starting with
use. - In the next module you will start building components with props.