Wir haben die gleiche App in SolidJS und React gebaut: Signals vs Hooks
Im letzten Quartal hatten wir ein Client-Projekt, das uns die perfekte Gelegenheit gab, etwas zu tun, das wir schon lange ausprobieren wollten: Dieselbe Anwendung sowohl in SolidJS als auch in React zu erstellen und dann alles zu vergleichen. Nicht eine Todo-App. Nicht ein Counter. Ein echtes Production-Dashboard mit Authentifizierung, Echtzeit-Datenupdates, komplexen Formularen und einem Chart-Modul, das Tausende von Datenpunkten rendert.
Die Ergebnisse überraschten uns. Nicht, weil ein Framework "gewonnen" hat -- sondern weil die Tradeoffs weit nuancierter waren, als der Twitter-Diskurs suggeriert. Einiges haben wir erwartet. Einiges hat uns völlig überrascht. Das ist, was wir wirklich gelernt haben.
Inhaltsverzeichnis
- Die App, die wir gebaut haben
- Signals vs Hooks: Ein Mentalitätswechsel
- Bundle-Size-Vergleich
- Rendering Performance Benchmarks
- Developer Experience und Ökosystem
- Production Tradeoffs, die wirklich zählen
- Wann man SolidJS gegenüber React wählen sollte
- Code-Vergleich: Echte Patterns
- FAQ

Die App, die wir gebaut haben
Die Anwendung ist ein Echtzeit-Analytics-Dashboard für einen E-Commerce-Kunden. Hier ist, was es enthält:
- Authentifizierungsflow mit JWT-Tokens und Refresh-Logik
- Dashboard mit 6 Widget-Panels, die jeweils Daten von verschiedenen API-Endpoints abrufen
- Echtzeit-Order-Feed mit WebSocket-Verbindungen
- Interaktive Charts mit Rendering von 5.000+ Datenpunkten (unter Verwendung einer Chart-Bibliothek)
- Komplexe Filter-Formulare mit abhängigen Dropdowns und Date-Range-Pickern
- Admin-Settings-Panel mit verschachteltem State Management
- Responsives Layout mit Sidebar-Navigation
Beiden Versionen verbinden sich mit derselben Backend-API. Beide verwenden TypeScript. Beide verwenden Vite als Build-Tool. Wir hielten Drittanbieter-Abhängigkeiten so ähnlich wie möglich -- dieselbe Chart-Bibliothek (Chart.js), derselbe HTTP-Client (ky), derselbe WebSocket-Wrapper.
Die React-Version verwendet React 19 mit Hooks. Die SolidJS-Version verwendet Solid 1.9. Wir verwendeten keine Meta-Frameworks (kein Next.js, kein SolidStart), da wir die Framework-Unterschiede isolieren wollten, ohne dass Routing und SSR den Vergleich verwässert.
Signals vs Hooks: Ein Mentalitätswechsel
Das ist das Wichtigste. Und ehrlich gesagt, brauchte unser Team etwa eine Woche, um aufzuhören, React-förmigen Code in SolidJS zu schreiben.
Wie React Hooks funktionieren
Du kennst das, aber es ist erwähnenswert, es ausdrücklich für den Vergleich zu erwähnen. Reacts Modell ist: Wenn sich der State ändert, wird die Component-Funktion neu ausgeführt. Die gesamte Funktion. Jeder useState, jeder useMemo, jeder useCallback -- sie sind alle Mechanismen, um um die Tatsache herum zu arbeiten, dass die ganze Funktion neu ausgeführt wird.
// React: Diese gesamte Funktion wird bei jeder State-Änderung neu ausgeführt
function OrderFeed() {
const [orders, setOrders] = useState([]);
const [filter, setFilter] = useState('all');
// Dies wird bei jedem Render neu berechnet, es sei denn, wir memoisieren
const filteredOrders = useMemo(() =>
orders.filter(o => filter === 'all' || o.status === filter),
[orders, filter]
);
// Diese Ref wird konzeptionell bei jedem Render neu erstellt
const handleNewOrder = useCallback((order) => {
setOrders(prev => [order, ...prev]);
}, []);
useEffect(() => {
const ws = connectWebSocket(handleNewOrder);
return () => ws.close();
}, [handleNewOrder]);
return <OrderList orders={filteredOrders} />;
}
Wie Solid Signals funktionieren
Solids Modell ist fundamental unterschiedlich. Die Component-Funktion wird einmal ausgeführt. Danach werden nur die spezifischen Ausdrücke, die ein Signal lesen, neu ausgeführt, wenn sich dieses Signal ändert. Es gibt keinen Virtual DOM Diff. Es gibt keine Reconciliation. Der reaktive Graph verfolgt genau, welche DOM-Knoten von welchen Signals abhängen.
// Solid: Diese Funktion wird EINMAL ausgeführt
function OrderFeed() {
const [orders, setOrders] = createSignal([]);
const [filter, setFilter] = createSignal('all');
// Dies wird automatisch verfolgt -- kein Dependency-Array erforderlich
const filteredOrders = createMemo(() =>
orders().filter(o => filter() === 'all' || o.status === filter())
);
// Kein useCallback erforderlich -- dieser Closure ist stabil
const handleNewOrder = (order) => {
setOrders(prev => [order, ...prev]);
};
// onMount anstatt useEffect mit leeren Deps
onMount(() => {
const ws = connectWebSocket(handleNewOrder);
onCleanup(() => ws.close());
});
return <OrderList orders={filteredOrders()} />;
}
Was das in der Praxis bedeutet
Die Solid-Version hat keine Dependency-Arrays. Kein useCallback. Kein useMemo für abgeleiteten State (obwohl createMemo existiert für teure Berechnungen -- der Unterschied ist, dass es Opt-in für Performance ist, nicht erforderlich für Korrektheit).
Hier ist, was uns während der Entwicklung getroffen hat:
Props zu destructurieren, zerstört die Reaktivität in Solid. Wir hatten einen Junior-Developer, der Props in einer Solid-Component destructurierte, und wir verbrachten 45 Minuten damit zu debuggen, warum Updates nicht propagiert wurden. In React ist Destructuring in Ordnung, da die ganze Funktion neu ausgeführt wird. In Solid müssen Sie
props.valueinnerhalb der JSX oder eines tracked Scope zugreifen.Early Returns sind knifflig in Solid. Du kannst nicht
if (!data()) return <Loading />am Anfang einer Solid-Component tun, wie du es in React würdest. Die Component-Funktion wird nur einmal ausgeführt, daher würde dieser Conditional nie neu evaluiert. Du brauchst<Show when={data()}>stattdessen.Keine Stale Closure Bugs. Das war der große Sieg. In unserer React-Version hatten wir drei separate Stale Closure Bugs in der ersten Woche, die mit WebSocket-Handlern zusammenhingen, die alten State erfassten. Die Solid-Version hatte null, da Signals immer zum Zugriffszeit gelesen werden, nicht in einem Closure erfasst.
Bundle-Size-Vergleich
Wir haben beide Production-Builds mit der exakt gleichen Vite-Konfiguration, gzip-Kompression und Code-Splitting-Strategie gemessen.
| Metrik | React 19 | SolidJS 1.9 | Unterschied |
|---|---|---|---|
| Framework Runtime | 44,2 KB (gzip) | 7,1 KB (gzip) | -84% |
| Gesamt Initial Bundle | 127,8 KB | 89,3 KB | -30% |
| Gesamt App (alle Chunks) | 312,4 KB | 274,1 KB | -12% |
| Erster Chunk (kritischer Pfad) | 68,4 KB | 41,2 KB | -40% |
| Anzahl der Chunks | 14 | 14 | Gleich |
Solids Runtime ist dramatisch kleiner. Das ist keine Neuigkeit -- Ryan Carniato hat darüber ausführlich gesprochen. Aber was uns überraschte, war, dass der Gesamtumsatz der App Unterschied sich deutlich verengte, sobald Du echten Application Code, Drittanbieter-Bibliotheken und Assets hinzufügst.
Die Framework Runtime ist am wichtigsten für das Initial Load. Und mit 7,1 KB gzipped verschwindet Solid praktisch in die Luft. Reacts 44 KB ist merklich, besonders bei mobilen Verbindungen.
Tree Shaking
Solid Tree-Shakes besser als React. Ungenutzte Solid Primitives werden vollständig eliminiert. Mit React versandt der Reconciler und die Fiber-Architektur, egal ob Du alle ihre Features nutzt. Wir bestätigten dies durch das Bauen einer minimalen Seite in beide -- Solids Boden ist niedriger.

Rendering Performance Benchmarks
Wir führten strukturierte Benchmarks unter Verwendung von Chrome DevTools Performance Profiles, Lighthouse und Custom Timing Instrumentation durch. Alle Tests auf einem M2 MacBook Pro mit CPU Throttling auf 4x Slowdown gesetzt, um Mid-Range Geräte zu simulieren.
Chart Rendering (5.000 Datenpunkte)
| Metrik | React 19 | SolidJS 1.9 |
|---|---|---|
| Initial Render | 142ms | 89ms |
| Re-render bei Filter-Änderung | 67ms | 23ms |
| Speicher während des Render | 18,4 MB | 11,2 MB |
| Erstellte DOM-Knoten | 5.847 | 5.812 |
Solid war konsistent schneller bei Re-Renders, da es einen Virtual DOM Tree nicht diffed. Wenn sich ein Filter-Signal ändert, aktualisieren sich nur die Ausdrücke, die dieses Signal lesen. Reacts 19 Compiler-Verbesserungen halfen -- der gleiche Test auf React 18 war 95ms für Re-Renders -- aber Solid hatte immer noch einen klaren Vorteil.
Echtzeit Order Feed (100 Updates/Sekunde)
Hier wurde es wirklich interessant. Wir schickten 100 WebSocket-Nachrichten pro Sekunde in den Order Feed.
| Metrik | React 19 | SolidJS 1.9 |
|---|---|---|
| Frame Drops (pro 10s) | 12 | 2 |
| Durchschnittliche Paint-Zeit | 8,3ms | 3,1ms |
| Maximale Paint-Zeit | 34ms | 11ms |
| CPU-Auslastung (Durchschnitt) | 24% | 9% |
Solid zerschmetterte absolut diesen Benchmark. Hochfrequente Updates sind, wo Fine-Grained Reactivity die größten Dividenden auszahlt. React bündelte Updates (was gut ist), aber differenzierte immer noch mehr DOM als nötig auf jedem Batch.
Wir sollten anmerken: Reacts 19 useTransition und automatisches Batching machten dies viel besser als React 18 es gewesen wäre. Und für die meisten realen Apps pushst du nicht 100 Updates pro Sekunde. Bei 10 Updates/Sekunde waren beide Frameworks smooth.
Komplexes Formular mit 40 Feldern
| Metrik | React 19 | SolidJS 1.9 |
|---|---|---|
| Keystroke Input Lag | 2-4ms | <1ms |
| Form Submission Render | 28ms | 12ms |
| Component Re-Renders pro Keystroke | 3-8 | 1 |
In React würde die Eingabe in ein Feld dazu führen, dass Parent-Components neu rendern würden, es sei denn, wir memoisierten sorgfältig alles. In Solid, die Eingabe in ein Feld aktualisiert buchstäblich nur den DOM-Textknoten dieses Feldes. Nichts anderes wird neu ausgeführt.
Developer Experience und Ökosystem
Performance ist nicht alles. Du musst das Ding tatsächlich bauen, debuggen, dafür einstellen und warten.
Ökosystem-Größe (Stand früh 2025)
| Faktor | React | SolidJS |
|---|---|---|
| npm Wöchentliche Downloads | ~28M | ~85K |
| GitHub Stars | 233K+ | 33K+ |
| Stack Overflow Fragen | 470K+ | ~2K |
| UI-Komponenten-Bibliotheken | 50+ reife Optionen | 5-8 Optionen |
| Job Postings (LinkedIn US) | ~45.000 | ~200 |
| Meta-Framework | Next.js (reif) | SolidStart (Beta) |
Das ist der Elefant im Raum. Reacts Ökosystem ist um Größenordnungen größer. Als wir einen Date-Range-Picker für Solid brauchten, mussten wir entweder einen React portieren oder unseren eigenen schreiben. In React hatten wir 15 Optionen zur Auswahl.
Wir verwendeten Kobalte für zugängliche UI-Primitives in Solid, und es ist wirklich gut. Aber es ist kein Radix UI in Bezug auf Component-Abdeckung.
Debugging
React DevTools ist reif, gut gepflegt und etwas, das jeder Frontend-Dev kennt. Solid hat seine eigene DevTools-Extension, und sie ist ordentlich -- du kannst den Signal-Graph überprüfen, was eigentlich nützlicher ist, um Reaktivitäts-Bugs zu verfolgen als Reacts Component Tree-View. Aber es ist weniger poliert.
TypeScript Unterstützung
Beide sind ausgezeichnet. Solids TypeScript-Unterstützung ist eigentlich leicht besser für JSX, da der Compiler mehr zum Build-Zeit verarbeitet. Wir hatten weniger Type-Gymnastik in der Solid-Codebase.
Production Tradeoffs, die wirklich zählen
Nachdem wir beide Versionen gebaut und die Solid-Version auf Staging bereitgestellt haben (der Client wählte letztendlich React für Production -- mehr dazu unten), sind hier die Tradeoffs, die wirklich zählten:
Hiring
Unser Client hat ein Team von 8 Frontend-Entwicklern. Alle kennen React. Keiner hatte Solid verwendet. Trainings-Zeit-Schätzung: 2-3 Wochen für Kompetenz, 2-3 Monate für Meisterschaft. Das sind echte Kosten. Dies ist der einzelne größte Faktor in den meisten Production-Entscheidungen, und es ist der Grund, warum wir normalerweise React oder Frameworks wie Next.js für Teams empfehlen, die häufig einstellen müssen.
Drittanbieter-Bibliotheks-Kompatibilität
Wir mussten Custom Wrapper für drei Bibliotheken schreiben, die React-spezifische Integrationen hatten. Dies addierte etwa 20 Stunden Entwicklungszeit. In einem React-Projekt existieren diese Stunden nicht.
Server-Side Rendering
SolidStart ist vielversprechend, war aber während unseres Projekts noch in Beta. Next.js ist Battle-getestet. Für Projekte, bei denen wir Production-grade SSR mit allen Trimmings benötigen, greifen wir immer noch zu Next.js Development oder Astro, je nach Content-Modell.
Performance, wo es zählt
Hier ist die ehrliche Wahrheit: Für dieses spezielle Dashboard funktionierten beide Frameworks gut genug für Production. Die Solid-Version war messbar schneller, aber die React-Version war nie langsam. Nutzer würden den Unterschied in den meisten Interaktionen nicht bemerken.
Die Ausnahme war der Echtzeit-Feed bei hohen Update-Frequenzen. Wenn deine App einen Use-Case wie diesen hat, ist Solids Performance-Vorteil bedeutsam, nicht nur Benchmark-Prahlerei.
Wann man SolidJS gegenüber React wählen sollte
Nach diesem Experiment, hier ist unser ehrlicher Framework für die Entscheidung:
Wähle SolidJS, wenn:
- Deine App hochfrequente reaktive Updates hat (Dashboards, Trading-Plattformen, Echtzeit-Zusammenarbeit)
- Bundle-Größe ist kritisch (Embedded Widgets, Micro-Frontends, Mobile-First)
- Dein Team ist klein und bereit, in das Erlernen eines neuen Paradigmas zu investieren
- Du willst Fine-Grained Reactivity ohne gegen das Framework zu kämpfen
- Du baust etwas Neues und brauchst kein großes Component Library Ökosystem
Wähle React, wenn:
- Dein Team kennt bereits React (dies allein ist normalerweise entscheidend)
- Du brauchst ein reifes Meta-Framework (Next.js, Remix)
- Verfügbarkeit von Drittanbieter-Bibliotheken ist wichtig
- Du stellst ein und brauchst einen großen Talent Pool
- Deine Apps Performance-Anforderungen sind typisch (nicht extrem)
Für unsere Headless CMS Development Projekte dominiert React immer noch, weil CMS-Integrationen (Sanity, Contentful, Storyblok) SDKs erster Klasse für React haben. Solid-Unterstützung existiert, wird aber oft von der Community gepflegt.
Code-Vergleich: Echte Patterns
Schauen wir uns einige echte Patterns aus dem Projekt nebeneinander an.
Datenabruf mit Loading States
React:
function Dashboard() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetchDashboardData()
.then(setData)
.catch(setError)
.finally(() => setLoading(false));
}, []);
if (loading) return <Skeleton />;
if (error) return <ErrorBanner error={error} />;
return <DashboardGrid data={data} />;
}
SolidJS:
function Dashboard() {
const [data] = createResource(fetchDashboardData);
return (
<Suspense fallback={<Skeleton />}>
<ErrorBoundary fallback={(err) => <ErrorBanner error={err} />}>
<DashboardGrid data={data()} />
</ErrorBoundary>
</Suspense>
);
}
Solids createResource mit Suspense ist wirklich elegant. React hat auch Suspense (und es ist besser geworden in React 19), aber Solids Version fühlte sich natürlicher an zu nutzen. Weniger Boilerplate, weniger State-Variablen zu verwalten.
Bedingtes Rendering
React:
{user ? (
<Profile user={user} />
) : (
<LoginPrompt />
)}
SolidJS:
<Show when={user()} fallback={<LoginPrompt />}>
{(u) => <Profile user={u()} />}
</Show>
Solids <Show> Component existiert, weil Ternaries nicht auf die gleiche Weise funktionieren, wenn die Component-Funktion nur einmal ausgeführt wird. Es brauchte Gewöhnung, aber das Callback-Pattern gibt dir eine eingegrenzte, Non-Null Reference, was nett für TypeScript ist.
List Rendering
React:
{orders.map(order => (
<OrderRow key={order.id} order={order} />
))}
SolidJS:
<For each={orders()}>
{(order) => <OrderRow order={order} />}
</For>
Solids <For> braucht keine Keys, da es Array-Items nach Reference verfolgt. Wenn sich ein Item in dem Array bewegt, bewegt Solid den tatsächlichen DOM-Knoten. React würde unmounten und remounten. Dies ist der Grund, warum Solids List-Performance so gut ist.
FAQ
Ist SolidJS 2025 Production-Ready?
Ja. Solid 1.x ist seit über zwei Jahren stabil. Unternehmen wie Cloudflare und Samsung haben es in Production verwendet. Die Core-Bibliothek ist reif und gut getestet. Das Ökosystem darum (SolidStart, Component-Bibliotheken) ist kleiner als Reacts, aber wächst stetig. Die Frage ist nicht, ob Solid bereit ist -- es ist, ob dein Team und deine Projekt-Anforderungen mit seiner Ökosystem-Größe übereinstimmen.
Kann ich inkrementell von React zu SolidJS migrieren?
Nicht leicht. Trotz der ähnlichen JSX-Syntax sind die Runtime-Modelle fundamental unterschiedlich. Du kannst keine Solid-Components in einer React-App einbetten (oder umgekehrt) ohne iframe oder Web Component Grenzen. Eine Migration würde im Wesentlichen ein Rewrite sein. Wenn du es in Betracht ziehst, beginne mit einer neuen isolierten Feature oder Micro-Frontend, anstatt zu versuchen, existierenden React-Code zu konvertieren.
Unterstützt SolidJS Server-Side Rendering?
Ja. SolidStart bietet SSR, Streaming und Server-Funktionen. Es ist funktional und verbessert sich schnell, aber Stand früh 2025 ist es immer noch weniger reif als Next.js oder Remix. Für SSR-schwere Projekte würden wir immer noch empfehlen, Next.js oder Astro, je nach deinen Content-Anforderungen zu evaluieren.
Wie vergleicht sich Reacts 19 Compiler mit Solids Ansatz?
Reacts 19 Compiler (ehemals React Forget) memoize automatisch Components, um unnötige Re-Renders zu reduzieren. Es ist eine signifikante Verbesserung. Aber es arbeitet immer noch innerhalb Reacts Modell von Component-Funktionen, die neu ausgeführt und einen Virtual DOM diffed werden. Solid überspringt beide Schritte völlig. Der Compiler macht React schneller, aber es ändert nicht die fundamentale Architektur. In unseren Benchmarks war React 19 mit dem Compiler etwa 30% schneller als React 18, aber immer noch langsamer als Solid bei Update-schweren Szenarien.
Was ist mit Preact Signals als Mittelweg?
Preact Signals (und der @preact/signals-react Adapter) bringen Signal-ähnliche Reaktivität ins React-Ökosystem. Es ist ein interessanter Ansatz, aber er kämpft gegen Reacts Kernmodell, anstatt damit zu arbeiten. Wir testeten es kurz und fanden Edge Cases mit Suspense und Concurrent Features. Wenn du Signals willst, gibt Solid dir die volle Erfahrung ohne die Impedanz-Nichtübereinstimmung.
Ist SolidJS schwerer zu lernen als React?
Wenn du bereits React kennst, wird Solids API vertraut aussehen -- ähnliche JSX, ähnliche Patterns. Der schwere Teil ist, Reacts Mental Model zu verlernen. Du wirst nach useEffect Patterns greifen, die nicht existieren. Du wirst Props destructurieren und Reaktivität zerstören. Du wirst Early Returns probieren und dich fragen, warum sie nicht funktionieren. Budgetiere etwa 1-2 Wochen für einen erfahrenen React-Dev, um in Solid produktiv zu werden, und noch ein, zwei weitere Monate, um aufzuhören, React-förmiges Solid zu schreiben.
Welches Framework hat bessere TypeScript-Unterstützung?
Beide haben ausgezeichnete TypeScript-Unterstützung. Solid hat einen leichten Vorteil, da sein Compiler schnalere Typen in bestimmten Patterns bereitstellen kann (wie der Callback in <Show>), und du brauchst nicht die gleiche Lautstärke von generischen Type-Parametern, die komplexe React Hooks manchmal erfordern. Aber ehrlich gesagt, beide sind großartig. Dies sollte kein entscheidender Faktor sein.
Sollte ich SolidJS für mein nächstes Projekt verwenden?
Es hängt von deinen Einschränkungen ab. Wenn du ein kleines Team bist, das etwas Performance-Sensibles baut und bereit bist, in Lernkurve und Arbeit um ein kleineres Ökosystem zu investieren, ist Solid eine wirklich ausgezeichnete Wahl. Wenn du React-Developer einstellen musst, etablierte Component-Bibliotheken nutzen oder ein Battle-getestetes Meta-Framework für Production brauchst, ist React die sicherere Wette. Es gibt keine universelle Antwort -- nur die richtige Antwort für deine spezifische Situation. Wenn du die Entscheidung für dein Projekt durchdenken möchtest, kontaktiere uns und wir können dir helfen, die Tradeoffs zu evaluieren.