Eine Codebase. 13 Plattformen. Ohne Kompromisse.
Wie drei Dateien gleichzeitig zum Webformular, CLI-Befehl, MCP-Tool, nativen Screen und automatisierten Job werden.
5.802 TypeScript-Dateien. ~2,1 Millionen Zeilen. Null `any`. Null Runtime-Typfehler. Ein Pattern. 374-mal wiederholt.
Das ist die Codebase hinter unbottled.ai - und das Framework dahinter, next-vibe. Dieselbe Architektur betreibt eine Web-App, eine Mobile-App, eine CLI, ein KI-Agent-Interface, einen MCP-Server, ein Cron-System, einen WebSocket-Event-Bus und eine Live-Datenfluss-Engine.
Das Pattern heiĂt Unified Surface. Hier erfĂ€hrst du, was es ist, wie es funktioniert und warum du danach schwer davon loskommst.
Ein Feature ist ein Ordner
Jedes Feature in next-vibe lebt in einem Ordner. Drei Dateien sind Pflicht. Alles andere ist optional.
1explain-to-my-boss/
2 definition.ts â was es tut
3 repository.ts â wie es das tut
4 route.ts â lĂ€sst es ĂŒberall existieren
5 widget.tsx â eigene React-UI (optional)
6 widget.cli.tsx â eigene Terminal-UI (optional)Das ist alles. Ein Ordner. Drei Pflichtdateien. Und aus diesen drei Dateien existiert das Feature auf bis zu 13 Plattformen gleichzeitig.
13 Plattformen aus 3 Dateien
Wenn du ein Feature zu next-vibe hinzufĂŒgst, wird es nicht nur ein API-Endpoint. Es wird gleichzeitig alles.
Web API
REST-Endpoint, automatisch validiert, vollstÀndig typisiert
React UI
Automatisch aus der Definition generiert - kein JSX geschrieben
CLI
Jeder Endpoint ist ein Befehl mit automatisch generierten Flags
AI Tool Schema
Function-Calling-Schema wird automatisch generiert
MCP Server
Verbinde dich mit Claude Desktop, Cursor oder einem anderen MCP-Client
React Native
iOS- und Android-Screens aus derselben Definition
Cron Job
Jeden Endpoint nach Zeitplan ausfĂŒhren
WebSocket Events
Updates an verbundene Clients pushen, sobald etwas fertig ist
Electron Desktop
Native Desktop-App ĂŒber dieselben Endpoint-VertrĂ€ge
Admin-Panel
Automatisch generiertes Admin-UI, kein zusÀtzlicher Code nötig
VibeFrame Widget
Einbettbares iframe-Widget fĂŒr jede Website
Agent Skill
Von KI-Agenten als strukturierter Skill aufrufbar
Vibe Sense Node
Node in einem Live-Datenflussgraphen - selber Endpoint
Lösch den Ordner. Das Feature hört ĂŒberall gleichzeitig auf zu existieren.
Plattformzugriff ist ein Enum-Array
Du schreibst keine separaten Berechtigungsschichten fĂŒr jede Plattform. Der Plattformzugriff wird direkt in der Definition deklariert - ein Enum-Array, das jede Plattform zur Laufzeit nativ ausliest.
1// Dieses eine Array steuert, wo das Feature auftaucht
2allowedRoles: [
3 CLI_OFF, // blockt die CLI
4 MCP_VISIBLE, // Opt-in fĂŒr die MCP-Tool-Liste
5 REMOTE_SKILL, // trÀgt es in die Agent-Skill-Datei ein
6 PRODUCTION_OFF, // deaktiviert es in Produktion
7]Selbe Definition. Selber Ort. Keine Konfig-Dateien zum Synchronisieren. Keine separaten Berechtigungssysteme pro Plattform.
Es gibt keine API fĂŒr Menschen und API fĂŒr KI. Es gibt nur das Tool.
Die Live-Demo: Thea baut einen Endpoint
Statt das Pattern abstrakt zu erklÀren, zeig ich dir, wie es in der Praxis aussieht.
Thea ist die KI-Administratorin dieser Plattform. Sie lĂ€uft 24/7 auf Produktion und arbeitet mit denselben Endpoint-VertrĂ€gen wie jeder Benutzer - selbe Validierung, selbe Berechtigungen, keine HintertĂŒr. Und sie kann Arbeit an eine lokale Maschine delegieren.
Ich hab Thea gebeten, einen neuen Endpoint zu bauen - explain-to-my-boss - mit Claude Code auf meinem PC. Du gibst eine technische Entscheidung ein, und raus kommt eine nicht-technische BegrĂŒndung, die dein Chef tatsĂ€chlich glaubt. Das hat jeder Entwickler schon mal gebraucht.
Die Live-Demo: Thea baut einen Endpoint
Frag Thea
Tippe die Aufgabe in den Chat - zwei Eingabefelder, eine KI-generierte Antwort, alle Plattformen, MCP_VISIBLE, eigene React- und CLI-Widgets.
Erstellt die Aufgabe
Thea denkt laut nach, erstellt eine Aufgabe mit targetInstance="hermes" (deine lokale Maschine) und geht in den Ruhezustand.
Holt die Aufgabe ab
Die lokale Instanz synchronisiert alle 60 Sekunden. Keine offenen Ports. Deine Maschine initiiert die Verbindung.
Baut den Endpoint
Interaktive Session. Liest zuerst bestehende Patterns, erstellt fĂŒnf Dateien, fĂŒhrt vibe check aus. Null Fehler.
Meldet Fertigstellung
Ruft complete-task mit der Aufgaben-ID auf. Status: abgeschlossen. Zusammenfassung anbei.
Wacht auf
wakeUp feuert. Thea setzt das GesprÀch per WebSocket fort, streamt ihre Antwort, TTS spricht.
Existiert ĂŒberall
Webformular. CLI-Befehl. MCP-Tool. React-Native-Screen. Alles live. Aus fĂŒnf Dateien.
Der Beweis
Sobald Claude Code complete-task aufgerufen hat, gab es drei Dinge, die fĂŒnf Minuten vorher noch nicht existierten:
Ein eigenes React-Widget - dramatische Ăberschrift, animierter Gradient auf dem KI-Output, ein gefĂ€lschter Corporate-Alignment-Score.
Ein CLI-Widget - ASCII-Banner, Spinner wĂ€hrend die KI nachdenkt, die BegrĂŒndung Zeile fĂŒr Zeile in GrĂŒn.
Ein MCP-Tool - explain-to-my-boss_POST - weil MCP_VISIBLE in der Definition stand. Claude Desktop kann jetzt deine Entscheidungen deinem Chef erklÀren.
Eine Definition. FĂŒnf Dateien insgesamt. Drei komplett verschiedene UIs. Der Endpoint-Vertrag hat sich nicht geĂ€ndert. Nur die PrĂ€sentationsschicht.
Unter der Haube
definition.ts - der lebende Vertrag
Die Definition ist kein Code-Generator. Sie ist ein lebender Vertrag, den jede Plattform zur Laufzeit nativ ausliest. Ăndere sie - alles aktualisiert sich. Lösch den Ordner - nichts bricht downstream. Es gibt keinen generierten Code zum AufrĂ€umen.
1// definition.ts
2const { POST } = createEndpoint({
3 scopedTranslation,
4 aliases: [EXPLAIN_TO_MY_BOSS_ALIAS],
5 method: Methods.POST,
6 path: ["explain", "to-my-boss"],
7 title: "post.title",
8 description: "post.description",
9 icon: "sparkles",
10 category: "endpointCategories.ai",
11 allowedRoles: [UserRole.CUSTOMER, UserRole.ADMIN] as const,
12 fields: objectField(scopedTranslation, {
13 type: WidgetType.CONTAINER,
14 usage: { request: "data", response: true },
15 children: {
16 decision: requestField(scopedTranslation, {
17 type: WidgetType.FORM_FIELD,
18 fieldType: FieldDataType.TEXTAREA,
19 label: "post.fields.decision.label",
20 description: "post.fields.decision.description",
21 schema: z.string().min(1).max(2000),
22 columns: 12,
23 }),
24 justification: responseField(scopedTranslation, {
25 type: WidgetType.TEXT,
26 content: "post.fields.justification.content",
27 schema: z.string(),
28 }),
29 },
30 }),
31 errorTypes: { /* ... all 9 required error types ... */ },
32 successTypes: { title: "post.success.title", description: "post.success.description" },
33 examples: { requests: { default: { decision: "Migrate to Bun" } }, responses: { default: { justification: "..." } } },
34});repository.ts - niemals throw
Repository-Funktionen werfen nie. Fehler propagieren als Daten - typisiert, explizit und vom Aufrufer abfangbar. Die KI kann ĂŒber Fehlerpfade nachdenken. Keine ĂŒberraschenden Exceptions.
1// repository.ts
2// Gibt ResponseType<T> zurĂŒck - wirft niemals
3export async function explainToMyBoss(
4 data: { decision: string },
5 logger: Logger,
6): Promise<ResponseType<{ justification: string }>> {
7 const result = await ai.generateText({
8 prompt: buildPrompt(data.decision),
9 });
10 if (!result.text) {
11 return fail({ message: "AI returned empty response", errorType: EndpointErrorTypes.SERVER_ERROR });
12 }
13 return success({ justification: result.text });
14}route.ts - die komplette BrĂŒcke
route.ts verbindet Definition mit Handler. endpointsHandler kĂŒmmert sich um Validierung, Authentifizierung, Logging und Exposition fĂŒr alle 13 Plattformen. Die eigentliche GeschĂ€ftslogik ist eine Zeile.
1// route.ts
2import { endpointsHandler } from "next-vibe/core/route/multi";
3import { Methods } from "next-vibe/core/definition/enums";
4import definitions from "./definition";
5import { explainToMyBoss } from "./repository";
6
7export const { POST, tools } = endpointsHandler({
8 endpoint: definitions,
9 [Methods.POST]: { handler: ({ data, logger }) => explainToMyBoss(data, logger) },
10});Die Zahlen
374 Endpoints
Ein Pattern, 374-mal angewandt
Null `any`
Zur Build-Zeit erzwungen, keine Konvention
Drei Sprachen
Zur Compile-Zeit geprĂŒft - t("typo.here") ist ein Compiler-Fehler
Das ist keine Konvention. Das wird zur Build-Zeit erzwungen.
Ein Pattern. 374-mal wiederholt.
Jede Node in einem Vibe-Sense-Graph ist ein regulĂ€rer next-vibe-Endpoint. Dasselbe createEndpoint(). Dieselbe 3-Dateien-Struktur. Ein EMA-Indikator ist ein Endpoint. Ein Schwellenwert-Evaluator ist ein Endpoint. Und weil es ein Endpoint ist, kannst du ihn ĂŒber CLI, KI oder von ĂŒberall aufrufen.
vibe analytics/indicators/ema --source=leads_created --period=7
Die Pipeline ist die Plattform.
Vibe Sense sind einfach⊠mehr Endpoints. Dasselbe Prinzip, angewandt auf Zeitreihendaten. Lead-Funnels. Credit-Ăkonomie. Nutzerwachstum. Deine Plattform ĂŒberwacht sich selbst.
ZurĂŒck zum BlogEinmal definieren. Ăberall vorhanden.
WordPress gab jedem die Macht zu publizieren. next-vibe gibt dir die Macht, Plattformen zu bauen, die auf Web, Mobile, CLI, KI-Agenten und Automatisierung funktionieren - die sich selbst ĂŒberwachen, ĂŒber ihre eigenen Daten nachdenken und danach handeln.
next-vibe auf GitHub mit Stern versehen