ARTICLE

Next.js보다
SvelteKit이 더 좋은 이유

더 단순한 아키텍처, 더 명확한 규칙, 더 가벼운 결과물

truwater | 2026.02

들어가며

Next.js는 React 생태계의 풀스택 프레임워크로서 확고한 위치를 차지하고 있다. App Router, Server Components, Server Actions 등 강력한 기능들을 제공한다.

하지만 그 강력함에는 대가가 따른다. 복잡한 캐싱 전략, 끊임없이 변하는 API, 예측하기 어려운 렌더링 동작. Next.js가 점점 복잡해지는 동안, SvelteKit은 단순함을 무기로 조용히 성장해왔다.

이 글은 두 프레임워크를 실무에서 사용한 경험을 바탕으로, SvelteKit이 더 나은 선택이 될 수 있는 이유를 풀스택 관점에서 비교한다.

설계 철학의 차이

두 프레임워크의 근본적인 차이는 설계 철학에서 시작된다. Next.js는 React의 한계를 서버 측 기능으로 보완하려 하고, SvelteKit은 처음부터 서버와 클라이언트를 하나의 모델로 설계했다.

Next.js

"React를 위한 프레임워크"

  • React의 복잡성을 계승
  • Server/Client Component 경계 관리 필요
  • 캐싱 레이어가 여러 겹
  • Vercel 플랫폼에 최적화된 설계

SvelteKit

"웹을 위한 프레임워크"

  • 웹 표준(Web Standards) 기반 설계
  • 서버/클라이언트 경계가 파일 단위로 명확
  • 예측 가능한 데이터 흐름
  • 어댑터로 어디서든 배포 가능

라우팅 시스템

두 프레임워크 모두 파일 기반 라우팅을 사용하지만, 접근 방식이 다르다. Next.js의 App Router는 유연하지만 복잡하고, SvelteKit은 규칙이 명확하여 예측 가능하다.

Next.js App Router

app/
├── page.tsx
├── layout.tsx
├── loading.tsx
├── error.tsx
├── not-found.tsx
├── template.tsx
├── default.tsx
└── blog/
    ├── page.tsx
    └── [slug]/
        └── page.tsx

7종류의 특수 파일 + 동적 규칙

SvelteKit

routes/
├── +page.svelte
├── +page.server.ts
├── +layout.svelte
├── +error.svelte
└── blog/
    ├── +page.svelte
    └── [slug]/
        ├── +page.svelte
        └── +page.server.ts

+ 접두사로 명확한 파일 구분

SvelteKit의 + 접두사 컨벤션은 라우트 파일과 컴포넌트 파일을 명확히 구분한다. +page.svelte는 UI, +page.server.ts는 서버 로직. 파일 이름만 보고도 역할을 즉시 알 수 있다.

Next.js의 App Router에서는 page.tsx, layout.tsx, loading.tsx, error.tsx, template.tsx, default.tsx, not-found.tsx 등 다양한 특수 파일이 복잡하게 상호작용하며, 이들 사이의 우선순위를 이해해야 한다.

데이터 로딩

데이터 로딩은 풀스택 프레임워크의 핵심이다. 여기서 두 프레임워크의 철학 차이가 가장 극명하게 드러난다.

Next.js 방식

// app/blog/page.tsx
// Server Component에서
// 직접 fetch
async function BlogPage() {
  const posts = await
    fetch('/api/posts',
    {
      cache: 'force-cache',
      next: {
        revalidate: 60,
        tags: ['posts']
      }
    });

  return <PostList
    posts={posts} />;
}

● cache 옵션을 매번 결정해야 함

● revalidate 전략 선택 필요

● 캐싱 동작 예측이 어려움

SvelteKit 방식

// +page.server.ts
export async function
  load({fetch}) {
  const posts = await
    fetch('/api/posts');
  return {posts};
}

// +page.svelte
<script>
  let {data} = $props();
</script>

{#each data.posts
  as post}...{
  /each}

✓ load 함수 하나로 데이터 로딩

✓ 서버/클라이언트 자동 전환

✓ 데이터 흐름이 단방향

SvelteKit의 load 함수는 단순하다. 서버에서 데이터를 가져오고, 컴포넌트에 data로 전달한다. 캐싱 전략을 고민할 필요 없이, 프레임워크가 네비게이션 패턴에 맞게 자동으로 처리한다.

Next.js의 캐싱 시스템은 여러 차례 변경을 거쳤다. fetch 캐시의 기본 동작이 버전마다 달라지면서 개발자들에게 혼란을 야기했고, 이는 프레임워크에 대한 신뢰도에 영향을 미쳤다.

폼 처리

웹 개발에서 폼은 빠질 수 없는 요소다. 두 프레임워크 모두 서버 측 폼 처리를 지원하지만, SvelteKit의 Form Actions는 웹 표준에 더 가깝고 점진적 향상을 자연스럽게 지원한다.

Next.js Server Actions

// action.ts
'use server'

async function createPost(
  formData: FormData
) {
  // 'use server' 디렉티브 필수
  const title =
    formData.get('title');
  await db.post.create({
    data: {title}
  });
  revalidatePath('/blog');
}

SvelteKit Form Actions

// +page.server.ts
export const actions = {
  default: async ({
    request
  }) => {
    const data = await
      request.formData();
    const title =
      data.get('title');
    await db.post.create({
      data: {title}
    });
    return {success: true};
  }
};

SvelteKit Form Actions의 강점

점진적 향상

JavaScript 없이도 폼이 동작한다. JS가 로드되면 자동으로 SPA처럼 전환.

Named Actions

하나의 페이지에서 여러 폼 액션을 이름으로 구분하여 깔끔하게 처리.

자동 유효성 검증

fail() 함수로 에러를 반환하면 폼 데이터가 자동으로 유지.

use:enhance

한 줄 추가로 AJAX 폼 제출, 낙관적 UI 등 고급 기능 활성화.

SvelteKit의 폼 처리는 HTML의 기본 <form> 동작을 존중한다. use:enhance를 추가하면 JavaScript가 활성화된 환경에서 AJAX 방식으로 자동 업그레이드되지만, JS가 비활성화되어도 폼은 정상 동작한다. 이것이 진정한 점진적 향상이다.

번들 사이즈 & 배포

SvelteKit 앱은 Next.js 앱에 비해 현저히 작은 JavaScript 번들을 생성한다. Svelte 자체가 컴파일러이기 때문에 프레임워크 런타임 오버헤드가 거의 없다.

초기 JS 번들 비교 (간단한 블로그 앱)

SvelteKit ~25 KB
Next.js (App Router) ~95 KB

* gzip 압축 기준, 동일한 기능의 블로그 앱 비교 (근사치)

SvelteKit 어댑터 시스템

SvelteKit은 어댑터를 통해 다양한 환경에 맞는 빌드를 생성한다. 특정 플랫폼에 종속되지 않는다.

adapter-auto
adapter-node
adapter-static
adapter-vercel
adapter-netlify
adapter-cloudflare

Next.js는 Vercel에 최적화되어 있고, 다른 환경에서는 일부 기능이 제한되거나 추가 설정이 필요하다. SvelteKit은 어댑터 하나만 바꾸면 Node.js 서버, 정적 사이트, 엣지 환경 어디서든 동일하게 동작한다.

개발자 경험 (DX)

프레임워크를 선택할 때, 일상적으로 코드를 작성하는 경험이 어떤지가 중요하다. SvelteKit은 여러 면에서 더 쾌적한 개발 경험을 제공한다.

멘탈 모델의 단순함

Next.js는 Server Component, Client Component, Server Action, Route Handler, Middleware 등 다양한 개념을 이해해야 한다. SvelteKit은 +page.svelte(UI)와 +page.server.ts(서버) 두 파일의 관계만 이해하면 대부분의 패턴을 구현할 수 있다.

에러 메시지의 명확성

SvelteKit의 에러 메시지는 대체로 명확하고 해결 방향을 제시한다. Next.js의 에러, 특히 Server/Client Component 경계에서 발생하는 에러는 종종 원인을 파악하기 어렵다.

안정적인 API

SvelteKit 1.0 이후 API가 안정적으로 유지되고 있다. Next.js는 Pages Router에서 App Router로의 대규모 전환, 캐싱 기본값 변경 등 파괴적 변경이 빈번하다. 안정된 API는 장기 프로젝트 유지보수의 핵심이다.

빌트인 기능

SvelteKit은 트랜지션, 애니메이션, CSS 스코핑, 접근성 경고 등을 프레임워크 레벨에서 기본 제공한다. Next.js에서 같은 기능을 구현하려면 Framer Motion, CSS Modules, eslint-plugin-jsx-a11y 등 별도 라이브러리가 필요하다.

결론

SvelteKit은 웹 개발의 본질에 집중한다. 웹 표준을 존중하고, 복잡성을 컴파일러가 해결하며, 개발자는 제품 로직에만 집중할 수 있게 한다.

Next.js가 더 적합한 상황도 분명 있다. React 생태계의 방대한 라이브러리가 필수적이거나, 대규모 팀에서 React 경험자를 채용해야 하거나, React Native와 코드를 공유해야 하는 경우가 그렇다.

하지만 새 프로젝트를 시작할 때, 프레임워크가 제공하는 기능의 양보다 "얼마나 적은 인지 부하로 제품을 만들 수 있는가"를 기준으로 삼는다면, SvelteKit은 매우 매력적인 선택이다.

복잡함은 쉽다. 단순함이 어렵다. SvelteKit은 그 어려운 단순함을 선택했다.