BLOG
Handwired: Das JS-Code direkt in ein neuronales Netzwerk umwandeln
Am 15. Oktober veröffentlichte der React-Teammitglied chenglou auf GitHub das Projekt handwired. Die erste Zeile des README lautet: „Verwandeln Sie Ihren normalen JavaScript-Code in ein neuronales Netzwerk; ohne Training, präzise und dennoch vollständig differenzierbar.“ Am 20. Oktober hatte der Repo bereits 1804★ Bewertungen erhalten, wobei die Beliebtheit hauptsächlich von GitHub Trending und sozialen Medien stammt. Das Projekt wurde in TypeScript geschrieben, unterliegt dem MIT-Licence-Abkommen und wird mit dem Build-Tool bun erstellt. Die Online-Demo findet sich unter chenglou.me/handwired, während die Lokalversion durch bun install && bun start gestartet werden kann. Dieser Artikel analysiert das Projekt in sechs Abschnitten.
Das Besondere an diesem Projekt ist, dass es nicht den alten Weg des „Training von Netzwerken zur Simulation von Programmen“ beschreitet, sondern umgekehrt: Zuerst wird das Programm geschrieben und anschließend in eine Form kompiliert, die vom neuronalen Netzwerk ausgeführt werden kann. Diese umgekehrte Vorgehensweise verwandelt das neuronale Netzwerk von einem „Lerner“ zu einem „Ausführer“.
1. Wer ist der Autor?
Der Autor, chenglou, ist ein bekannter GitHub-Entwickler und Mitglied des React-Teams. Dieses Mal veröffentlicht er handwired als persönliches Projekt. Aus den Experimentierprotokollen im Lab-Verzeichnis geht hervor, dass es bereits Anfang September tägliche Experimente gab und auch Diskussionen über die Entwicklung im Juni und Juli erwähnt wurden. Das bedeutet, dass vor der Öffentlichkeitveröffentlichung eine längere Vorbereitungsphase stattgefunden hat. Die intensive Zusammenstellung nach der Veröffentlichung sollte als „Langfristige Vorbereitung mit einmaliger Öffentlichkeit und kontinuierlicher Organisation“ verstanden werden, nicht als vollständige Projektdauer. Dieser Veröffentlichungsrhythmus ist in der Open-Source-Community nicht ungewöhnlich: Zuerst wird das Projekt privat weiterentwickelt, anschließend einmalig öffentlich gemacht, um mit sozialen Medien die anfängliche Aufmerksamkeit zu steigern.
In Bezug auf das Projektsize enthält der Kern-Repository unter dem Verzeichnis src/submodules Module wie runtime, handwiredos und json-search. Die Größe der wichtigen Dateien ist wie folgt: src/runtime/numeric-ui-core.ts ca. 152 KB, src/runtime/cells.ts ca. 22 KB, src/runtime/host-timing.ts ca. 21 KB. Insgesamt macht TypeScript 90,5% des Repos aus – es handelt sich dabei um ein vollständiges Projekt mit Dokumentation, Tests und Online-Demo, nicht nur um eine Gist-Einheit für Konzeptdemonstriertes. Das Ziel ist nicht, ein weiteres Frontend-Framework zu werden, sondern eine durchführbare Referenzimplementierung für das Konzept „Programm als Netzwerk“ bereitzustellen. Für Entwickler, die schnell Erfahrungen mit differentiable programming sammeln möchten, bietet dieser Repository einen direkten Ausgangspunkt zum Klonen, Ausführen und Ändern.
2. Mechanismenanalyse
Der Ausgangspunkt von handwired: Jedes Programm besteht im Grunde aus if-else-Bedingungen, Schleifen und Zuständen. Handwired versucht, diese drei Elemente in „Matrixmultiplikation + ReLU“ umzuwandeln, um sie auf Fließkommawerte anzuwenden.
Das Beispiel in dem README ist am einfachsten verständlich. Eine Abzweigung wie ((a > 4) ? 10 : 12) kann in reines Arithmetik umgewandelt werden:
above4 = max(0, a - 4) - max(0, a - 5) // Wenn a > 4, wert 1; sonst 0
result = above4 * 10 + (1 - above4) * 12 // Beide Abzweigungen werden berechnet, anschließend wird der Wert von above4 gewählt
Dabei ist max(0, x) das ReLU. Diese Kontrollstrukturen wie Vergleiche und Entscheidungen werden in Addition, Multiplikation und ReLU kodiert. Schleifen und Zustände funktionieren ähnlich: Die Zustände werden in eine Float32Array-Tabelle gespeichert, wobei jede Iteration die Tabelle liest, berechnet und zurückgibt.
Um den gesamten Compilierprozess zu verbinden, läuft handwired während der Konstruktion einmal ein normales JavaScript-Programm, um Makros wie emitMultiply und emitCompare in feste Anweisungen umzuwandeln. Während des Laufzeitbetriebs gibt es keine Abzweigungen oder Schleifen, nur die sequenzielle Berechnung dieser Fließkomma-Tabelle. Das bedeutet auch, dass der Ausführungspfad eines Programms, sobald es kompiliert ist, festgelegt ist. Die GPU kann dann eine große Anzahl von identischen Threads gleichzeitig auslösen, ohne während des Laufzeitbetriebs dynamische Abzweigungen verarbeiten zu müssen.
Als Nächstes erfolgt die Sammlung: Alle Additionen, Multiplikationen und ReLU-Abfolgen des Programms werden in eine große matmul-Operation eingebettet, die auf JS oder WebGPU ausgeführt wird. Da nur diese beiden Grundprinzipien verwendet werden, geben die README-Fehler drei Eigenschaften an: Das gesamte Programm bleibt stochastisch; die Gewichte sind handschriftlich und benötigen keine Trainierung; die bewährte Optimierungstechnologie der GPU eignet sich besonders gut für diese reduzierte Prinzipien.
Die Kerninnovation des Projekts besteht darin, dass es nicht darum geht, ein Netzwerk zu trainieren, um das Programm zu approximieren, sondern ein handschriftliches Programm exakt in die Form eines neuronalen Netzwerks zu kompilieren. Die Gewichte sind nicht das Produkt der Trainierung, sie sind das Programm selbst. Diese dreifache Zielsetzung von „ohne Trainierung, präzise, stochastisch“ wird durch die Wahl der Kompiliermethode erreicht. Mit anderen Worten: Hier scheint das neuronale Netzwerk eher eine Ausführungsform des Programms zu sein als eine approximative Funktion, die aus den Daten abgeleitet wird.
Der Wert dieser Herangehensweise liegt darin, dass sie die „Stochastizität“ vom Trainingsprozess auf den Kompilierprozess verlagert. Traditionelle neuronale Netze benötigen große Mengen an Daten und Backpropagation, um die Gewichte zu optimieren; handwired ermöglicht es hingegen, mit einer vertrauten Programmlogik ein definiertes Verhalten zu schreiben, bevor die Gradientenstruktur erhalten bleibt, damit sie bei Bedarf in den Optimierer eingefügt werden kann. Es will nicht das Training ersetzen, sondern die Grenze zwischen „Training“ und „Programm“ um einen Schritt nach hinten verschieben.
3. Engineering-Qualität
Aus der Struktur des Verzeichnisses geht hervor, dass src/ der Kern des Runtimes ist, lab/ experimentelle Projekte, template/ Vorlagen und docs/ Dokumentation. Der Runtime-Bereich besteht hauptsächlich aus Dateien wie cells, host-timing und numeric-ui-core. Unter diesen ist numeric-ui-core.ts mit etwa 152 KB der Hauptbestandteil des numerischen/UI-Runtimes.
Der Anteil von TypeScript im Repository beträgt 90,5%, was zeigt, dass es sich nicht um eine leichte Verpackung handelt, sondern um ein Projekt, in dem numerische Berechnungen, Animationen und Hostinteraktionen integriert sind. Die Dokumente in docs/ decken Modelle, Tutorials, Muster und Verhaltensauswahl ab und sind daher für Personen geeignet, die sich mit schreibbaren Programmiermethoden beschäftigen möchten. Diese hohe Engineering-Dichte zeigt auch, dass handwired nicht ein Produkt von einem oder zwei Tagen ist, sondern ein System, das durch mehrere Iterationen entstanden ist.
Aus Sicht der Abhängigkeiten hat handwired keine wichtigen Laufzeitfunktionen eingeführt. In package.json sind nur TypeScript, Test- und Lint-Werkzeuge enthalten, und die Kernlogik ist vollständig selbsttragend. Diese Entscheidung sorgt dafür, dass der Repository leicht bleibt, bedeutet aber auch, dass er derzeit nur Programme abdecken kann, die mit der builder API ausgedrückt werden können. Für bestehende große Geschäftsysteme ist eine direkte Migration nicht realistisch; der sinnvollere Weg wäre, lokale, rechenintensive Abschnitte herauszunehmen und neu zu schreiben. Aus Sicht der Quellcodeorganisation stehen die Kataloge tests/ und template/ nebeneinander, was darauf hindeutet, dass der Autor möchte, dass Nutzer von Templates ausgehen und anschließend normales JS nach dem handwired-Stil umwandeln.
Die Online-Demo und die Beispiele im Katalog template/ bilden den einfachsten Eingang: Eine normale JS-geschriebene UI-Komponente wird durch die builder-Codekonvertierung von handwired in eine numerische Tabelle, die auf einem GPU ausgeführt werden kann. Während des Build-Zeitraums wird ein normales JavaScript ausgeführt, um Makros wie emitMultiply und emitCompare in feste Längenkommandos umzuwandeln; während der Ausführungszeit gibt es keine Brüche oder Schleifen.
Diese Schreibweise ist für Frontend-Engineers natürlich vertraut: Man muss weder CUDA noch WGSL schreiben, sondern nur die builder API von JavaScript verwenden, um numerische Berechnungen zu beschreiben. Der Rest wird von handwired durchgeführt. Für Menschen, die an React-deklarative Komponenten gewöhnt sind, bedeutet das, dass die „Komponentenbaum“ durch „numerische Programmdiagramme“ ersetzt wird, während die Darstellung weiterhin in JavaScript erfolgt. Das bedeutet auch, dass Frontend-Engineers ihre bekannteste Sprache verwenden können, um GPU-Koordination und schreibbare Programme zu erforschen – der Einstieg ist viel einfacher als das Erlernen einer neuen Sprache.
Allerdings bringt die Benutzerfreundlichkeit der builder API auch Einschränkungen mit sich: Alle Berechnungen müssen mit den von dem Projekt bereitgestellten Grundoperationen ausgedrückt werden können. Jede Operation, die über den Rahmen hinausgeht, muss in normalem JavaScript bearbeitet werden. handwired ist eher eine spezifische Sprache, die in JS eingebettet ist, als eine unterschiedlose Übersetzung der JS-Syntax.
Vier, Effekte und Verifizierung
Die Wirkung des Selbstbeschreibungs-Fensters ist in drei Schichten unterteilt. Die erste Schicht ist der Proof-of-Concept: if-else-Befehle, Schleifen und Zustandsabstimmungen werden in Matrizenmultiplikationen und ReLU umgewandelt, wobei das Programm weiterhin präzise und differenzierbar bleibt. Die zweite Schicht ist die Demonstration: Das Online-Demo zeigt ein vollständiges UI-Betriebssystem namens HandwiredOS. Interaktionen wie Fensterverschieben, Maximieren, Klickauswahl, Textumschreiben und virtuelles Scrollen von Listen werden in das numerische Programm integriert. Der Host ist nur dafür verantwortlich, Browser-Ereignisse in die Quelldaten zu schreiben, diese einmal auszuprüfen und die Ausgabe wieder in den DOM zu schreiben. Die dritte Schicht ist die Leistungsgarantie: Das JSON-Such-Demo verspricht, 100.000 Dokumente in Millisekunden zu verarbeiten. Der Vorteil liegt in der parallelen Arbeit auf identischen Strukturen, also dass jeder Dokument beide gleichen Operationen durchführt, ohne sich gegenseitig zu stören. Mit anderen Worten, der Wert der Handwired-Demonstration liegt darin, zu beweisen, dass es möglich ist, „Programme auf einer Fließkomma-Tabelle auszuführen“, und nicht nur theoretisch möglich. Es hat das abstrakte Konzept in eine interaktive Demo im Browser verwandelt, was ein wichtiger Grund für die hohe Anzahl an Likes ist.
Allerdings betrachten die Autoren dies als Experiment. Der Stil in der README mit „Was macht das eigentlich? Lassen Sie uns herausfinden!“ sowie Fragen wie „Wie kann nanoGPT gleichzeitig Shakespeare und Ihre UI lernen, indem es ein gefrorenes bestimmtes Programm mit einem universellen neuronalen Netzwerk end-to-end trainiert?“ zeigen, dass es eher ein exploratives Projekt ist als eine etablierte Werkzeugkette.
Fünftes Kapitel: Grenzen und Kontroversen
Zunächst muss über die Aussagegrenzen gesprochen werden. Die Anweisung in der README „Turn your regular JavaScript code into a neural net“ könnte dazu führen, dass man denkt, dass beliebiger JS automatisch in ein Netzwerk umgewandelt werden kann; doch die technische Realität ist, dass man das Programm manuell mit den von dem Projekt bereitgestellten Buildern und numerischen Kontrakten neu schreiben muss, nicht mit einem universellen JS-Compiler.
Das nächste Thema sind die numerischen Grenzen. Die Kodierung von Zahlen mit ReLU hängt davon ab, ob die Operanden innerhalb der angegebenen Grids und Bereiche liegen. In der Fließkomma-Welt gibt es keine Magie für Eingaben, die über die Grenzen hinausgehen; auch die Indexabfrage hat ihre Beschränkungen. Die Programmierer müssen diese numerischen Kontrakte aktiv pflegen.
Dritte Grenze ist die Größenordnung. Beide Seiten der Abzweigung werden berechnet, und die Operanden steigen mit der Komplexität des Programms. Handwired eignet sich zur Überprüfung der Idee, dass „Programme Netzwerke sind“, aber wenn der Kontrollfluss eines echten Geschäftssystems vollständig in matrizenbasierte Operationen umgewandelt wird, würden Größe und Debugging-Kosten schnell ansteigen. Das bedeutet auch, dass Handwired derzeit eher für lokale Berechnungsintensive Szenarien wie Kontrollmechanismen, Suchfunktionen und Animationen geeignet ist, nicht für den gesamten Geschäftsbetrieb.
Schließlich gibt es die ökologischen Grenzen. Als gerade veröffentlichtes Experimentelles Projekt hat Handwired noch keine stabile Community und Werkzeugkette gebildet. Dritte Parteien-Bibliotheken, Editor-Plugins und Debugging-Tools sind noch nicht ausgereift. Unternehmen müssen die Wartungs- und Kognitionskosten tragen, wenn sie Handwired einsetzen möchten.
Schließlich gibt es den Unterschied zwischen Verbreitung und Popularität. Auf GitHub hat Handwired eine hohe Bewertung von 1804★ und wurde mehrmals auf der Startseite angezeigt; aber die hohe Anzahl an Likes misst eher die Thematik als die Anwendung. Die Schnittstellen können jederzeit ändern, und die offenen Probleme nehmen zu. Es ist jetzt nicht ratsam, Handwired direkt für Produktionszwecke zu verwenden.
Sechstes Kapitel: Schlussfolgerungen
Der Wert von Handwired liegt darin, mit einem konkreten, lauffähigen Projekt die Idee, dass „normale Programme zu differenzierbaren neuronalen Netzwerken kompiliert werden können“, vom Slogan auf die Praxis umzusetzen. Es stellt die vorherrschende Vorstellung in Frage, dass neuronale Netzwerke trainiert werden müssen, und zeigt, dass differenzierbarkeit aus der Kompilierstruktur entstehen kann, anstatt durch Backpropagation von außen eingegeben zu werden. Diese Herangehensweise ergänzt die heutige AI-Entwicklung, die stark auf Trainingsdaten angewiesen ist: In bestimmten Situationen kann die Struktur des Programms selbst differenzierbarkeit ermöglichen, ohne dass das Problem vollständig als Optimierungsproblem modelliert werden muss.
Die Erhebung auf 1804 nach 4 Tagen zeigt, dass dieses Thema die Neugier der Community berührt hat; doch ob es sich um ein Forschungstool oder einen Paradigmenwechsel handelt, hängt davon ab, ob jemand später damit echte Anwendungen entwickelt oder ob dieses Verfahren auf komplexere Kontrollströme ausgedehnt werden kann. Im Moment eignet es sich eher als Lehrwerkzeug zur Verständnisbildung von differenzierbarer Programmierung und numerischer Kompilierung, als eine sofort verwendbare neue Generation von Frontends. Für Entwickler im Bereich Frontends und Compiler bietet Handwired eine interessante Art der Programmierausdrucksweise; für Teams, die direkt anwendungsorientiert sind, bedarf es weiterer Überprüfungen und Entwicklung eines Ökosystems.
Ein interessanter Vergleich ist das traditionelle neuronale Netzwerk. Traditionelle Netzwerke nutzen Training, um Gewichte zu finden – der Vorteil ist die Universalität, der Nachteil ist, dass das Verhalten nicht erklärbar ist und große Mengen an Daten benötigt werden. Handwired verwendet Programme, um Gewichte direkt festzulegen – der Vorteil ist, dass das Verhalten klar und erklärbar ist, der Nachteil ist, dass die Ausdrucksfähigkeit durch die Programmierung des Programmierers begrenzt ist. Beide sind keine Ersatzlösungen, sondern ergänzend zueinander. In Situationen, in denen eine hohe Erklärbarkeit und Klarheit gefordert werden, wie beispielsweise bei UI-Animationen, Finanzberechnungen oder physikalischen Simulationen, könnte die Herangehensweise von Handwired viel zuverlässiger sein als das Training von Netzwerken.
Es ändert nicht unbedingt Ihre heutige Programmierungstradition, aber es hat tatsächlich einen Spalt in die „Mauer zwischen Programm und Netzwerk“ geschlagen. Zukünftige interessante Fragen sind: Kann es dynamischere Kontrollströme unterstützen? Kann es die Skalierbarkeit erhöhen, gleichzeitig differenzierbar zu bleiben? Kann es mit bestehenden Frontends als Ergänzung statt als Ersatz funktionieren? Es gibt keine fertigen Antworten auf diese Fragen, aber gerade sie machen Handwired diskussionswürdig.
Quellen
- GitHub-Repository: chenglou/handwired (README, docs/, src/, lab/)
- Faktenpaket: /Users/kael/xhs-content/drafts/2026-10-20-facts-packages.json (Repository-Größe, Autor, Kernmechanismus, Demo-Adresse, Verbreitungskraft)
- Online-Demo: https://chenglou.me/handwired/