O que é Svelte?
Svelte é um framework de componentes com um diferencial: ele é um compilador. Em vez de enviar um runtime que interpreta seus componentes no navegador, o Svelte os analisa no momento do build e gera JavaScript puro que atualiza o DOM diretamente. Não existe virtual DOM e quase não há código do framework no bundle final.
Esse design muda a experiência do desenvolvedor. A reatividade faz parte da linguagem, os estilos são escopados por padrão e as transições já vêm integradas, resultando em componentes mais concisos. A contrapartida é a necessidade de uma etapa de build, mas as ferramentas modernas tornam isso algo trivial.
Componentes de arquivo único
Um componente Svelte é um arquivo .svelte com um bloco de script, marcação e estilos opcionais com escopo.
<!-- Card.svelte -->
<script>
let { title, children } = $props();
</script>
<article class="card">
<h3>{title}</h3>
{@render children?.()}
</article>
<style>
.card {
border-radius: 1rem;
padding: 1.5rem;
}
</style>
Os estilos em um componente possuem escopo local por padrão, portanto, a regra .card não pode vazar. $props() lê as props passadas pelo pai, e snippets (children) permitem que um pai passe marcação para um filho.
Reatividade com runes
O Svelte 5 introduziu as runes, primitivas explícitas que tornam a reatividade previsível. $state declara o estado reativo, $derived computa valores e $effect executa efeitos colaterais.
<!-- Search.svelte -->
<script>
let query = $state("");
let results = $state([]);
let hasResults = $derived(results.length > 0);
$effect(() => {
if (!query) return;
const controller = new AbortController();
fetch(`/api/search?q=${query}`, { signal: controller.signal })
.then((r) => r.json())
.then((data) => (results = data))
.catch(() => {});
return () => controller.abort();
});
</script>
<input bind:value={query} placeholder="Search" />
{#if hasResults}
<ul>
{#each results as item (item.id)}
<li>{item.name}</li>
{/each}
</ul>
{/if}
As runes também funcionam em arquivos .svelte.js e .svelte.ts, permitindo que você extraia a lógica reativa para módulos reutilizáveis, da mesma forma que o React utiliza custom hooks.
Props, eventos e snippets
As props fluem para baixo e são declaradas com $props(). Em vez de um sistema de eventos especial, o Svelte 5 utiliza callback props para a comunicação do filho para o pai.
<!-- Child.svelte -->
<script>
let { label, onselect } = $props();
</script>
<button onclick={() => onselect(label)}>{label}</button>
<!-- Parent.svelte -->
<Child label="Save" onselect={(value) => save(value)} />
Snippets substituem os slots para regiões de marcação reutilizáveis, e {@render} os insere onde você desejar.
Fluxo de controle
O Svelte possui blocos de template dedicados para condicionais e loops, e o bloco #each suporta uma expressão com chave (keyed expression) para atualizações eficientes.
<!-- list.svelte -->
{#if users.length > 0}
<ul>
{#each users as user (user.id)}
<li>{user.name}</li>
{/each}
</ul>
{:else}
<p>No users yet.</p>
{/if}
Como o compilador conhece a estrutura, esses blocos geram operações de DOM direcionadas em vez de uma passagem genérica de reconciliação.
Stores e estado compartilhado
Para estados compartilhados entre muitos componentes, o Svelte oferece stores: uma store writable armazena um valor e notifica os inscritos, enquanto readable e derived cobrem outros casos.
// counter.js
import { writable, derived } from "svelte/store";
export const count = writable(0);
export const double = derived(count, ($count) => $count * 2);
<!-- Display.svelte -->
<script>
import { count, double } from "./counter.js";
</script>
<p>{$count} doubled is {$double}</p>
O prefixo $ faz a inscrição e o cancelamento da inscrição automaticamente para você. Com runes, um módulo .svelte.js exportando $state pode alcançar o mesmo resultado sem a API de store, o que muitos projetos novos preferem para valores globais da aplicação.
Transições e animações
O movimento já vem integrado. As diretivas transition, animate e in/out adicionam movimento sem a necessidade de uma biblioteca externa.
<!-- toast.svelte -->
<script>
import { fade, fly } from "svelte/transition";
let visible = $state(false);
</script>
<button onclick={() => (visible = !visible)}>Toggle</button>
{#if visible}
<div transition:fly={{ y: 20, duration: 200 }}>
Saved!
</div>
{/if}
Como as transições são compiladas, elas são eficientes e suportam tree-shaking, além de respeitarem a preferência de redução de movimento do usuário quando você utiliza os helpers integrados.
SvelteKit
O SvelteKit é o framework oficial para a criação de aplicações. Ele adiciona roteamento baseado em arquivos, renderização no servidor, carregamento de dados e ações de formulário sobre o Svelte.
src/routes/
├── +page.svelte # a page
├── +layout.svelte # shared layout
├── about/+page.svelte # /about
└── blog/[slug]/+page.js # load data for /blog/:slug
Se você está construindo algo mais complexo do que um widget, o SvelteKit é o ponto de partida recomendado. Ele cuida das convenções que toda aplicação real precisa, permitindo que você foque nas funcionalidades.
Melhores práticas
- Use runes (
$state,$derived,$effect) em códigos novos. - Prefira
$derivedpara valores computados e reserve$effectpara efeitos colaterais (side effects). - Mantenha os componentes pequenos e extraia a lógica reutilizável para módulos
.svelte.js. - Use blocos
{#each}com chaves (keyed) quando os itens puderem ser reordenados. - Mantenha os estilos com escopo (scoped) por padrão e evite
:global, a menos que seja necessário. - Compartilhe estados entre componentes usando stores ou um módulo reativo.
- Inicie novos apps com SvelteKit em vez de configurar o build manualmente.
Erros comuns
- Usar
$effectpara calcular um valor que o$deriveddeveria gerenciar. - Esquecer a key em
{#each}e quebrar as atualizações de listas. - Mutar uma propriedade aninhada de um objeto
$statede forma que ignore a reatividade em padrões mais antigos. - Recorrer a um store global quando um estado local seria suficiente.
- Assumir que o Svelte não possui runtime algum — existe um, porém é pequeno.
- Ignorar a acessibilidade porque o compilador torna a escrita da marcação muito rápida.
Próximos passos
O Svelte é uma maneira rápida e elegante de construir interfaces, e o SvelteKit o transforma em um framework de aplicação completo. Compare a abordagem de compilador com React e Vue, e mantenha seu JavaScript afiado. Depois, construa um pequeno app com uma store e uma transition para sentir a diferença.