Next.js 16 프로젝트, AI와 함께 아키텍처 결정하는 법

Next.js 16 프로젝트, AI와 함께 아키텍처 결정하는 법

day 1에 day 90의 기준을 심는 것—그 판단을 AI와 함께 내리려면 질문 구조 자체가 달라야 한다

Next.js 16 React Server Components AI 디버깅 아키텍처 결정 프론트엔드 워크플로우 Biome SSR 설계 프롬프트 엔지니어링
광고

'왜 이 결정인가'를 먼저 쓰는 사람들

Next.js 스타터를 처음 세팅할 때 우리는 보통 빠른 선택을 한다. create-next-app 실행, ESLint + Prettier 붙이기, 상태 관리 라이브러리 추가. 그런데 6개월 후 돌아보면 꼭 한두 가지가 조용히 무너져 있다. HTTP 클라이언트가 Server Component로 옮기면서 동작을 멈췄거나, Redux 스토어가 SSR 환경에서 요청 간 인스턴스를 공유하거나, 환경 변수가 부트 타임이 아닌 런타임에 실패하거나.

dev.to에 공개된 Next.js 16 스타터 재구축 사례는 바로 그 지점을 정면으로 겨냥한다. 저자의 원칙은 단 하나다. "day 1의 기본값은 day 90에도 내가 선택했을 것이어야 한다." 이 원칙 하나가 모든 아키텍처 결정의 준거가 된다.

Next.js 16이 바꾼 것들: 아는 것과 모르는 것의 간극

이 스타터가 흥미로운 이유는 단순히 '좋은 구성' 목록을 나열하는 게 아니라, 각 결정이 어떤 함정을 피하기 위한 것인지를 명시한다는 점이다.

가장 먼저 눈에 띄는 변화는 middleware.ts의 소멸이다. Next.js 16에서는 proxy.ts로 파일명, 내보내기 함수명, matcher 문법이 모두 바뀌었다. 이전 프로젝트에서 그대로 복사해 오면 빌드가 조용히 실패한다—에러 없이. 이런 종류의 무음 실패(silent failure)가 프로덕션 디버깅을 얼마나 고통스럽게 만드는지는 경험해본 사람이라면 안다.

React Compiler도 기본값으로 활성화됐다. 인라인 콜백의 참조 동일성에 의존하던 메모이제이션 패턴들이 다르게 동작할 수 있다. 누군가 useEffect 탓을 하기 전에 알아야 할 사실이다.

결정 하나하나에 이유가 있어야 한다

스타터의 핵심 설계 선택들을 보면 패턴이 보인다. 각 결정은 단독으로 서 있지 않고, 회피하려는 구체적인 문제와 쌍을 이룬다.

Biome로 ESLint + Prettier 대체: 설정 파일 4개, 버전 충돌, 느린 프리커밋 훅. 하나의 바이너리로 린트·포맷·임포트 정렬을 단일 패스로 처리한다. CI 품질 게이트가 25~40초에서 4~6초로 줄었다는 건 단순한 속도 문제가 아니다—훅을 우회하려는 유혹이 사라진다는 뜻이다.

Zod 기반 환경 변수 검증: process.env.NEXT_PUBLIC_FOO의 타입은 string | undefined다. non-null assertion으로 거짓말하거나, 런타임 체크를 코드베이스 전반에 흩뿌리거나. 이 스타터는 모듈 로드 시점에 단 한 곳에서 검증하고, 유효하지 않으면 부트 타임에 즉시 실패한다.

Per-request Redux store: SSR 환경에서 글로벌 스토어 인스턴스를 공유하면 요청 A의 상태가 요청 B에 흘러들 수 있다. 요청별 스토어를 생성하고 Server Components에서 하이드레이션하는 구조는 이 문제의 구조적 해결이다.

use client 회귀 감지 sentinel: next/headers가 클라이언트 번들에 유출되면 빌드가 실패하도록 강제한다. 재현하기 어려운 버그를 런타임이 아닌 빌드 타임에 잡는다.

AI와 함께 아키텍처를 결정할 때 달라져야 하는 것

여기서 두 번째 이야기가 합류한다. AI 디버깅 워크플로우를 다룬 dev.to 아티클에서 저자는 웹훅 이벤트가 조건부로 조용히 사라지는 버그를 AI에게 "왜 안 돼요?"라고 물었다가 2시간을 잃었다. AI는 존재하지 않는 레이스 컨디션을 자신 있게 설명했다.

반전은 프롬프트 구조를 바꾸면서 왔다. **"이 함수가 해야 하는 일

출처

더 많은 AI 트렌드를 Seedora 앱에서 확인하세요