SolidJS em 2026: Por que a reatividade fina está superando o Virtual DOM
Sem Virtual DOM e com reatividade fina, o SolidJS redefine o desenvolvimento frontend em 2026 com performance superior e componentes otimizados..

Por que esse framework importa — e quando ele não importa
Em 2026, a pergunta não é mais se o Virtual DOM funciona, mas se o custo de reconciliação ainda é aceitável para a sua aplicação. Escolher um framework de frontend transcende a sintaxe; é uma decisão sobre qual modelo mental norteará sua equipe pelos próximos anos.
O Virtual DOM foi uma solução inteligente para um problema real: como atualizar a UI sem tocar no DOM manualmente? React respondeu com uma cópia em memória da interface, comparação de árvores e aplicação das diferenças. Funcionou. Funcionou tão bem que se tornou o default da indústria por uma década.
SolidJS respondeu à mesma pergunta de outra forma. Em vez de construir e comparar árvores, conecta cada pedaço de estado diretamente ao nó DOM que o exibe. Quando o estado muda, o nó atualiza. Não há árvore para comparar porque nunca há uma cópia — há apenas a conexão.
A diferença não é cosmética. É arquitetural. E em 2026, com o Solid 2.0 em beta maduro e a versão estável em 1.9.13, a pergunta não é mais "isso funciona?" — é "quando vale a troca?"
Ryan Carniato, criador do SolidJS e hoje Principal Engineer para Open Source na Netlify, levou mais de uma década refinando o modelo reativo do framework. Não é um experimento — é uma filosofia testada em produção. Em 2026, essa filosofia influencia Angular, Vue 3 e até a direção do compilador React.
"A reatividade fina não é otimização prematura. É não pagar pelo que você não usa."
O ecossistema em números — Jun 2026
Métrica | Valor |
|---|---|
Downloads semanais npm | ~2,4M |
Estrelas GitHub | 35K+ |
Core gzipped | 7,6KB |
Crescimento ano a ano | ~60% |
O SolidJS em 2026 ocupa uma posição fascinante no ecossistema JavaScript. Pode não ser o framework mais popular, mas é provavelmente o mais influente dos últimos cinco anos. O paradigma de signals que ele pioneirizou é hoje a fundação da reatividade do Angular, a base filosófica do sistema do Vue, a pressão competitiva por trás do compilador do React, e um candidato à inclusão na própria linguagem JavaScript via TC39.
⚠️ Trade-off honesto: O ecossistema do SolidJS ainda é jovem. Bibliotecas de UI são limitadas, a maioria das bibliotecas React não tem port para Solid, e os recursos comunitários são escassos comparados ao React — menos tutoriais, menos respostas no Stack Overflow, menos padrões testados em produção para edge cases. A presença no mercado de trabalho é mínima. Avalie se as bibliotecas que você precisa existem antes de se comprometer.
Os três primitivos que substituem toda a mágica
Aprenda estes três e você aprendeu o framework. Tudo o mais é construído sobre eles.
Getter e setter que rastreiam automaticamente os consumidores sem arrays de dependência.
Calculado de forma preguiçosa, atualiza somente quando necessário.
Executa interações externas em resposta a mudanças reativas.
Três conceitos essenciais para entender o framework
Primitivo 01 — Signal
A fonte do estado. Um getter e um setter. O detalhe que importa: ele rastreia automaticamente quem o lê. Sem arrays de dependência — o runtime detecta os consumidores durante a execução.
Primitivo 02 — Memo
Valor derivado, lazy e puro. Recalcula apenas quando algo de que depende muda, e apenas quando alguém efetivamente o lê. É o useMemo do React, mas sem o array manual e sem a armadilha do stale closure.
Primitivo 03 — Effect
O efeito colateral. O único lugar com permissão para tocar o mundo externo — DOM, rede, console. Re-executa apenas quando suas entradas mudam. Sem useEffect, sem lista de deps, sem bug de sincronização.
import { createSignal, createMemo, createEffect } from "solid-js";// 1. Signal: a origem do estadoconst [preco, setPreco] = createSignal(100);// 2. Memo: derivado, lazy — só recalcula quando lido e quando preco mudaconst comImposto = createMemo(() => preco() * 1.1);// 3. Effect: efeito colateral — SEM array de dependênciascreateEffect(() => { console.log("Total com imposto:", comImposto()); // O Solid rastreou automaticamente que comImposto() foi lido aqui});// Componente — executa UMA vez, nunca re-renderizafunction Preco() { return <p>{comImposto()}</p>; // só o nó de texto atualiza}✅ Diferença chave: O componente em Solid executa uma única vez. React chama a função do componente a cada render. Em Solid, apenas os signals e efeitos re-executam — o componente em si é executado só na montagem, configurando as conexões reativas.
Estado complexo com createStore
Para objetos e arrays aninhados, signals básicos ficam verbosos. O createStore usa Proxies para rastrear acesso a propriedades em profundidade, mantendo a reatividade fina mesmo em estruturas complexas.
import { createStore, produce } from "solid-js/store";function TodoApp() { const [state, setState] = createStore({ todos: [], filtro: "todos", }); const adicionarTodo = (texto) => { setState(produce((s) => { s.todos.push({ id: Date.now(), texto, feito: false }); })); }; const toggleTodo = (id) => { setState( "todos", (todo) => todo.id === id, "feito", (feito) => !feito ); // Só o campo "feito" do item específico atualiza no DOM }; return ( <ul> {state.todos.map((todo) => ( <li onClick={() => toggleTodo(todo.id)}>{todo.texto}</li> ))} </ul> );}Async como cidadão de primeira classe — Solid 2.0 Beta
A mudança central no Solid 2.0 é que async agora é first-class. Computações podem retornar Promises e o grafo reativo lida com suspensão e retomada automaticamente.
// Solid 2.0 Beta: createAsync como primitivo padrãoimport { createAsync } from "@solidjs/router";function Perfil(props) { // O grafo reativo cuida de suspensão e retomada const usuario = createAsync(() => buscarUsuario(props.id)); return <h1>{usuario()?.nome}</h1>; // Sem useState, useEffect, dependências manuais, try/catch}// ATENÇÃO Solid 2.0: leia o signal ANTES do awaitconst dobro = createMemo(async () => { const c = count(); // ← leia aqui, ANTES do await await delay(100); return c * 2; // ← não leia count() depois do await boundary});⚠️ Mudança de mental model no 2.0: No Solid 2.0, se você definir signals e imediatamente ler do sistema, pode não ver o que espera porque as escritas ainda estão em batch. Use
flush()para observar o estado atualizado em testes unitários. Leia o signal antes de qualquer boundaryawait.
React vs SolidJS: o que a diferença arquitetural significa na prática
Critério | React 19 | SolidJS 1.9 / 2.0 |
|---|---|---|
Modelo de renderização | Virtual DOM + diffing | DOM direto via signals ✅ |
Re-execução de componente | A cada mudança de estado | Uma única vez ✅ |
Array de dependências | Manual — fonte de bugs | Automático — o runtime rastreia ✅ |
Tamanho do bundle | ~45KB (react + react-dom) | ~7,6KB core ✅ 6× menor |
JS Framework Benchmark | Top 10, mas atrás do Solid | Próximo do vanilla JS ✅ 1º tier |
Async (data fetching) | useEffect + useState ou TanStack Query | createAsync / createResource (2.0 nativo) |
Estado global | Zustand / Redux / Context | createStore nativo, signals globais |
Downloads npm (jun/2026) | ~50M/semana (ecossistema) | ~2,4M/semana (+60% a/a) |
Mercado de trabalho | Dominante | Mínimo — especialistas |
Meta-framework | Next.js (maduro, 11M/sem) | SolidStart 1.3 (estável, crescendo) |
Os cinco critérios técnicos
01 — Escalabilidade
A reatividade fina do Solid escala de forma sublinear. Em sistemas de store centralizados (padrão NgRx), o custo de uma atualização tende a O(n) — proporcional ao número de assinantes. Em observables aninhados (RxJS), pode chegar a O(n²). Em signals, o custo se aproxima de O(1): a atualização propaga apenas para os cálculos que efetivamente dependem do signal alterado.
Para listas longas e atualizações frequentes, isso é medível. Empresas como a Radware reportaram bundles Solid de ~80KB comparados a ~290KB do React para funcionalidades equivalentes. A Jolt AI usa Solid em 6 plataformas (web, VS Code, JetBrains, macOS, Windows, Linux) com 93% de reuso de código mantendo baixo footprint de memória para ambientes IDE embarcados.
O limite de escalabilidade não está na performance — está no ecossistema.
02 — Curva de aprendizado
A JSX é familiar para quem vem do React. A API parece familiar. O mental model, não. Solid parece React na superfície mas é fundamentalmente diferente embaixo. Quem aprende Solid depois do React frequentemente passa por um momento de desorientação: "por que meu console.log dentro do componente só roda uma vez?" — porque o componente só executa uma vez.
A curva sobe especialmente com signals em contextos assíncronos. No Solid 2.0, se você espera que uma leitura de signal rastreie depois de um await, vai ter problemas. Rastreamento acontece em sincronia.
Para desenvolvedores sem histórico de React, a curva pode ser mais suave: eles não carregam os hábitos errados. O que leva semanas para quem veio do React pode levar dias para quem vem do vanilla JS.
03 — Performance e throughput
O JS Framework Benchmark é o indicador mais amplo disponível. Solid fica consistentemente no primeiro tier, ao lado de Inferno e vanilla JS, acima de React, Vue e Angular.
O ganho não vem de heurística ou otimização: vem do modelo. Sem Virtual DOM, sem reconciliação, sem cópia da árvore. O compilador transforma JSX em operações DOM diretas em tempo de build.
import { createSignal } from "solid-js";function Counter() { const [count, setCount] = createSignal(0); // Esta função executa UMA vez — não a cada clique // Só o nó de texto com {count()} atualiza no DOM return ( <button onClick={() => setCount(count() + 1)}> Clicado {count()} vezes </button> );}// O que o compilador Solid gera (simplificado):// const button = document.createElement("button");// const text = document.createTextNode("");// createEffect(() => { text.data = `Clicado ${count()} vezes`; });// button.addEventListener("click", () => setCount(count() + 1));04 — Latência e SSR
O Solid suporta SSR, streaming SSR e Suspense. O compilador combinou SSR síncrono, streaming e assíncrono num mesmo output, com uma abordagem de Async SSR não-reativa que é mais simples e rápida. Reutilização de strings estáticas nos templates rende 5–8% de ganho onde há muitas linhas.
A latência percebida pelo usuário é favorecida pelo bundle menor: 7,6KB de framework significa Time-to-Interactive mais rápido mesmo antes de qualquer otimização de conteúdo.
05 — Suporte da comunidade
Ryan Carniato, atualmente Principal Engineer para Open Source na Netlify, desenvolve o modelo reativo do Solid há mais de uma década. O Discord oficial tem o time core ativo. A versão 1.9.13 saiu em maio de 2026. O SolidStart 1.3 é o meta-framework estável.
A maior limitação de suporte não é qualidade — é quantidade: se você trava num edge case específico, é possível que não haja uma resposta pronta no Stack Overflow.
Casos de uso: onde o SolidJS realmente entrega
✅ Use SolidJS para
Dashboards e visualizações em tempo real: atualizações a 60fps — gráficos de métricas, orderbooks, telemetria de IoT. A reatividade fina atualiza apenas o nó DOM do valor que mudou, sem re-renderizar o painel inteiro.
Widgets embarcados em outros sistemas: o bundle de 7,6KB torna o Solid ideal para componentes que vivem dentro de páginas que já têm seu próprio stack. Chat widget, player de vídeo, form de checkout — sem carregar 45KB de runtime externo.
Apps com requisitos rigorosos de performance: jogos 2D no browser, editores ricos, tabelas com milhares de linhas atualizando em tempo real.
Projetos novos com time aberto a aprender: JSX, TypeScript, Vite — tudo familiar. O que muda é o modelo mental.
❌ Evite quando
A biblioteca que você precisa não existe para Solid: Rich text editors (Lexical, TipTap), bibliotecas de animação (Framer Motion), charting libraries específicas — verifique antes.
Prioridade é contratação ou onboarding rápido: o mercado de trabalho para SolidJS é mínimo. Se o plano inclui contratar devs frontend rapidamente, React reduz drasticamente o custo de onboarding.
SolidStart: o meta-framework
O SolidStart 1.3 é o equivalente do Next.js para Solid: routing baseado em arquivos, SSR, server functions e form actions.
// src/routes/contato.tsx — SolidStart 1.ximport { createAsync, action, redirect } from "@solidjs/router";import { getContatos } from "~/lib/db";// Server function — roda só no servidorconst enviarMensagem = action(async (formData: FormData) => { "use server"; const nome = formData.get("nome") as string; await salvarMensagem({ nome, ts: Date.now() }); return redirect("/obrigado");});// Componente isomórfico — SSR + hidratação no clienteexport default function Contato() { const contatos = createAsync(() => getContatos()); return ( <main> <h1>Contato</h1> <form action={enviarMensagem} method="post"> <input name="nome" required /> <button type="submit">Enviar</button> </form> <ul> {contatos()?.map(c => <li>{c.nome}</li>)} </ul> </main> );}SolidJS com LLMs — chats, pipelines editoriais e loops de agentes
Por que a reatividade fina importa para apps de IA
Toda interface de chat com LLM resolve o mesmo problema: um token chega a cada poucos milissegundos via Server-Sent Events (SSE), e a UI precisa acrescentá-lo ao texto em exibição sem redesenhar nada ao redor.
Cada token novo dispara um setState.
O componente re-renderiza completamente.
Virtual DOM faz diff da string inteira.
Aplica diferenças no DOM após reconciliação.
500 tokens geram 500 ciclos de reconciliação.
Cada token novo atualiza um signal.
Apenas um nó de texto no DOM muda.
Não há re-renderização completa.
Atualização pontual e eficiente.
Reduz processamento em interfaces de chat.
Em React, cada token novo dispara um setState, o componente re-renderiza, o Virtual DOM faz o diff da string inteira e aplica a diferença. Para 500 tokens em 30 segundos, isso é 500 ciclos de reconciliação numa mesma conversa aberta.
Em Solid, o token novo atualiza um signal — um único nó de texto no DOM muda, sem mais nada.
O mesmo argumento se multiplica em pipelines editoriais com múltiplos agentes rodando em paralelo, onde cada etapa (pesquisa, rascunho, revisão, SEO) emite tokens independentemente. Manter o estado de cada passo em signals separados significa que o progresso de um agente não causa nenhum custo nos demais.
Chat com streaming token a token
import { createSignal, createEffect, For, onCleanup } from "solid-js";type Message = { role: "user" | "assistant"; content: string };function ChatLLM() { const [mensagens, setMensagens] = createSignal<Message[]>([]); const [streamAtual, setStreamAtual] = createSignal(""); const [carregando, setCarregando] = createSignal(false); const enviar = async (texto: string) => { setMensagens(m => [...m, { role: "user", content: texto }]); setCarregando(true); setStreamAtual(""); const res = await fetch("/api/chat", { method: "POST", body: JSON.stringify({ mensagens: mensagens() }), headers: { "Content-Type": "application/json" }, }); const reader = res.body!.getReader(); const decoder = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; const chunk = decoder.decode(value, { stream: true }); for (const linha of chunk.split("\n\n")) { if (!linha.startsWith("data: ")) continue; const token = linha.slice(6); if (token === "[DONE]") break; // Signal acumula → APENAS o nó de texto do assistente atualiza setStreamAtual(prev => prev + token); } } setMensagens(m => [...m, { role: "assistant", content: streamAtual() }]); setStreamAtual(""); setCarregando(false); }; return ( <div class="chat"> <For each={mensagens()}> {(msg) => ( <div class={`msg msg--${msg.role}`}>{msg.content}</div> )} </For> {/* Só este nó de texto atualiza a cada token */} {carregando() && <div class="msg msg--assistant streaming">{streamAtual()}</div>} <input onKeyDown={(e) => e.key === "Enter" && enviar(e.currentTarget.value)} /> </div> );}✅ Por que importa:
setStreamAtualé chamado centenas de vezes por resposta. Em React, cada chamada re-renderiza o componente inteiro — incluindo a lista de mensagens anteriores. Em Solid, apenas o nó de texto do bloco de streaming atualiza.
Pipeline editorial com loop de agentes
Um pipeline editorial típico encadeia agentes: pesquisa → rascunho → revisão editorial → SEO → publicação. Cada etapa pode demorar 10–60 segundos e emite tokens independentemente. Cada agente tem seu próprio signal — atualizações completamente isoladas.
Pesquisa → Rascunho → Revisão → SEO → Publicar ↓ ↓ ↓ ↓ ↓ signal signal signal signal signal ↓ ↓ ↓ ↓ ↓DOM node DOM node DOM node DOM node DOM nodeCada signal atualiza seu próprio nó DOM — sem interferência entre etapas.
import { createSignal, createMemo, Show } from "solid-js";type EtapaStatus = "idle" | "rodando" | "feito" | "erro";function PipelineEditorial() { // Cada agente tem seu próprio signal — completamente isolados const [pesquisa, setPesquisa] = createSignal({ tokens: "", status: "idle" as EtapaStatus }); const [rascunho, setRascunho] = createSignal({ tokens: "", status: "idle" as EtapaStatus }); const [revisao, setRevisao] = createSignal({ tokens: "", status: "idle" as EtapaStatus }); const [seo, setSeo] = createSignal({ tokens: "", status: "idle" as EtapaStatus }); // Memo derivado — só recalcula quando qualquer etapa muda const progresso = createMemo(() => { const etapas = [pesquisa(), rascunho(), revisao(), seo()]; return etapas.filter(e => e.status === "feito").length; }); const rodarEtapa = async ( setter: (v: (prev: any) => any) => void, endpoint: string, payload: object ) => { setter(prev => ({ ...prev, status: "rodando" })); const res = await fetch(endpoint, { method: "POST", body: JSON.stringify(payload), headers: { "Content-Type": "application/json" }, }); const reader = res.body!.getReader(); const dec = new TextDecoder(); while (true) { const { done, value } = await reader.read(); if (done) break; // Apenas o signal desta etapa atualiza — os outros não são tocados setter(prev => ({ ...prev, tokens: prev.tokens + dec.decode(value) })); } setter(prev => ({ ...prev, status: "feito" })); }; const iniciarPipeline = async (tema: string) => { await rodarEtapa(setPesquisa, "/api/agent/pesquisa", { tema }); await rodarEtapa(setRascunho, "/api/agent/rascunho", { pesquisa: pesquisa().tokens }); await rodarEtapa(setRevisao, "/api/agent/revisao", { rascunho: rascunho().tokens }); await rodarEtapa(setSeo, "/api/agent/seo", { texto: revisao().tokens }); }; return ( <div class="pipeline"> <p>Etapas concluídas: {progresso()} / 4</p> <button onClick={() => iniciarPipeline("IA generativa em 2026")}>Iniciar</button> <Etapa titulo="🔍 Pesquisa" dados={pesquisa()} /> <Etapa titulo="✍️ Rascunho" dados={rascunho()} /> <Etapa titulo="📝 Revisão" dados={revisao()} /> <Etapa titulo="🔖 SEO" dados={seo()} /> </div> );}SolidJS vs Next.js para apps com agentes de IA
SDKs de LLM são agnósticos de framework
SDKs de LLM são TypeScript puro — funcionam em qualquer ambiente JS. Vercel AI SDK (streamText, generateText, generateObject), Firebase Genkit, LangChain.js, SDK da Anthropic, OpenAI SDK: todos rodam em SolidJS, Next.js, SvelteKit ou Vanilla JS sem modificação.
O que é React-específico são apenas os hooks de UI — useChat, useCompletion, useAssistant. Em Solid, você substitui esses hooks por signals. A lógica de negócio e a chamada ao LLM permanecem idênticas.
Comparativo técnico
Critério | Next.js (App Router) | SolidJS + SolidStart |
|---|---|---|
Custo por token recebido via SSE | Re-render do componente + diff Virtual DOM | Atualização do nó de texto via signal — O(1) ✅ |
Estado de múltiplos agentes paralelos | useState por agente → re-renders cascata | Signal por agente → atualizações isoladas ✅ |
Streaming de server functions | React Server Components com streaming nativo | Server functions + createAsync / SSE |
Server-Side Rendering inicial | Maduro, bem documentado | Funcional e estável, menos mileagem |
SDKs de LLM | Mesmo ecossistema TypeScript | Mesmo ecossistema TypeScript |
Bundle do framework | ~45KB + Next.js runtime | ~7,6KB core ✅ 6× menor |
Componentes de UI para chat | shadcn/ui, Radix — prontos para React | Kobalte (port Radix), Solid UI — menor seleção |
Dashboards com 10K+ rows | Otimização manual com useMemo | Nativo via reatividade fina ✅ 2× mais rápido |
Contratação / onboarding | Mercado maduro | Especialistas escassos |
O mesmo chat — Next.js e SolidJS lado a lado
Next.js — hook useChat (React-específico):
// Next.js App Router — "use client"import { useChat } from "ai/react"; // hook React — não funciona no Solidexport default function Chat() { const { messages, input, handleInputChange, handleSubmit } = useChat(); // Cada token → re-render do componente inteiro return ( <div> {messages.map(m => <div key={m.id}>{m.content}</div>)} <form onSubmit={handleSubmit}> <input value={input} onChange={handleInputChange} /> <button type="submit">Enviar</button> </form> </div> );}SolidJS — mesmo SDK, camada de UI com signals:
// SolidJS — streamText do Vercel AI SDK funciona aqui sem modificaçãoimport { createSignal, For } from "solid-js";import { streamText } from "ai"; // ← mesmo SDK, sem modificaçãoimport { anthropic } from "@ai-sdk/anthropic";export default function Chat() { const [msgs, setMsgs] = createSignal([]); const [stream, setStream] = createSignal(""); const enviar = async (texto) => { setMsgs(m => [...m, { content: texto }]); // streamText é agnóstico — funciona em qualquer JS runtime const result = await streamText({ model: anthropic("claude-sonnet-4-6"), prompt: texto, }); for await (const delta of result.textStream) { // Apenas o nó de texto do stream atualiza — sem re-render setStream(s => s + delta); } setMsgs(m => [...m, { content: stream() }]); setStream(""); }; return ( <div> <For each={msgs()}>{(m) => <div>{m.content}</div>}</For> {stream() && <div>{stream()}</div>} <input onKeyDown={e => e.key === "Enter" && enviar(e.currentTarget.value)} /> </div> );}Por qual cenário escolher
Cenário | Escolha | Por quê |
|---|---|---|
Dashboard de monitoramento de agentes em tempo real | SolidJS | Dezenas de agentes com tokens em paralelo — O(1) por update |
Pipeline editorial com UI de progresso granular | SolidJS | 5 signals isolados vs. Zustand + memoização manual |
Chat como feature de produto React/Next.js existente | Next.js |
|
SaaS com SEO + blog + dashboard + chat | Next.js | RSC, amplo ecossistema, meta-framework mais maduro |
💡 A diferença real: A escolha entre Solid e Next.js para apps de LLM não é sobre qual SDK de IA você pode usar — ambos têm acesso ao mesmo ecossistema TypeScript. A diferença está em dois pontos: (1) modelo de renderização — Solid atualiza o nó de texto do token com O(1); (2) maturidade de meta-framework — Next.js tem RSC, mais adapters de deploy e ecossistema de UI mais amplo.
Ecossistema — Skills disponíveis para SolidJS
O diretório oficial lista mais de 220 pacotes em 10 categorias: 22 primitivos, 4 routers, 23 pacotes de dados, 5 de visualização, 82 de UI, 35 plugins, 9 starters, 21 build utilities, 22 add-ons e 3 de testing.
Pacotes oficiais — o núcleo
Pacote | O que resolve | Instalar |
|---|---|---|
| Core — signals, memos, effects, stores, controle de fluxo ( |
|
| Routing declarativo com lazy loading, nested routes, preload, |
|
| Meta-framework completo — SSR, file-based routing, server functions, streaming, deploy adapters (Vercel, Netlify, Cloudflare, Node) |
|
| Gerenciamento de |
|
| Plugin Vite oficial — transforma JSX Solid, HMR, SSR mode, dev tools integration |
|
UI headless e design systems
Componentes sem estilo — você traz o CSS. A filosofia é a mesma do Radix UI no ecossistema React: acessibilidade e comportamento prontos, aparência totalmente sua.
@kobalte/core — 1.700+ ⭐
Componentes headless nativos do Solid: Accordion, AlertDialog, Combobox, DatePicker, Select, Tabs, Toast, Tooltip e mais. Base do Solid UI (port do shadcn). WAI-ARIA completo, foco e teclado gerenciados.
npm i @kobalte/corecorvu
Primitivos headless nativos Solid com foco em customização granular: Drawer, Dialog, Tooltip, Disclosure, Popover. Fornece createFocusTrap, createPreventScroll como utilitários reutilizáveis. Plugin Tailwind + UnoCSS incluídos.
npm i corvu@ark-ui/solid — multi-framework
45+ componentes headless baseados em state machines (Zag.js). Suporta Solid, React, Vue e Svelte. Battle-tested na Chakra UI, usado por OVHCloud e PluralSight. v5.37 publicada recentemente. Totalmente type-safe.
npm i @ark-ui/solidSolid UI — port do shadcn/ui
solid-ui.com — port não-oficial do shadcn/ui + tremor-raw para Solid, construído sobre Kobalte e corvu, estilizado com Tailwind CSS. Filosofia de ownership: você copia o componente, ele é seu. Mais de 1.300 estrelas no GitHub. Não é um pacote npm — você copia e cola os componentes.
Solid Primitives — utilitários reativos
Gerenciado por membros do time core mas mantido separado do core para iteração independente. O objetivo é envolver funcionalidades de cliente e servidor numa camada de API totalmente reativa. Cada primitivo é tree-shakable individualmente.
// Instale só o que precisar — cada pacote é independenteimport { createIntersectionObserver } from "@solid-primitives/intersection-observer";import { createDebounce } from "@solid-primitives/scheduled";import { createGeolocation } from "@solid-primitives/geolocation";import { createLocalStorage } from "@solid-primitives/storage";import { createResizeObserver } from "@solid-primitives/resize-observer";import { createEventListener } from "@solid-primitives/event-listener";import { createKeyHold } from "@solid-primitives/keyboard";import { makeTimer, createCountdown } from "@solid-primitives/timer";// Exemplo: debounce de busca + intersection para lazy-loadfunction BuscaLazy() { const [query, setQuery] = createSignal(""); const [ref, setRef] = createSignal(null); const debouncedQuery = createDebounce((v) => setQuery(v), 300); createIntersectionObserver(ref, ([entry]) => { if (entry.isIntersecting) carregarMais(); }); return ( <div> <input onInput={(e) => debouncedQuery(e.currentTarget.value)} /> <div ref={setRef}>sentinela de scroll</div> </div> );}Dados e server state
Pacote | Caso de uso | Observação |
|---|---|---|
| Data fetching integrado ao router com cache por chave, deduplicação e revalidação. O caminho canônico em SolidStart — zero dependências extras | ✅ Recomendado para SolidStart |
| Port completo do TanStack Query. Suporta | Use quando precisar de polling ou recursos avançados |
| Port do TanStack Table — sorting, filtering, pagination, virtualização. Dados como stores, colunas reativas | Ideal para grids de dados pesados |
⚠️ Atenção ao usar
@tanstack/solid-query: o retorno das primitives é um store (não um objeto), e suas propriedades só são rastreadas em contexto reativo. Não desestruture o resultado fora de um tracking scope.
Formulários
Formulários são o caso onde a reatividade fina do Solid mais brilha: validar um campo em tempo real sem re-renderizar o resto do formulário é O(1) aqui, não uma otimização que você precisa implementar.
@modular-forms/solid — Validação field-level: só o campo com erro re-avalia. Bundle mínimo por design modular (tree-shaking por feature). Integra com Zod, Valibot, Arktype.
npm i @modular-forms/solid@gapu/formix — API flexível para estado complexo de formulário. Alternativa ao modular-forms com API mais familiar para quem vem do React Hook Form.
npm i @gapu/formixTesting
Pacote | O que faz | Notas |
|---|---|---|
| Port do Testing Library para Solid — renderiza componentes em DOM real (jsdom/happy-dom), queries por role/text/label, fire events, async utilities | Recomendado pelo core team junto com Vitest |
| Test runner oficial recomendado. Integra nativamente com Vite, suporte a JSX Solid sem configuração extra, watch mode rápido | Adicione |
| Permite rodar e testar código Solid no Node.js via Jest — alternativa para projetos que já usam Jest | Prefira Vitest em projetos novos |
| Extension Chrome + biblioteca de dev tools: visualiza o grafo reativo em tempo real, inspeciona signals, stores e componentes | Só dev — não impacta bundle de produção |
Styling, animação e DnD
Pacote | O que faz |
|---|---|
| Animações de entrada/saída inspiradas no Vue Transition. |
| Drag-and-drop e reordenação de listas — primitivos reativos para sortable lists, kanban boards e tree views |
| CSS-in-JS no estilo styled-components — tagged template literals, theming, SSR-safe |
| Coleção de ícones (fork do Feather Icons) compilados como componentes Solid — tree-shakable, sem SVG sprite |
| HMR para Solid em múltiplos bundlers (Vite, Webpack, esbuild). Mantém o estado reativo durante o reload de módulos |
Stack mínimo para produção — do zero à produção
# 1. Scaffold com SolidStart (meta-framework completo)npx create-solid@latest meu-appcd meu-app && npm install# 2. UI headless com acessibilidadenpm install @kobalte/core # componentes headless nativos# ou: npm install @ark-ui/solid # multi-framework, mais componentes# 3. Formulários — escolha umnpm install @modular-forms/solid # field-level validation, bundle mínimo# 4. Server state — escolha um# Opção A: nativo do SolidStart (zero deps extras)# import { query, createAsync } from "@solidjs/router"# Opção B: TanStack Query (polling, retries, devtools)npm install @tanstack/solid-query# 5. Primitivos utilitários (instale só os que precisar)npm install @solid-primitives/scheduled # debounce, throttlenpm install @solid-primitives/intersection-observer # lazy loadnpm install @solid-primitives/storage # localStorage reativo# 6. Testingnpm install -D vitest @solidjs/testing-library happy-dom# 7. Dev tools (só development)npm install -D solid-devtools⚠️ O que ainda falta: O ecossistema tem lacunas reais em comparação com React — rich text editors (sem port do Lexical ou TipTap), bibliotecas de animação complexa (sem port do Framer Motion — use
solid-transition-group+ Web Animations API), mapas (use wrappers de Leaflet/Mapbox vanilla). Para gráficos de dados: D3 funciona diretamente com Solid (acesso ao DOM nativo), e há wrappers comosolid-apexchartsesolid-recharts, mas com menos manutenção que os equivalentes React. Sempre verifique em solidjs.com/ecosystem antes de assumir que algo não existe.
Solid 2.0 — o próximo capítulo
O roadmap do Solid 2.0 (GitHub Discussion #2425) é ambicioso:
Pull-based run-once SSR — nova arquitetura de server-side rendering
Concurrent transitions — atualizações de UI mais suaves durante operações assíncronas
Self-healing error boundaries — recuperação de erros mais resiliente
Immutable diffable stores — primitivos de state management melhorados
Automatic batching — atualizações de signals agrupadas para performance ótima
Lazy memos e derived signals — valores computados mais eficientes
createAsynccomo primitivo padrão — abordagem recomendada para data fetching async
O Solid 2.0 Beta pulou a fase Alpha planejada — o criador Ryan Carniato observou que "a maioria dos marcos dentro do Alpha não parece relevante o suficiente para justificar sua própria fase".
TC39 Signals — a proposta que vai além do Solid
O modelo que o SolidJS popularizou está sendo padronizado na linguagem. Mantenedores de Angular, Vue, Svelte, Solid, Preact, Qwik, MobX, Ember, RxJS e mais colaboram numa proposta TC39 para adicionar signals ao JavaScript. Já está em Stage 1, com um polyfill disponível.
// A proposta do TC39: signals na linguagem, sem frameworkconst count = new Signal.State(0);const double = new Signal.Computed(() => count.get() * 2);count.set(1);double.get(); // 2O que começou como a filosofia central do Solid pode se tornar uma primitiva nativa do JavaScript.
Alinhando ao negócio — a decisão técnica
SolidJS não é a escolha segura. É a escolha certa para um conjunto específico de condições — e a escolha errada para outro conjunto igualmente específico.
Se o seu produto compete em tempo de carregamento, taxa de frame, latência de interação ou tamanho de bundle, SolidJS entrega vantagem mensurável. A reatividade fina não é marketing: é um modelo que provadamente gera menos trabalho por atualização.
Se o seu produto compete em velocidade de shipping, tamanho de time, facilidade de contratação ou breadth de integrações com terceiros, React ainda é a resposta para a maioria dos casos.
Use SolidJS quando
Performance de renderização é critério de produto mensurável
Bundle size importa (apps embarcadas, mobile mid-range, TV)
Atualizações de UI são frequentes e granulares (tempo real, 60fps)
Aplicações de LLM com múltiplos agentes emitindo tokens em paralelo
Time já conhece React e está aberto ao novo mental model
Você está construindo algo novo com liberdade de escolha de stack
As bibliotecas que você precisa têm versão Solid disponível
Considere outra opção quando
Contratação e onboarding rápido são prioridade — vá para React
Você depende de bibliotecas UI sem port para Solid (Framer Motion, Lexical…)
O time nunca teve contato com reatividade fina — curva tem custo real
SolidStart ainda não tem o adapter de deploy que você precisa
Performance não está nos seus OKRs — otimize onde dói
"SolidJS prova que o Virtual DOM foi uma solução de transição. Se seus usuários sentem a diferença — use Solid. Se não sentem, sua stack atual provavelmente já é boa o suficiente."
Fontes e dados — Jun 2026
solidjs.com / docs.solidjs.com — documentação oficial, primitivos, fine-grained reactivity, changelog
InfoQ (mai/2026) — "SolidJS 2.0 Beta: First-Class Async, Reworked Suspense and Deterministic Batching"
Tomas Listiak / listiak.dev (fev/2026) — "The State of Solid.js in 2026" — dados de bundle (7,6KB), casos de uso empresariais (Radware, Jolt AI)
PkgPulse Guides (mar/2026) — comparativos React vs SolidJS e SolidJS vs Svelte, downloads npm (1,49M–2,41M/semana), crescimento 60% a/a
SoloDevStack (mai/2026) — dados de versões (solid-js 1.9.13, SolidStart 1.3.2)
GitHub solidjs/solid — Discussion #2425 — roadmap oficial do Solid 2.0
npmjs.com/package/solid-js — descrição oficial, integrações, suporte a ambientes
Zylos Research (mar/2026) — "LLM Output Streaming and Real-Time Token Delivery Architectures" — SSE como padrão para agentes, MCP/A2A
GitHub peerreynders/solid-start-sse-chat — implementação de referência de chat SSE em SolidStart
BCMS Blog (fev/2026) — "Top 10 Next.js Alternatives in 2026" — SolidStart "2x mais rápido em dashboards com 10K+ rows"
Toptal (mai/2026) — "SolidJS vs React: The Go-to Guide" — comparativo meta-framework
solidjs.com/ecosystem — diretório oficial (220+ pacotes em 10 categorias)
kobalte.dev, corvu.dev, solid-ui.com — documentação dos principais pacotes de UI
tanstack.com/query/solid — documentação oficial do TanStack Query para Solid (v5.100+)
github.com/solidjs-community/solid-primitives — documentação e catálogo dos Solid Primitives
Dados de downloads, versões e posições de benchmark refletem junho de 2026. O Solid 2.0 está em beta — a API pode mudar antes do release estável. Dados de empresas (Radware, Jolt AI) são reportados pelo ecossistema, não verificados de forma independente. O dado "2x mais rápido para dashboards com 10K+ rows" é reportado por BCMS em comparativo com Next.js. Compare live em pkgpulse.com e framework-benchmarks.as93.net antes de decidir.


