Ich habe über diesen Blog zwei Jahre nachgedacht.
„Wollen“ zu sagen ist eigentlich nicht ganz exakt, es ist eher eine Obsession. In den frühen Tagen, als ich noch weder Front‑End‑ noch Back‑End‑Code schreiben konnte und keine Embedded‑Programmierung kannte, entstand das Verlangen. Ich bastelte noch mit Elektronik und stieß zufällig auf @ushios B‑Station‑Video und Webseite, fand es so spannend, dass ich es selbst ausprobieren wollte. Anschließend verbrachte ich etwa ein halbes Jahr damit, von Grund auf C und ein bisschen JS/CSS zu lernen, und baute mit Hexet einen statischen Blog, den ich auf GitHub Pages bereitstellte – so entstand mein kleines eigenes Eckchen.


再后来,看到了 @Innei 的小站,设计很精致、功能也很全,当时的我看了一眼我就想要,甚至还赞助支持了,虽然后面没用上但是这钱也花的不怨 因为我摸到了 React 源码,就和我最初看到 C 一样,不过就是代码嘛,有什么大不了的,总有一天我要自己写一个。

Später entdeckte ich die kleine Website von @Innei. Das Design ist sehr fein verarbeitet und die Funktionen sind umfassend. Beim ersten Blick wollte ich sie sofort haben und habe sogar gesponsert. Obwohl ich sie später nicht benutzt habe, bereue ich das ausgegebene Geld nicht, weil ich den React-Quellcode kennengelernt habe – das fühlte sich an wie das erste Mal, als ich C sah. Es ist nur Code, nichts Großes. Ich bin mir sicher, dass ich eines Tages selbst einen schreiben werde.
Stiller Wald
Das war das Jahr 2024, dann 24, 25, 26 Jahre bis jetzt
Seitdem lässt es sich nicht mehr stoppen.
Außer Kontrolle
Anfangs wollte ich nur einen Licht‑Dunkel‑Umschalter zum Hexo‑Theme Nlvi von @colmugx hinzufügen. Ich habe schnell ein Dark‑Reader‑ähnliches JavaScript reingehauen – es sah hässlich aus und entsprach nicht meinen Vorstellungen. Danach habe ich CSS @media gelernt, dann zu einem JS‑SPA‑Umschalter gewechselt, TailwindCSS‑.dark‑Klasse ausprobiert, SSR mit next‑theme verwendet und schließlich ein eigens geschriebenes Cookie + Head‑Sync‑Inline‑Skript eingesetzt, um das FOUC‑Flackern zu beheben. Ich habe dabei vier‑fünf verschiedene Lösungen ausprobiert.

Aber das ist nur die Spitze des Eisbergs. Nachdem ich React entdeckt hatte, ging ich von der Steinzeit von Hexo und Vanilla JS über zu Next.js 13 Page Router, wandte mich dann Vue zu, studierte SPA‑Routing, verstand das index.html‑Fallback und erstellte unzählige neue Projekte. Ich kaufte einen Server, bastelte an Docker, Nginx, NAS; fand 1Panel unschön und schrieb das Canopy‑Panel selbst, erforschte NAS‑Speicher-Arrays und schrieb RFS. Beim SSL‑Handling machte die heimische Umgebung mit acme.sh so viel Ärger, dass ich einen Reverse‑Proxy in Rust schrieb: Vane & Lazyacme. Was ursprünglich ein dreistündiges, 800‑Zeilen‑“Müllprojekt” war, entwickelte sich nach der Ermutigung eines Freundes zu vier Monaten Arbeit, in die ich HTTP/3, Zero‑Copy, das Layer‑Modell und die Flow‑Engine stopfte. Später kam noch Seam dazu, ein Full‑Stack‑Framework, das ebenfalls ein Albtraum ist – darüber später mehr.
Überengineering
Dann kam das KI-Zeitalter, und die Angst hat sich verdoppelt.
Am ironischsten ist, dass diese Dinge eigentlich erst nach dem Start eines Blogs erledigt werden sollten – dabei gleichzeitig festgehalten. Stattdessen wurde der Blog immer wieder aufgegeben, Ideen häuften sich, und es gab keinen Ort, sie zu dokumentieren. Einerseits verurteilt mich mein Inneres; ich hatte versprochen, Vane fertigzustellen, aber ich konnte es nicht und musste aufhören. Auf der anderen Seite überkommt mich ein wachsendes Gefühl der Hilflosigkeit, je weiter ich mich entferne. Ich erinnere mich stets, was ich tun will, schaffe es aber einfach nicht. Wenn ich darüber nachdenke, merke ich, dass ich schon lange nicht mehr gesessen habe, um etwas zu schreiben. Im Rückblick deutet all das auf dasselbe hin – übermäßiges Engineering.
Damals hatte ich tatsächlich nicht das Gefühl, vom Kurs abzukommen. Vane? Auf jeden Fall muss der Blog später bereitgestellt werden, also braucht man wohl einen Reverse‑Proxy. Seam? Da ich früher oder später das Full‑Stack‑Entwickeln in Angriff nehmen muss, könnte ich genauso gut zuerst das Framework meiner Vorstellung fertigstellen. Jeder Schritt hat einen Grund, jeder Schritt ist „irgendwann nützlich“. Das Problem ist jedoch, dass „irgendwann“ nie kommt, weil ich nie wirklich begonnen habe…
Fehlschlag
Ein Blog erfordert eigentlich keinen Reverse‑Proxy und kein eigens entwickeltes Framework. Trotzdem habe ich damals diese Dinge als Vorbedingungen angesehen und sie als die immer blockierende, aber scheinbar vernünftige Begründung benutzt – obwohl sie nie solche waren. Die einzige wahre Voraussetzung ist nur eine: Setz dich hin und schreibe den ersten Beitrag.
Eigentlich wurde der Blog nicht unberührt gelassen, im Gegenteil, ich habe es dreimal gemacht.

Das erste Mal war noch zur Zeit des Next.js 13 Page Router. Damals verstand ich kaum, was eine SPA ist, und die Konzepte SSR, SSG, ISR waren mir völlig unbekannt, aber weil andere sagten, SSR sei gut, wollte ich es ebenfalls verwenden. Während ich schrieb, stellte ich fest, dass ich nicht verstand, welche Probleme diese Architekturen lösen sollten, und ich kam nicht weiter. Später wechselte ich zu einer reinen Vue 2‑SPA. Warum Vue? Ehrlich gesagt gefiel mir der Name, er wirkte neu, also probierte ich es aus. Das hielt nicht lange. Beim dritten Mal kehrte ich zu React zurück, begann mit einfachem JSX, lernte TypeScript, beherrschte TSX, verstand den Unterschied zwischen CJS und ESM, verliebte mich in reaktive Programmierung und nutzte Lucide, Framer Motion, Radix UI – Bibliotheken, ohne die ich jetzt nicht mehr auskomme – dieses Mal sah es endlich nach einem funktionierenden Ansatz aus. Trotzdem scheiterte ich, weil ich im Kern nur nachahmte: Ich nahm, was andere benutzten, es wirkte zwar korrekt, aber ich verstand nicht, warum es so gemacht werden sollte. Hinzu kamen die Halluzinationen der KI; man konnte ein MVP zum Laufen bringen, aber beim Scale‑Up war alles voller Fallen.

Später habe ich auch React (Remix) Router Loader, den Next.js 15 App Router und RSC gelernt, aber zu diesem Zeitpunkt war mein Alltag bereits sehr hektisch, ich hatte kaum Zeit zum Programmieren und bekam nicht einmal die Chance für einen vierten Misserfolg. Rückblickend musste ich feststellen, dass meine Seite von Next.js 13 zu Next.js 15 migriert wurde; gerade als die Migration abgeschlossen war und die Seite noch nicht live ging, erschien Next.js 16 beta‑1.
Loslassen
Zu sagen „想开了“ ist eigentlich nicht präzise; ich bin einfach müde.

Das Tempo der KI‑Ära ist zu schnell. Modelle werden nacheinander iteriert, neue Technologien tauchen ebenfalls nacheinander auf, und ich werde immer ängstlicher, als ob ein Stillstand bedeuten würde, überholt zu werden. In meinem verrücktesten Moment schrieb ich an einem Tag 16 kleine Programme; ein Tag an Tokens konnte etwa 1.900 USD verbrennen (ungefähr im Februar), und ich war fast am Ende. Doch was das alles zum Stillstand brachte, war kein Erwachen, sondern reine Erschöpfung. Bei dem immer schneller werdenden Rhythmus drückte das letzte Strohhalm‑Glas nach unten, und ich fühlte plötzlich Erleichterung, ließ los, gab den Kampf auf; so ist das eigentlich ziemlich gut.
Ich habe begonnen loszulassen. Ich habe die Dinge, an denen ich einst festgehalten habe, aufgegeben, gelernt, bei Bedarf zu stoppen, und das Morgen erledige ich morgen. Vane nicht fertig? Erst mal liegen lassen. Seam ist noch weit entfernt? Später erledigen. Der Blog ist nicht perfekt? Erst einmal veröffentlichen. Beginne komplett mit Vibe Coding; wenn es kein Problem gibt, ignoriere es, bei Problemen kümmere ich mich später darum.
Seltsamerweise hat die Qualität nach dem Loslassen nicht nachgelassen. Ich denke, das liegt wahrscheinlich daran, dass die früheren „古法“-Programmierzeiten nicht umsonst waren; bereits in der GPT‑2‑Ära habe ich angefangen, KI zu benutzen, doch damals schrieb ich noch jede Zeile Code gewissenhaft und verstand jedes Konzept. Diese Erfahrung hat mir ein Fundament gegeben, und eher als später Vibe Coding zu bezeichnen, sollte man von Context Coding sprechen; das nötige Urteilsvermögen ist noch vorhanden, und das Loslassen hat nicht zu niedrigen Fehlern oder Unfällen geführt.
All das frühere Durcheinander hat mir das nötige Kapital verschafft, jetzt loszulassen.
Ursprung
Die endgültige Lösung ist überraschend einfach: All in Cloudflare. R2‑Objektspeicher, D1 Edge‑Datenbank, KV für Caching, Worker führt SSR aus, alles ist serverlos, es gibt keinen Server.

Ist diese Antwort sarkastisch? Sehr sarkastisch. Denn bevor ich dieses „einfache“ Ziel erreichte, habe ich einen kompletten Umweg gemacht. Ich hatte einst vor, alles selbst zu hosten, also musste ich den Server verwalten, mit Docker experimentieren und Container managen, daher schrieb ich Canopy als Verwaltungs‑Panel, Lazycert zur Zertifikatsverwaltung, Vane als Reverse‑Proxy und Twig für Ressourcen‑Monitoring‑Hooks. Eine Menge Projekte nur, um einen alten Müll‑Server zu bedienen.
Der Speicher ist genauso. Da ich Object Storage zu teuer finde, wollte ich die Festplatten meines eigenen Servers nutzen und schrieb RFS, ein VFS für atomare Deduplizierung und Zusammenführung einzelner Dateien, revivierte sogar das Registrierungs‑Konzept der 80er‑90er Jahre und mountete es schließlich über FUSE. Das Ergebnis: Ich habe noch mehr Zeit damit verbracht, ein nicht besonders gutes Rad zu bauen, der Server lief ein Jahr lang leer, es war ein komplett verlustreiches Geschäft.

Am Ende drehte ich mich im Kreis und landete wieder bei Serverless. Das Konzept von Vercel ist gut, aber ich mag Next.js nicht; außerdem steckt bei Vercel zu viel „Magie“, und das Middleware‑Design, das im Voraus kompiliert wird, um am Edge zu laufen, führt letztlich zu einer Zersplitterung und sogar zu mehreren CVEs. Es wäre besser, alles auf dem Origin‑Server zu betreiben. Cloudflare Workers hingegen sind großartig und erreichen ein extremes Szenario: Produkte unter 10 MB werden zu WASM kompiliert und können echte Geschäftslogik am Edge ausführen – genau das, was ich will. Abgesehen von den Kosten gibt es kaum Nachteile – obwohl man das nicht wirklich als Nachteil bezeichnen kann, denn gesparte Zeit ist Geld.
Weniger ist mehr
Ich habe diesen Satz unzählige Male gehört, aber es dauerte zwei Jahre, bis ich seine wahre Bedeutung wirklich verstand.
Der Kern des Rückgriffs auf das Ingenieurwesen lautet: „Make it function, make it correct, then make it exceptional.“ Ich habe endlich den richtigen Kurs gefunden und es functional gemacht. Ist mein aktueller Blog schlicht? Ja, schlicht. Unvollständig? Tatsächlich unvollständig. Aber besser als gar nichts. Wenn du nicht einmal einen Release‑Tag hast und ständig an etwas arbeitest, das „vielleicht nötig“ ist, dabei einer unsichtbaren Perfektion nachjagst, bleibt am Ende nichts greifbar. Das ist kein Kompromiss, sondern ein technisches Abwägen. So oder so, ich habe es mir gefallen lassen. Also habe ich losgelassen. Ich fixiere mich nicht mehr auf jedes Detail und habe stattdessen das Haus verlassen. In meinem Handy‑Album gibt es seit langem kein Outdoor‑Foto mehr, also habe ich spontan ein Bild vom Straßenrand geschossen – ich war schon ewig nicht mehr draußen.

Wenn ich auf die Umwege zurückblicke, die ich früher genommen habe, bereue ich das? Nein, ich bereue es nicht. Manchmal versteht man etwas nie, wenn man es nicht selbst ausprobiert. Vor allem im Zeitalter der KI gibt es praktisch keine Chance mehr, den alten Weg, den ich damals ging, nachzuvollziehen; zu viele Arbeitsabläufe haben sich bereits geändert. Außerdem ist dieses Projekt Taki, zu 100 % KI‑Programmierung, aber das bedeutet nicht, dass es nicht langfristig gepflegt werden kann, noch dass es keinen menschlichen Touch hat. Eigentlich ist es egal, ob KI beteiligt ist oder nicht; außerdem liebe ich nicht das reine Schreiben von Code, sondern das Bauen von etwas…