Open Source · MIT + GPL v3

Jedna definicja.Trzynaście platform.

next-vibe zamienia pojedynczą definicję TypeScript w trzynaście platform naraz - dedykowany interfejs web, polecenie CLI, narzędzie MCP, ekran mobilny, cron job, WebSocket, panel admina i więcej. Pełne bezpieczeństwo typów, zero dryfu, zero powtórzeń.

501+

typed endpoints

0

runtime type errors

13

platforms per endpoint

2

files required

Problem

Budowałeś to samo trzynaście razy.

Każdy feature potrzebuje własnego interfejsu web, polecenia CLI, narzędzia MCP, ekranu mobilnego, cron joba, handlera WebSocket, panelu admina i więcej. Ta sama walidacja, ten sam i18n, ta sama obsługa błędów - tylko inaczej ubrana. Za każdym razem.

Web API
React UI
CLI
Narzędzie AI
Serwer MCP
React Native
Cron Job
WebSocket
Electron
Panel administracyjny
Widget VibeFrame
Skill agenta
Węzeł Vibe Sense
next-vibe buduje wszystkie trzynaście z jednego pliku.
Wzorzec

Dwa pliki wymagane. Każda platforma.

Każdy feature żyje w folderze. Tylko definition.ts i route.ts są wymagane - wszystko inne jest opcjonalne.

definition.ts - kontrakt

Zadeklaruj pola, schematy Zod, etykiety, typy błędów i przykłady raz. Ten plik jest jedynym źródłem prawdy - framework odczytuje go w czasie wykonania na każdej platformie.

typescript
1const { POST } = createEndpoint({
2  scopedTranslation,
3  method: Methods.POST,
4  path: ["explain", "to-my-boss"],
5  title: "post.title" as const,
6  description: "post.description" as const,
7  icon: "sparkles",
8  category: "endpointCategories.ai",
9  allowedRoles: [UserRole.CUSTOMER, UserRole.ADMIN] as const,
10  fields: customWidgetObject({
11    render: ExplainContainer,
12    usage: { request: "data", response: true } as const,
13    children: {
14      decision: requestField(scopedTranslation, {
15        type: WidgetType.FORM_FIELD,
16        fieldType: FieldDataType.TEXTAREA,
17        label: "post.decision.label" as const,
18        columns: 12,
19        schema: z.string().min(10),
20      }),
21      justification: responseField(scopedTranslation, {
22        type: WidgetType.TEXT,
23        content: "post.justification.content" as const,
24        schema: z.string(),
25      }),
26    },
27  }),
28  errorTypes: {
29    [EndpointErrorTypes.UNAUTHORIZED]:      { title: "post.errors.unauthorized.title" as const,      description: "post.errors.unauthorized.description" as const },
30    [EndpointErrorTypes.SERVER_ERROR]:      { title: "post.errors.serverError.title" as const,       description: "post.errors.serverError.description" as const },
31    // ... other error types
32  },
33  successTypes: { title: "post.success.title" as const, description: "post.success.description" as const },
34  examples: { requests: { default: { decision: "Przepisz wszystko na TypeScript" } }, responses: { default: { justification: "..." } } },
35});
36
37export type ExplainResponseOutput = typeof POST.types.ResponseOutput;
38const definitions = { POST } as const;
39export default definitions;

repository.ts - logika

Logika biznesowa żyje tu - zapytania DB, sprawdzanie uprawnień, obsługa błędów z success()/fail(). Plik route.ts to tylko cienki delegator; walidacja, logowanie i rejestracja platform działają automatycznie.

typescript
1import "server-only";
2
3export class ExplainRepository {
4  static async explainToMyBoss(
5    data: ExplainRequestOutput,
6    user: JwtPayloadType,
7    logger: EndpointLogger,
8    t: ExplainT,
9  ): Promise<ResponseType<ExplainResponseOutput>> {
10    if (!user.id) {
11      return fail({ message: t("post.errors.unauthorized.title"), errorType: ErrorResponseTypes.UNAUTHORIZED });
12    }
13    try {
14      const [saved] = await db
15        .insert(explainResults)
16        .values({ userId: user.id, decision: data.decision })
17        .returning();
18      logger.info("Saved decision", { userId: user.id, id: saved.id });
19      return success({ justification: saved.justification ?? "" });
20    } catch (error) {
21      logger.error("Failed to save decision", parseError(error));
22      return fail({ message: t("post.errors.serverError.title"), errorType: ErrorResponseTypes.INTERNAL_ERROR });
23    }
24  }
25}

widget.tsx - UI (opcjonalny)

Bez widgetu framework automatycznie renderuje pola wszędzie. Dodaj widget.tsx, żeby dostarczyć w pełni customowy interaktywny interfejs - ten sam komponent renderuje w panelach admina, osadzonych widgetach i ekranach mobilnych.

tsx
1"use client";
2
3interface CustomWidgetProps {
4  field: {
5    value: ExplainResponseOutput | null | undefined;
6  } & (typeof definition.POST)["fields"];
7}
8
9export function ExplainContainer({ field }: CustomWidgetProps): JSX.Element {
10  const children = field.children;
11  const emptyField = useMemo(() => ({}), []);
12
13  return (
14    <Div className="flex flex-col gap-4 p-4">
15      <TextareaFieldWidget fieldName="decision" field={children.decision} />
16      <SubmitButtonWidget<typeof definition.POST>
17        field={{
18          text: "Explain to my boss",
19          loadingText: "Explaining...",
20          icon: "sparkles",
21          variant: "primary",
22        }}
23      />
24      <FormAlertWidget field={emptyField} />
25      <AlertWidget
26        fieldName="justification"
27        field={withValue(children.justification, field.value?.justification, null)}
28      />
29    </Div>
30  );
31}
Usuń folder. Feature znika z każdej platformy naraz.
Every Platform

Jedna definicja. Trzynaście platform.

Gdy dodajesz feature do next-vibe, nie staje się tylko endpointem API. Działa wszędzie naraz.

Web API

Endpoint REST, w pełni walidowany i typowany

React UI

Dedykowany interaktywny interfejs - bez JSX

CLI

Każdy endpoint to polecenie z automatycznie generowanymi flagami

Narzędzie AI

Schemat function calling generowany automatycznie

Serwer MCP

Połącz Claude Desktop, Cursor, dowolny klient MCP

React Native

Ekrany iOS i Android z tej samej definicji

Cron Job

Zaplanuj dowolny endpoint na wyrażeniu cron

WebSocket

Wypchnij aktualizacje do podłączonych klientów po zakończeniu

Electron

Natywna aplikacja desktopowa przez te same kontrakty endpoint

Panel administracyjny

Automatycznie generowany panel admina - bez dedykowanego kodu

Widget VibeFrame

Osadzalny widget iframe dla dowolnej strony

Skill agenta

Wywoływalny przez agentów AI jako strukturalny skill

Węzeł Vibe Sense

Węzeł w grafie przepływu danych na żywo - ten sam endpoint

Supremacja TypeScript

Żadnego any. Żadnego unknown. Żadnego throw.

Typy muszą być całkowicie zgodne - bez wyjątków. To nie jest preferencja stylistyczna. To reguła strukturalna wymuszana w czasie budowania przez vibe check.

brak any

Zastąp prawdziwym typowanym interfejsem. Jeśli sięgasz po any, twoja architektura ma dziurę.

brak unknown

Ta sama reguła. unknown to tylko any z dodatkowymi krokami. Zdefiniuj typ.

brak gołego object

Gołe object jest bez znaczenia. Napisz kształt, którego naprawdę oczekujesz.

brak as X

Asercje typów to kłamstwa dla kompilatora. Napraw architekturę zamiast tego.

brak throw

Użyj ResponseType<T> z success(data) lub fail({message, errorType}). Błędy to dane.

brak zakodowanych stringów

Każdy string potrzebuje klucza tłumaczenia. Checker wykrywa nie przetłumaczone literały.

vibe check uruchamia Oxlint (Rust), ESLint i sprawdzanie typów TypeScript równolegle. Zero błędów wymagane przed wysyłką.

Zacznij

Sforkuj, zapytaj, wdróż.

Od pierwszego dnia na poziomie unbottled.ai.

1Forkuj i klonuj

Sforkuj na GitHub, potem sklonuj swój fork lokalnie.

bash
1git clone https://github.com/YOUR_USERNAME/next-vibe
2cd next-vibe && bun install
2Uruchom serwer

Do lokalnego dewelopmentu vibe dev uruchamia PostgreSQL w Dockerze, migracje, seeduje dane i daje hot reload. Na produkcji vibe build && vibe start robi pierwszy deploy. Potem używasz vibe rebuild, żeby aktualizować produkcję bez przestojów.

bash
1# development
2vibe dev
3
4# production - pierwsze uruchomienie
5vibe build && vibe start
6
7# production - po zmianach
8vibe rebuild
3Zaloguj jako admin

Otwórz aplikację i kliknij "Zaloguj jako admin" - kreator konfiguracji przeprowadzi przez klucze API i hasło admina.

4Zapytaj AI

Otwórz czat unbottled.ai lub Claude Code i opisz feature, który chcesz. AI napisze wszystkie pliki - definicję, route, widget, i18n - i automatycznie uruchomi vibe check.

bash
1# W czacie unbottled.ai lub Claude Code:
2"Zbuduj mi feature, który tłumaczy decyzje mojemu szefowi"
3# AI pisze wszystkie pliki i automatycznie uruchamia vibe check
Enterprise

Budujesz coś dużego?

Pomagamy zespołom przy konfiguracji, niestandardowych integracjach, przeglądzie architektury i bieżącym wsparciu deweloperskim. Ta sama baza kodu, twój deployment.

Skontaktuj się z nami
Prawdziwa osoba to przeczyta i odpowie. Bez botów, bez runaround.