본문 바로가기
Frontend2026년 4월 23일8분 읽기

Astro 5 vs Next.js 16 — 콘텐츠 사이트 vs 앱 선택 가이드

YS
김영삼
조회 1
Astro 5 vs Next.js 16 — 콘텐츠 사이트 vs 앱 선택 가이드

핵심 요약

둘 다 React 호환이지만 사상이 다르다. Astro는 "기본 정적 + 필요한 곳만 인터랙티브 (Islands)", Next.js는 "기본 컴포넌트 = 인터랙티브 가능 + RSC로 부분 정적". 콘텐츠 vs 앱 비중에 따라 선택이 갈린다.

  • Astro 5 (2026-01): React·Vue·Svelte 모두 통합, Server Islands
  • Next.js 16 (2025-10): App Router 안정화, RSC 표준
  • Astro 번들이 항상 작음 (인터랙티브 없으면 0KB JS)

1. 철학 차이

Astro — 기본 정적

---
// .astro 파일 — 빌드 시 한 번만 실행
const posts = await fetch('/api/posts').then(r => r.json())
---
<html>
  <body>
    {posts.map(p => <article>{p.title}</article>)}
    <!-- 자바스크립트 0KB 페이지 -->
    
    <!-- 필요한 곳만 island -->
    <ReactCounter client:load />
  </body>
</html>

Next.js — 기본 컴포넌트

// page.tsx (RSC by default in Next 16)
async function PostList() {
  const posts = await fetch('/api/posts').then(r => r.json())
  return (
    <div>
      {posts.map(p => <article>{p.title}</article>)}
      <ClientCounter /> {/* 클라이언트 컴포넌트 */}
    </div>
  )
}

2. 번들 크기 비교

페이지 유형AstroNext.js (RSC)
완전 정적 콘텐츠0~5KB JS~80KB JS
일부 인터랙티브 (Counter)~30KB~120KB
대시보드 (인터랙티브 많음)~150KB~180KB

콘텐츠 사이트에서 Astro의 차이가 크다. 인터랙티브 비중이 높으면 차이 줄어듦.

3. Server Islands (Astro 5 신기능)

Astro의 정적 + dynamic 혼합. 페이지는 정적이지만 일부 영역만 동적 렌더.

---
import UserGreeting from './UserGreeting.astro'
---
<html>
  <body>
    <h1>블로그 — 정적</h1>
    
    <!-- 이 부분만 요청 시점에 server에서 렌더 -->
    <UserGreeting server:defer>
      <p slot="fallback">Loading...</p>
    </UserGreeting>
    
    <article>블로그 콘텐츠 — 정적</article>
  </body>
</html>

RSC와 비슷한 개념이지만 Astro는 정적 베이스 위에 dynamic 추가, RSC는 dynamic 베이스 위에 정적 캐시.

4. 콘텐츠 통합 — Content Collections

// content/config.ts
import { defineCollection, z } from 'astro:content'

const blog = defineCollection({
  type: 'content',
  schema: z.object({
    title: z.string(),
    publishedAt: z.date(),
    tags: z.array(z.string()),
  }),
})

export const collections = { blog }
---
// pages/blog/[slug].astro
import { getEntry } from 'astro:content'
const { slug } = Astro.params
const post = await getEntry('blog', slug)
const { Content } = await post.render()
---
<Layout title={post.data.title}>
  <Content />
</Layout>

Markdown·MDX 파일을 타입 안전하게 다룸. 블로그·문서 사이트에 강력.

5. 통합 — 여러 프레임워크 동시 사용

---
import ReactCounter from './Counter.tsx'
import VueChart from './Chart.vue'
import SvelteAccordion from './Accordion.svelte'
---
<!-- 동일 페이지 안에 React·Vue·Svelte 동시 -->
<ReactCounter client:load />
<VueChart client:visible />
<SvelteAccordion client:idle />

레거시 코드 점진 마이그레이션·팀별 다른 프레임워크 사용 시 강함.

6. SEO·Performance

지표AstroNext.js
LCP (정적 콘텐츠)0.6초0.9초
TTI (정적)0.7초1.2초
SEO (Lighthouse)10096
접근성비슷비슷

콘텐츠 사이트에서 Astro의 LCP·TTI가 명확히 빠름. 모바일·저사양 디바이스에서 차이 더 큼.

7. 의사결정 매트릭스

워크로드1순위
블로그·문서Astro
이커머스 (콘텐츠 비중 큼)Astro
마케팅 사이트Astro
관리자 대시보드Next.js
SaaS 앱Next.js
실시간 협업 도구Next.js
인터랙티브 미디어Next.js
API 위주 + 약간 페이지Hono/Bun (둘 다 아님)

8. 호스팅·배포

플랫폼AstroNext.js
Vercel★★★★★★★★★
Cloudflare Pages★★★★★★★★★
Netlify★★★★★★★★★
self-hosted★★★★★ (정적이라 단순)★★★★ (Node 필요)

9. 마이그레이션

Next.js → Astro

콘텐츠 사이트라면 1~2주. 컴포넌트 대부분 그대로 사용 (.tsx → .astro 또는 island로 유지).

Astro → Next.js

인터랙션 비중 커지면 자연스러운 전환. 단 페이지 구조 재설계 필요.

실전 사례

  • youngsam.net 같은 블로그+커뮤니티: Astro가 콘텐츠 부분, Next.js가 인터랙션 부분 (둘 다 사용)
  • shopify storefront: Astro로 단일 사이트 마이그레이션 사례 많음
  • 실시간 분석 대시보드: Next.js 압도

자주 묻는 질문

둘 다 쓸 수 있나?가능. 콘텐츠는 Astro, 앱은 Next.js로 분리. 같은 도메인 다른 path.

Astro에서 RSC 같은 게 가능?Server Islands가 RSC와 비슷한 개념. 단 더 단순.

학습 부담?둘 다 비슷. Astro는 .astro 문법 추가, Next.js는 RSC·서버액션 추가. 한쪽 알면 1~2주면 다른 쪽도 가능.

댓글 0

아직 댓글이 없습니다.
Ctrl+Enter로 등록