Backend-Migration: Inkrementeller Wechsel von Node/TypeScript zu Go #321

Closed
opened 2026-01-26 08:25:18 +00:00 by jack · 0 comments
Owner

Motivation

Das Backend wächst in eine Richtung, wo Go objektiv besser passt als Node/TypeScript:

  • Memory-Overhead: Backend (~100MB) + Worker (~80MB) + SSE-Writer (~40MB) neben Claude Code. Go-Äquivalent: ~30MB gesamt.
  • WebSocket-Stabilität: Permanente WebSocket closed: 1006 Reconnects, noServer-Workaround (c25f50f) - Go's net/http teilt sich den Server nativ.
  • ORM-Overhead ohne Nutzen: MikroORM wird für kritische Queries (FTS5, BM25, JSON-Functions, Aggregationen) mit Raw SQL umgangen. Der ORM-Layer (Reflection, Unit-of-Work, Entity-Tracking) ist Overhead ohne Mehrwert für diese Fälle.
  • Worker Federation: Hub-Federation mit Token-Auth, Capability-Matching, Heartbeats - viele langlebige Connections, die Go's Goroutine-Modell nativ besser handhabt.
  • Concurrency: Event-Loop ist single-threaded. Task-Dispatcher polling + WebSocket-Hub + SSE-Broadcasting konkurrieren um denselben Thread.

Was NICHT migriert wird

Paket Bleibt Node/TS Grund
hooks Claude Code Plugin-Ökosystem
plugin Claude Code Plugin-Format
ui React/Vite Frontend
worker (vorerst) I/O-bound, Go bringt wenig

Strategie

Inkrementeller Ansatz in 3 Phasen:

  1. API-Contract definieren - OpenAPI-Spec aus bestehenden Endpoints, sodass Backend austauschbar wird
  2. Go-Backend implementieren - chi/echo + sqlc + gorilla/websocket
  3. Worker evaluieren - Nur wenn CPU-intensive Aufgaben dazukommen

Voraussetzungen für den Start

  • Kein aktiver Feature-Push, der das Backend stark verändert
  • Oder: Ein größerer Rewrite steht ohnehin an
  • Oder: Memory/Performance wird zum echten Problem
  • Oder: Federation-Features sollen produktionsreif werden

Risiken

  • Polyglot-System (Node + Go) erhöht Maintenance-Aufwand
  • Shared Types müssen über OpenAPI/Protobuf synchronisiert werden
  • Go-Expertise im Team nötig
  • ~20k LOC Backend + Database sind nicht trivial zu portieren
## Motivation Das Backend wächst in eine Richtung, wo Go objektiv besser passt als Node/TypeScript: - **Memory-Overhead**: Backend (~100MB) + Worker (~80MB) + SSE-Writer (~40MB) neben Claude Code. Go-Äquivalent: ~30MB gesamt. - **WebSocket-Stabilität**: Permanente `WebSocket closed: 1006` Reconnects, `noServer`-Workaround (c25f50f) - Go's `net/http` teilt sich den Server nativ. - **ORM-Overhead ohne Nutzen**: MikroORM wird für kritische Queries (FTS5, BM25, JSON-Functions, Aggregationen) mit Raw SQL umgangen. Der ORM-Layer (Reflection, Unit-of-Work, Entity-Tracking) ist Overhead ohne Mehrwert für diese Fälle. - **Worker Federation**: Hub-Federation mit Token-Auth, Capability-Matching, Heartbeats - viele langlebige Connections, die Go's Goroutine-Modell nativ besser handhabt. - **Concurrency**: Event-Loop ist single-threaded. Task-Dispatcher polling + WebSocket-Hub + SSE-Broadcasting konkurrieren um denselben Thread. ## Was NICHT migriert wird | Paket | Bleibt Node/TS | Grund | |-------|----------------|-------| | hooks | ✅ | Claude Code Plugin-Ökosystem | | plugin | ✅ | Claude Code Plugin-Format | | ui | ✅ | React/Vite Frontend | | worker | ✅ (vorerst) | I/O-bound, Go bringt wenig | ## Strategie Inkrementeller Ansatz in 3 Phasen: 1. **API-Contract definieren** - OpenAPI-Spec aus bestehenden Endpoints, sodass Backend austauschbar wird 2. **Go-Backend implementieren** - chi/echo + sqlc + gorilla/websocket 3. **Worker evaluieren** - Nur wenn CPU-intensive Aufgaben dazukommen ## Voraussetzungen für den Start - Kein aktiver Feature-Push, der das Backend stark verändert - Oder: Ein größerer Rewrite steht ohnehin an - Oder: Memory/Performance wird zum echten Problem - Oder: Federation-Features sollen produktionsreif werden ## Risiken - Polyglot-System (Node + Go) erhöht Maintenance-Aufwand - Shared Types müssen über OpenAPI/Protobuf synchronisiert werden - Go-Expertise im Team nötig - ~20k LOC Backend + Database sind nicht trivial zu portieren
jack closed this issue 2026-01-26 08:32:43 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
customable/claude-mem#321
No description provided.