FE Dev./React

📚 React + Next.js + TypeScript 폴더 구조 완벽 가이드

웅담이형 2025. 8. 9. 14:07

리액트 로고

App Router / Pages Router / 환경별 구조 차이까지 정리

1. 들어가며

기본적으로 React의 폴더 구조가 어떻게 되는지 정리해본다.

 

리액트는 환경(설정)에 따라 폴더구조가 다르다. 그래서 같은 리액트를 사용한다고 해도 어떻게 초반에 설정을 했느냐에 구조가 다를 수 밖에 없다.

 

필자는 리액트를 시작한지 얼마안되었지만 개인 프로젝트 및 회사에서의 프로젝트를 고려했을 때 아래와 같이 고민을 했었다.

“폴더 구조를 어떻게 잡아야 하지?”

 

예제를 보거나 강의를 몇개를 찾아보면 조금씩 다르기 때문이다. 물론 리액트와 Next.js 버전, TypeScript 따라 달라질 수 있는에 정확하게 어떻게 달라지는지 기록을 해보려고 한다.

 

특히 Next.js를 사용할 때는 App RouterPages Router라는 두 가지 라우팅 방식이 있고, 여기에 TypeScript, 상태 관리, API 연동, 스타일 전략까지 더해지면 폴더 구조가 제각각 달라진다.

 

2. React + TypeScript 기본 구조

(Vite, CRA 등 Next.js 없이 단독 React 프로젝트)

my-react-app/
├─ public/                  # 정적 파일
├─ src/
│  ├─ app/                  # 엔트리와 전역 설정
│  ├─ pages/                # react-router 페이지
│  ├─ features/             # 도메인 단위(회원, 글, 결제 등)
│  ├─ components/           # 공용 UI
│  ├─ hooks/                 # 전역 커스텀 훅
│  ├─ store/                # Zustand, Redux 전역 상태
│  ├─ services/             # API 클라이언트, Firebase/Supabase 연동
│  ├─ lib/                   # 유틸, 헬퍼 함수
│  ├─ styles/               # 전역 스타일
│  ├─ types/                # 전역 타입 정의
│  └─ config/               # 환경 설정, 상수
└─ vite.config.ts

 

💡 포인트

 

  • pages → URL 매핑되는 화면
  • features → 관련 로직, API, UI, 타입을 한 기능 단위로 모음
  • services → 외부 서비스 연동

 

3. Next.js + TypeScript (App Router 기준)

Next.js 13+에서 기본 라우팅 방식이다.

my-next-app/
├─ public/
├─ app/
│  ├─ layout.tsx              # 루트 레이아웃
│  ├─ page.tsx                # /
│  ├─ dashboard/
│  │  ├─ layout.tsx
│  │  ├─ page.tsx
│  │  └─ settings/page.tsx
│  ├─ api/                    # Route Handlers (간단 API)
│  │  └─ auth/route.ts
│  └─ actions/                # 서버 액션
├─ components/                # 공용 UI
├─ features/                  # 도메인 단위 모듈
├─ lib/                        # DB, 인증, 유틸
├─ providers/                 # 전역 Provider
├─ styles/                    # 전역 CSS, Tailwind
├─ types/
└─ config/

 

 

💡 App Router 특징

  • 페이지·레이아웃이 폴더 구조로 매핑
  • 서버 컴포넌트 기본, "use client"로 클라이언트 전환
  • 서버 액션(Server Action)을 페이지 근처에 둘 수 있음

4. Next.js + TypeScript (Pages Router 기준)

Next.js 12 또는 App Router를 쓰지 않는 경우

my-next-pages-app/
├─ public/
├─ pages/
│  ├─ _app.tsx               # 전역 레이아웃/Provider
│  ├─ _document.tsx          # HTML 문서 커스터마이즈
│  ├─ index.tsx              # /
│  ├─ about.tsx              # /about
│  ├─ blog/[slug].tsx        # 동적 라우트
│  └─ api/                   # API 라우트
│     └─ auth.ts
├─ components/               # 공용 UI
├─ features/                 # 도메인 단위 모듈
├─ lib/                       # 유틸, API 클라이언트
├─ hooks/
├─ styles/
├─ types/
└─ config/

 

 

💡 Pages Router 특징

  • pages/ 폴더 안에 라우트 정의
  • getStaticProps, getServerSideProps 등 페이지에서 직접 데이터 패칭
  • API 라우트는 pages/api/ 안에 위치

5.  App Router vs Pages Router 비교

구분 App Router Pages Router
라우트 정의 app/ 폴더 구조 기반 pages/ 폴더 파일명 기반
전역 레이아웃 app/layout.tsx pages/_app.tsx
데이터 패칭 서버 컴포넌ㅌ, 서버 액션, fetch API getStaticProps, getServerSideProps
API 라우트  app/api/**/route.ts pages/api/**
기본 컴포넌트 서버 컴포넌트 클라이언트 컴포넌트

 

 

6. 왜 환경(설정)에 따라 폴더 구조가 달라질까? 

 

  • 라우팅 방식
    • App Router는 서버 액션과 서버 컴포넌트 중심 → 도메인별 로직 근접 배치
    • Pages Router는 페이지 중심 → 페이지는 얇게, 기능 폴더에서 로직 처리
  • 배포 대상
    • Serverless/Edge: 환경별 DB, 캐시 유틸 분리 필요
    • Node 서버: 서버 전용 코드와 클라이언트 코드를 명확히 구분
  • 데이터 패칭 전략
    • 클라이언트 패칭(SWR, React Query) vs SSR/SSG 여부에 따라 fetch 로직 위치가 달라짐
  • 인증/세션 방식
    • NextAuth, JWT, OAuth에 따라 API 라우트나 미들웨어가 추가됨
  • 스타일 방식
    • Tailwind, CSS-in-JS, CSS Modules 중 무엇을 쓰느냐에 따라 styles/ 구조가 달라짐
  • 모노레포 여부
    • Turborepo/PNPM 환경이면 공용 패키지를 packages/로 분리

 

7. TypeScript 설정 팁 (경로 별칭)

// tsconfig.json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@components/*": ["./src/components/*"],
      "@features/*": ["./src/features/*"],
      "@lib/*": ["./src/lib/*"]
    }
  }
}

 

 

8. 마무리

프로젝트의 폴더 구조에 정답은 없는거 같다.
다만, 환경(라우팅 방식, 배포, 데이터 패칭, 인증 방식 등)에 따라 응집도와 확장성을 고려한 구조를 잡는 것이 중요하다고 한다.

핵심 원칙: 페이지는 얇게, 기능은 두껍게!
그리고 관련 파일은 가깝게(co-location) 두기.

 

 

 

반응형
LIST