컴포넌트를 빌드할 때 DOM(Document Object Model)을 직접 바꾸는 JS(JavaScript)로 컴파일하는 UI 프레임워크. React처럼 런타임에 가상 DOM(Virtual DOM)을 비교하지 않고, 어떤 값이 바뀌면 어떤 DOM을 고칠지 컴파일러가 미리 코드로 만들어 둔다. 앱 프레임워크는 SvelteKit이다.
마크업 블록
{#await promise}
<p>불러오는 중…</p>
{:then items}
{#each items as item}<li>{item}</li>{/each}
{:catch error}
<p>{error.message}</p>
{/await}Promise를 마크업에서 바로 다룬다. React의 Suspense와 use()가 하는 일을 템플릿 문법으로 푼 셈이다. 내장 HTTP 클라이언트는 없어서 fetch를 쓴다.
each 블록에는 괄호로 키를 줄 수 있다. 키는 항목마다 고유해야 하고, 문자열이나 숫자를 권장한다. 객체 자체가 새로 바뀌어도 같은 항목으로 알아볼 수 있기 때문이다.
{#each items as item (item.id)}
<li>{item.name}</li>
{/each}키가 있으면 Svelte는 데이터가 바뀔 때 키를 따라 그 항목의 DOM을 삽입·이동·삭제한다. 키가 없으면 목록 끝에서 DOM을 더하거나 빼고, 중간의 DOM은 위치 그대로 두고 새 데이터로 내용만 갱신한다. 그래서 중간 항목 하나를 지우면 그 뒤의 DOM 노드들이 한 칸씩 다른 항목의 데이터를 받는다. React의 key도 형제 항목을 구별해 같은 문제를 막는다(재조정(Reconciliation)).
특수 요소
svelte:window,svelte:body,svelte:document: 전역 객체의 이벤트와 값(scrollY등)을 선언적으로 바인딩한다. 컴포넌트가 사라지면 리스너도 자동으로 정리된다svelte:head: 페이지 제목처럼head안의 태그를 컴포넌트에서 바꾼다 → generateMetadata와 비교- 모듈 스크립트(
<script module>)는 인스턴스마다가 아니라 모듈이 처음 평가될 때 한 번만 실행되어, 인스턴스 사이에 값을 공유하는 데 쓴다
Svelte 5에서 바뀐 점(2026 기준)
Svelte 5는 반응성을 $state, $derived, $effect 같은 룬(Runes)으로 바꿨고, 옛 문법 몇 가지가 바뀌었다.
- 모듈 스크립트:
context="module"→module속성 - 동적 컴포넌트:
svelte:component this={X}없이 컴포넌트 변수를 바로 태그로 쓴다 - 재귀 컴포넌트:
svelte:self대신 자기 자신을 import해서 쓴다 - 이벤트:
on:click디렉티브 대신onclick속성
옛 자료(Svelte 3·4)를 볼 때는 이 차이를 감안해야 한다. $derived가 의존성을 자동으로 추적하는 방식은 Vue의 computed와 비슷하다.
출처: Svelte 공식 문서 · Svelte - Keyed each blocks · Svelte 튜토리얼 - Keyed each blocks · React - Why does React need keys? · Svelte 5 migration guide