이 글은 Next.js의 버전 12 까지의 내용인 Page Router를 기준으로 작성되었습니다.
흔히 말하는 개발자의 단점 중 하나는 끊임없이 공부를 해야한다는거죠. 기술은 계속 발전하고 개발자는 그 흐름을 따라가야합니다. 특히 웹 프론드엔드 생태계는 더더욱 그 흐름이 빠르기에 이러한 기술 트렌드를 따라가려는 적극성도 프론트엔드 개발자의 중요한 덕목 중 하나가 되었습니다.
Next.js는 현대 웹 프론트엔드의 트렌드를 가장 주도하는 프레임워크 중 하나입니다. 현재 회사의 채용공고를 봐도 Next.js에 대한 역량을 요구가 늘어나는 것이 보이고 npm trends에서도 다양한 웹 프레임워크 사이 next.js의 인기를 확인할 수 있습니다.
다양한 기능을 가지고 있기에 Next.js를 효율적으로 사용하기 위해서는 배워야할 개념도 많습니다. 몇몇 개발자는 Next.js의 복잡성에 피로감을 느끼기도 합니다. 저 또한 그랬었고요.
Next.js가 정말 필요한가요? 그 물음에 대한 답은 제가 Next.js를 사용해보고 Next.js의 의의에 대해 자세히 알게되었을 때 꽤 명확해졌습니다.
Next.js하면 SSR이지!
Next.js라는 프레임워크를 들어보거나 접하시는 분들이라면 가장 먼저 생각나는 단어가 무엇인가요? 아마 SSR(server-side-rendering)일 것입니다. Next.js에 익숙하지 않으신 분들은 Next.js를 사용하는 이유가 자신의 프로젝트에 SSR의 이점을 쉽게 가져오기 위함이라고 생각하실 텐데요.
요즘 많은 개발자들은 “Next.js는 단순히 SSR을 위한 프레임워크가 아니다”라고 말합니다. 이는 맞는 말입니다. Next.js는 이제 SSR을 넘어 웹 어플리케이션을 개발을 위한 다양한 기능을 제공하고 있죠. 이에 대해서는 뒤에 따로 후술할 정보이기도 합니다.
하지만 Next.js에서 SSR을 강조하는 것은 여전히 의미가 있습니다. SSR은 Next.js의 근본이자 시작점이기 때문입니다. Next.js가 2016년 처음 출시되었을 때, 그 핵심 가치는 “제로 설정으로 React 애플리케이션의 서버 사이드 렌더링을 가능하게 하는 것”이었습니다.
현재 next.js의 첫 버전 출시에 대한 정보를 담은 글은 찾기 힘들지만 next.js의 블로그 중 버전 7 출시에 대한 이 포스트에서 과거의 next.js 공식 홈페이지가 next.js를 어떻게 설명하는 지를 확인할 수 있습니다.

이 근본적인 철학은 Next.js가 발전하면서도 계속 유지되고 있습니다.
그럼 Next.js의 SSR은 무엇인가요?
자 먼저 웹을 화면에 보여주는 방식에 대한 중요한 개념 2가지를 짚고 넘어 갑시다.
1. SPA와 MPA
- SPA(Single Page Application): 한개의 HTML 페이지에서 Javascript를 이용하여 동적으로 화면을 변경하는 방식이며, 대표적으로
React,Vue,Svelte등이 SPA 프레임워크가 존재합니다. - MPA(Multi Page Application): 요청할 때마다 새로운 HTML을 받아오는 전통적인 웹 어플리케이션 방식이며, 과거의
PHP,JSP, 현대의Astro와 같은 서버 렌더링 기반의 웹 프레임워크가 존재합니다.
2. CSR과 SSR
- CSR(Client Side Rendering): 클라이언트(브라우저)에서 Javascript을 사용하여 동적으로 DOM을 생성하는 방식
- SSR(Server Side Rendering): 요청이 들어올 때마다 서버에서 HTML을 완성하여 클라이언트로 전달하는 방식
개념에 대한 오해
여기서 흔히 오해하고 있는 부분은 “SPA = CSR, MPA = SSR” 이라는 것입니다.
물론 SPA는 보통 CSR을 사용하고, MPA는 SSR을 사용하는 것이 일반적입니다. 하지만, SSR을 SPA에 적용하는 경우도 있고, CSR을 MPA에 사용하는 경우도 있습니다.
예를 들면, React를 사용하더라도 Routing 관련된 써드파티 라이브러리(예: React Router)를 사용하지 않고, <a> 태그를 이용해 페이지 이동을 시키는 경우가 있습니다.
<a href="/about">About 페이지 이동</a>
이 경우, 브라우저는 완전히 새로운 HTML을 요청하기 때문에 페이지 전환 시 전체 리소스를 다시 불러오게 됩니다. 즉, React를 사용하고 있다고 하더라도 실제로는 MPA처럼 동작하게 되는 것이죠.
반면, React Router 같은 클라이언트 사이드 라우팅 라이브러리를 사용하면 컴포넌트를 활용하여 페이지 이동이 가능합니다.
import { Link } from "react-router-dom";
<Link to="/about">About 페이지 이동</Link>;
이렇게 하면 새로운 HTML을 요청하는 것이 아니라, 클라이언트 측에서 JavaScript가 동작하여 페이지를 전환하게 됩니다. 즉, SPA의 CSR 방식이 유지되는 것입니다.
이처럼 MPA에서도 CSR을 사용할 수 있으며, SPA에서도 SSR을 적용할 수 있습니다.
이러한 하이브리드 형태의 렌더링 방식이 곧 Next.js의 렌더링 전략의 기반이 됩니다.
Next.js의 SSR
기존 React SPA는 클라이언트에서 JavaScript가 실행된 후 데이터를 가져와 화면을 구성하는 CSR 방식을 사용합니다. 하지만 이 방식은 js 번들 파일이 클수록 초기 로딩이 느리고, 검색 엔진이 내용을 크롤링하기 어려운 문제가 있었습니다.
Next.js는 이 문제를 해결하기 위해 SSR을 도입하여, 요청이 들어올 때마다 서버에서 HTML을 생성하여 클라이언트로 전달합니다. 이를 통해
- 초기 페이지 로딩 속도 개선 – 브라우저가 별도의 js 로드 없이 즉시 완전한 HTML을 보여줄 수 있습니다.
- SEO 향상 – 검색 엔진이 HTML을 바로 인식할 수 있습니다.
- 유연한 렌더링 방식 – 필요에 따라 페이지 단위로
getServerSideProps,getStaticProps등을 선택 가능합니다.
와 같은 장점을 얻을 수 있습니다.
다음은 next.js의 SSR을 통한 웹 렌더링이 어떻게 진행되는 지 나타낸 그림입니다.

Next.js는 기존 CSR 방식만을 구사하는 SPA에 대해서 SSR을 통해 초기 HTML 로드를 서버에서 부터 빠르게 가져와 웹 성능과 SEO와 같은 사용자 경험을 향상시키는 렌더링 방식을 채택하였습니다.
Next.js의 SSR은 매 요청마다 서버로부터 새로운 HTML을 생성해야했던 기존의 MPA 기반 SSR과도 다릅니다. Next.js에서 SSR을 수행한다고 해서 기존 React SPA의 CSR 방식을 완전히 대체하는 것이 아닙니다.
Next.js의 SSR을 구현하는 함수들은 모두 초기에 어떻게 HTML을 가져올지만 관여하기 때문입니다. SSR로 제공된 HTML이 브라우저에 도착한 후에는 React의 SPA 메커니즘과 동일하게 동작하며, 이후 클라이언트에서 Ajax 요청을 통해 CSR 방식처럼 동적으로 데이터를 가져올 뿐만 아니라, 이를 활용해 새로운 DOM을 생성하고 업데이트할 수도 있습니다.
Next.js의 SSR 방식
위 그림을 보면 Next.js는 SSR을 수행할 때 정적 렌더링(Static Rendering)과 동적 렌더링(Dynamic Rendering) 2가지 방식을 지원하는 것을 확인할 수 있습니다.
이 두가지 방식에 대해 간단히 설명을 드리겠습니다.
1. Static Rendering/SSG(static site generation) (정적 렌더링)
- Next.js에서는 기본적으로 Static Rendering(정적 렌더링)을 사용합니다
- 빌드 타임에 HTML을 미리 생성하여 저장하고, 요청이 들어오면 즉시 제공하는 방식입니다
- HTML이 미리 생성되므로 배포 후에는 별도의 서버가 필요하지 않으며, CDN을 통해 빠르게 전달됩니다.
- Next.js에서는 getStaticProps 또는 ISR(Incremental Static Regeneration)을 사용하여 정적 렌더링을 수행할 수 있습니다.
✅ 장점:
- 요청 시 서버 부하가 없습니다. (CDN 활용 가능)
- 빠른 페이지 로딩 속도를 보유합니다.
- SEO 최적화
❌ 단점:
- 실시간 데이터 반영이 어렵습니다.
2. Dynamic Rendering/SSR(server-side rendering) (동적 렌더링)
- 동적 렌더링은 요청이 들어올 때마다 런타임 서버에서 HTML을 생성하여 클라이언트에 전달하는 방식입니다.
- Next.js에서는 getServerSideProps를 활용하여 SSR을 수행할 수 있습니다.
✅ 장점:
- 최신 데이터를 즉시 반영 가능합니다.
- 사용자별 맞춤 데이터를 제공할 수 있습니다.
❌ 단점:
- 요청마다 서버가 HTML을 생성해야 하므로 성능 부담이 있습니다.
- 서버에서 데이터를 가져오는 과정이 길어질 경우, 최종적으로 클라이언트가 HTML을 받기까지의 응답 시간이 지연될 수 있습니다.
결국 Next.js의 SSR에서 중요한 것은 서버에서 HTML을 언제 생성하는가입니다. 서버에서 HTML을 빌드 시점(Build Time)에 생성할 것인지, 요청 시점(Request Time)에 생성할 것인지를 잘 파악하여 결정하는 것이 중요하며, 이를 적절하게 선택하는 개발자의 역량이 웹 성능과 사용자 경험을 최적화하는 핵심 요소가 됩니다.
Next.js는 리액트 프레임워크다.
The React Framework for the Web
공식문서에 따르면 next.js는 웹을 만들기 위한 React 프레임워크라고 합니다. 중요한 키워드를 확인할 수 있는데요. react 프레임워크입니다.
개발을 하다보면 필연적으로 라이브러리/프레임워크와 같은 외부 도구를 사용하게 됩니다. 이러한 외부 도구를 사용하는 이유는 우리는 비즈니스 로직을 개발하거나 사용자 경험에 대해서 고민하는 등 각자가 원하는 구현에 집중하기 위해 도움을 받을 수 있기 때문입니다. Next.js를 사용함으로서 따로 구체적인 코드를 직접 작성하지 않고 리액트 어플리케이션을 더욱 효울적으로 개발 할 수 있습니다.
Next.js에서 제공하는 대표적인 기능들은 다음과 같습니다.
- Rendering
- SSR/SSG/CSR등 여러 렌더링 전략을 유연하게 사용할 수 있게 도와줍니다.
- Routing
- 파일 기반의 라우팅을 제공하여 별도의 써드파티 라우터를 설치할 필요가 없습니다.
- Data fetching
getStaticProps,getServerSideProps,getStaticPaths와 같은 함수들을 통해 서버로부터 Runtime(Request time) 또는 Build time에서 데이터를 받아 올 수 있습니다.
- API routes
- 별도의 서버를 배포하지 않고 백엔드 함수를 작성하여 클라이언트와 통신할 수 있습니다.
pages/api/에 파일을 생성하면 해당 경로가 자동으로 API 엔드포인트가 됩니다.
- Optimizing
- 자동 코드 분할을 제공하여 애플리케이션 전체의 번들 크기를 감소해줍니다.
- Image, Font등의 컴포넌트를 사용하여 쉽게 최적화가 가능합니다.
제가 생각하는 Next.js의 프레임워크로서 주는 가장 큰 이점은 모노레포 방식의 풀스택 개발을 지원한다는 점입니다.
Next.js의 API routes와 서버사이드 기능을 내장하고 있어, 별도의 백엔드 서버를 설정하거나 복잡한 레포지토리 구조를 갖출 필요 없이 프론트엔드와 백엔드를 하나의 프로젝트 내에서 함께 관리할 수 있습니다.
API routes의 코드들을 node.js로 작성하여 Isomorphic Javscript의 이점을 얻을 수 있습니다. 이러한 이점을 통해 쉽게 풀스택 개발을 진행할 수 있으며 typescript을 사용 시 더 높은 개발자 경험을 기대할 수 있습니다.
저는 이러한 개발 방식이 특히 개발자가 프론트엔드와 백엔드 역할을 구분 짓지 않고 풀스택 개발을 지향할 때 더욱 효과적이라고 생각합니다. Next.js는 공유 가능한 코드, 일관된 개발 환경, 그리고 간편한 의존성 관리 등의 이점을 제공하여 효율적으로 프로젝트를 관리할 수 있게 합니다. 이러한 접근 방식은 특히 역할 구분이 모호하고 유연한 개발이 필요한 소규모 웹 기반 스타트업에서 장점이 극대화됩니다.
이 외에도 Next.js에 제공하는 기능은 다양하며 공식 문서에서 확인이 가능합니다.
Next.js는 단점이 없는 완벽한 프레임워크인가요?
당연히 아닙니다. 이렇게 Next.js의 장점만 많이 기술하다 보니 Next.js 칭송자로 오해받을 수도 있을 것 같다는 생각이 듭니다.😅
저도 그렇고 개발 동료분들도 그렇고 Next.js로 개발하면서 어려움을 겪은 적이 많습니다. 이미 다양한 개발 커뮤니티에서 Next.js의 장단에 대해 굉장히 뜨겁게 토론을 많이 하는 것을 볼 수 있는데요.
제가 Next.js를 사용하면서 겪은 단점은 다음과 같습니다.
1. 신버전 출시 주기가 짧습니다.
Next.js는 비교적 빠른 릴리스 주기를 가지고 있으며 이는 빠르게 발전하는 프레임워크의 장점이 될 수 있지만 몇가지 단점을 동반합니다.
먼저 기존의 버전에 익숙해졌더라도 새로 배워야 할 상황이 많이 온다는 의미이고 러닝커브를 꽤 요구합니다.
또한 기존의 코드가 빠르게 레거시(legacy)가 될 확률이 높습니다. 이는 프로젝트 규모가 커질수록 마이그레이션에 대한 부담이 크게 다가옵니다.
특히 이 문제는 최근 v.13이 출시되면서 더욱 체감이 됐는데요. RSC(React Server Compoent)를 중심으로 한 App router의 사용을 Next.js가 공식적으로 격려하면서 Page router 관련 코드들이 벌써 legacy의 길로 접어 들었습니다…
이러한 경향의 프로젝트 관리는 안정성이 부족하다는 평가도 많이 받습니다. 새로운 기능이 완전히 검증되지 않은 상태에서 도입되어 디버깅이나 문제 해결 시 커뮤니티 자원이 부족하여 관련 정보를 찾기 어려울 수 있습니다.
2. Next.js는 자유도가 꽤 떨어집니다.
Next.js는 프레임워크이기 때문에 어느 정도 사용 방식을 정해두고 있으며, 이는 개발자들에게 편리함을 제공하는 동시에 자유도를 제한하는 요소가 되기도 합니다.
Next.js는 기본적으로 Webpack을 사용하며, Vite와 같은 모던 번들러를 지원하지 않습니다. Webpack은 가장 대표적인 js 번들러이지만 그 외의 번들러를 선호하는 개발자들에게는 다소 아쉬운 부분입니다. 그 외에도 lint 등의 개발 도구 지원 범위도 넓지 않습니다.
Vercel이라는 serverless cloud platform에 상당히 종속적입니다. 이는 여러 개발자들의 비판이 되기도 합니다.
Next.js가 제공하는 서버 관련 기능을 포함하는 프로젝트는 단순히 정적 파일을 호스팅하는 방식으로 배포할 수 없으며, 서버 인프라가 필요합니다. 따라서 Next.js 프로젝트를 배포하려면 서버리스 플랫폼(Vercel 등)이나 AWS EC2와 같은 일반적인 클라우드 서버를 활용하는 경우가 많습니다.
허나 일부 최신 기능들은 Vercel 환경에서만 원활하게 동작하며, 타 배포 환경에서는 완전히 지원되지 않거나 까다로운 커스터마이징이 필요할 수도 있습니다.
예를 들면
- ISR은 Vercel의 서버리스 인프라에 최적화된 형태로 동작하기 때문에, 다른 클라우드 환경에서 동일한 기능을 구현하려면 상당한 추가 작업이 필요합니다.
- Next.js의 이미지 컴포넌트의 최적화 로직은 Vercel을 기본 배포 환경으로 설정한 상태에서 동작하도록 설계되어 있습니다.
Next.js의 주 사용자들은 제품에 집중하는 경우가 많기 때문에 인프라에 대해서 작업 비용을 투자하는 것을 상당히 꺼려합니다.
또한 Vercel은 DX(개발자 경험)를 극대화한 AWS 래퍼에 가깝기에 비용이 상당히 높은 편입니다. 무료 플랜에서는 기능이 제한적이며, 유료 플랜을 사용할 경우 프로젝트가 커질수록 비용 부담이 빠르게 커질 수 있습니다.
이러한 문제를 해결하기 위해 OpenNext와 같은 오픈소스 배포 도구가 등장했지만, Next.js의 기본적인 배포 전략이 Vercel을 중심으로 설계되어 있는 점은 여전히 개발자들에게 불편한 요소로 남아 있습니다.
마지막으로 이러한 Serverless 플랫폼에 배포하면 SSR은 필연적으로 cold start 문제에 직면하게 됩니다.
Serverless 아키텍처는 사용량이 없을 때 리소스를 자동으로 축소하고, 필요할 때 다시 인스턴스를 생성하는 방식을 사용합니다. 이러한 특성은 비용 절감에는 유리하지만, 초기 요청 시 서버가 활성화되는 데 시간이 걸리는 문제를 야기할 수 있습니다.
이는 특히 getServersideProps 함수를 통한 dynamic rendering에서 더 두드러집니다. 주로 새로운 데이터를 가져오기 위해 데이터베이스에 접근하는 경향이 높기 떄문이죠. Vercel측에서는 이러한 단점을 보완하기 위해 edge function을 제안하고 있지만 글쎼요.. runtime이 다른 함수를 프로덕션 환경에서 적용하기에는 아직 어려움이 있는 것 같습니다.
3. Server Server Server
Next.js는 다양한 서버 관련 기능을 내장하고 있지만 이러한 특성 덕분에 서버를 다루는 피로감과 불편함도 존재합니다.
기존 클라이언트 환경에서의 리소스 관리만 집중한 프론트엔드 개발자는 서버 환경에서의 리소스 관리 문제도 고려해야합니다. 물론 서버/클라이언트 모두 능숙하게 다루는 개발자가 이상적이긴 하지만 추가적인 공수를 요구한다는 점에서 피로감이 있을 수 있습니다.
일단 디버깅이 불편합니다. Next.js는 서버와 클라이언트가 같은 코드베이스에서 동작하지만, 디버깅할 때는 서로 다른 방식으로 접근해야 합니다. 프론트는 브라우저의 개발자 도구에서 쉽게 디버깅이 가능하지만, 서버 관련 디버깅은 터미널을 통해 확인해야합니다.
그리고 에디터로 코딩할 때 뭔가 램을 더 잡아먹는 느낌이 있습니다. 특히 HMR(Hot Module Reload) 관련하여 속도 저하가 종종 일어나고 간혹 멈춰서 에디터를 다시 시작해야 하는 경우도 있습니다.
그래서 Next.js는 필요한가요?
이 질문에 대해서는 개발자로서 뻔한 대답이 있죠.
상황에 따라서 다르다
보통 많은 개발자 분들이 Next.js의 필요성에 대해서 언급을 할 때 공통적으로 귀결되는 의견이 있습니다.
해당 프레임워크의 이점을 파악하고 이 이점이 현재 내가 하고자 하는바에 어떤 도움을 주는지를 인지하고 사용해야한다는 점입니다. 만약 그러지 않으면 오버 엔지니어링이 될 수 도 있고 예상치 못한 사이드 이펙트를 유발하여 유지보수성을 해칠 위험이 있습니다.
결국 프레임워크의 도입 여부는 본인이 처한 상황을 고려해 신중하게 해야한다는 모범적인 답안이라고 생각이 되는데요. 틀린 말은 아니지만 저는 조금 다른 견해를 가지고 있습니다.
프레임워크의 진짜 장점은, 내가 무었을 할 지 모를 때 더 빛을 발한다고 이라고 생각합니다.
저희는 어떤 프로덕트를 만들 때, 처음부터 모든 케이스를 완벽하게 설계하는 것은 불가능합니다. 개발을 진행하다 보면 끊임없이 새로운 고민과 의사결정에 부딪히게 되죠.
- “어떤 방식으로 페이지를 렌더링하면 가장 효율적일까?”
- “이 부분은 어떤 방식으로 최적화하면 좋을까?”
- “이 페이지는 SEO가 꼭 필요할까? 아니면 굳이 신경 쓰지 않아도 될까?”
- “이 도메인에서는 어떤 라우팅 전략을 적용하는 것이 좋을까?”
이러한 고민 속에서, Next.js는 다양한 기능을 통해 자연스럽게 해결책을 찾아갈 수 있도록 도와줍니다.
페이지마다 CSR, SSR, SSG 등의 렌더링 방식을 유연하게 선택할 수 있고, SEO가 필요한 페이지에는 SSR이나 SSG를 적용하고, 필요하지 않은 페이지는 CSR로 동작하도록 설정할 수도 있습니다.
처음에는 모든 기능이 필요하지 않을 수도 있습니다. 하지만 개발이 진행되면서 점점 더 많은 요구 사항이 생길 때, Next.js를 사용하고 있다면 이미 내장된 기능을 활용해 쉽게 대응할 수 있습니다.
마지막으로 프레임워크 적용에 대한 고민을 여행을 떠날 때 싸는 짐에 비유해서 생각해 볼까요?
어딘가로 매우 멀리 긴 여행을 떠난다고 가정하겠습니다. 사람마다 짐을 싸는 성향은 다를 겁니다.
-
어떤 사람은 출발전에 짐을 잔뜩 쌉니다.
- 혹시라도 현지 음식이 맞지 않을까 음식을 챙기고
- 날씨 변화에 대비해 더울 떄, 추울 때, 비 올 때 등 입을 옷을 모두 챙기며,
- 각종 상황에 대비할 수 있는 여행용품까지 빼곡히 가방에 채웁니다.
- 이들은 사전에 최대한 많은 준비를 해서, 예상치 못한 문제를 줄이는 것을 선호합니다.
-
반면 어떤 사람은 가볍게 배낭 하나만 메고 떠납니다.
- 꼭 필요한 최소한의 물건만 챙긴 뒤,
- 여행 중에 필요하면 그때그때 조달하면 된다고 생각하죠.
- 이들은 때에 따른 변화를 고려하며 더 가볍고 자유롭습니다
첫번째 사람은 짐을 무겁게 잔뜩 쌋기 때문에 수하물 비용도 많이 나갈 것입니다. 또한 막상 여행을 하면서 불필요한 짐도 있을 것입니다. 하지만 여러 상황에 대하여 유연하게 대처할 수 있을 것입니다.
두번째 사람은 수하물 비용이 거의 없을 것입니다. 매우 가벼운 몸으로 여행도 빠르게 다닐 수 있겠죠. 반면 여행을 하면서 현지에서 몇몇 상황을 어렵게 대처해야 할 수도 있습니다.
누가 옳다고 말하긴 힘듭니다. 하지만 보통 여행 초심자는 전자가 많고 여행 숙련자는 후자가 많겠죠?
자 그럼 묻겠습니다.
여러분은 어떻게 짐을 싸실건가요?