Skip to content

zac-tily/base-react-project-template

 
 

Repository files navigation

Base Folder Structure

Version 1

Overview

This project follows a feature-based folder structure with shared global resources.

All imports use the @ alias configured in vite.config.ts:

// Use this
import { Button } from '@/components'

// Not this
import { Button } from '../../../components/button'

Source (/src) Structure

src/
├── assets/         # Icons, images, fonts
├── components/     # Reusable UI components (global)
├── config/         # Axios, React Query, test setup
├── constants/      # App-wide constants and config values
├── features/       # Domain-specific implementations
├── hooks/          # Custom React hooks (global)
├── interfaces/     # TypeScript types and interfaces
├── queries/        # React Query data-fetching hooks
├── routes/         # TanStack Router route definitions
├── styles/         # Global CSS and variables
├── utils/          # Helper functions
└── main.tsx        # App entry point

Global Folders

components/

Presentational UI components shared across the app. No business logic — props in, UI out.

components/
├── button/
│   ├── button.tsx
│   └── button.module.css
├── input/
├── heading/
├── card/
├── badge/
├── loader/
├── spinner/
├── table/
├── modal/
├── sidebar/
├── dropdown/
└── index.ts
import { Button, Input, Card } from '@/components'

features/

Self-contained, domain-specific components that contain business logic. See Features below.

import { MetricsSummary, ActivityFeed } from '@/features'

hooks/

Custom hooks that encapsulate reusable logic. Co-locate tests alongside each hook.

hooks/
├── use-form.tsx
├── use-form.test.tsx
├── use-pagination.tsx
├── use-media-query.tsx
├── use-sort-data.tsx
├── use-sidebar-filters.tsx
└── index.ts
import { useForm, usePagination, useMediaQuery } from '@/hooks'

utils/

Pure helper functions with no side effects.

import { formatDate, formatCurrency } from '@/utils'

Features

Features are self-contained units that combine components, hooks, and queries to implement a specific piece of functionality.

Structure

feature-name/
├── feature-name.tsx
├── feature-name.module.css
├── feature-name.test.tsx   # optional
└── index.ts                # optional re-export

Example

features/
├── metrics-summary/
├── activity-feed/
├── recent-transactions/
├── user-table/
├── report-filters/
├── chart-panel/
├── notification-banner/
├── sidebar-nav/
├── date-range-picker/
└── index.ts
// features/metrics-summary/metrics-summary.tsx
import { Card, Heading } from '@/components'
import { useGetAnalytics } from '@/queries'

import styles from './metrics-summary.module.css'

export const MetricsSummary = () => {
  const { data } = useGetAnalytics()

  return (
    <div className={styles.grid}>
      <Card title="Revenue">{data?.revenue}</Card>
      <Card title="Users">{data?.users}</Card>
    </div>
  )
}

queries/

Note: This is not required if tanstack-query (formally known as react-query) is not used.

React Query hooks for data fetching, organised by domain.

queries/
├── users/
├── analytics/
├── reports/
└── index.ts
import { useGetAnalytics, useGetUsers } from '@/queries'

interfaces/

All TypeScript types and interfaces, centralised.

import { UserInterface, ReportInterface } from '@/interfaces'

constants/

App-wide constants — API endpoints, feature flags, config values.

import { API_BASE_URL, FEATURE_FLAGS } from '@/constants'

Feature vs Component — When to Use Which

Use a Feature when... Use a Component when...
It has business logic It's purely presentational
It fetches or transforms data It only receives props
It's domain-specific It's generic and reusable
It composes multiple things It's a simple UI building block

Key rule: Features should not import from other features. If two features share logic, extract it into a hook or utility.


Naming Conventions

Type Convention Example
Components kebab-case.tsx metrics-summary.tsx
Styles kebab-case.module.css metrics-summary.module.css
Tests kebab-case.test.tsx metrics-summary.test.tsx
Hooks use-kebab-case.tsx use-pagination.tsx
Interfaces kebab-case.interface.tsx user.interface.tsx
Utils camelCase.ts formatDate.ts

Key Rules

Always use absolute imports — the @/ prefix for anything from src/.

Export through index.ts — each folder exposes a single public API:

// components/index.ts
export * from './button/button'
export * from './card/card'

Co-locate tests — keep *.test.tsx files next to the code they test.

Use CSS Modules*.module.css for scoped styles, no global class pollution.

Don't cross-import features — features are peers, not parents. Shared logic goes in hooks/ or utils/.

Do not manually edit src/routeTree.gen.ts — this is auto-generated by TanStack Router.

About

Base react project template

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • CSS 46.4%
  • TypeScript 24.0%
  • JavaScript 23.3%
  • HTML 6.3%