← Blog
AI15 min czytania

NextChat — lekki klient do Claude, GPT, Gemini i DeepSeek

Osiemdziesiąt osiem tysięcy gwiazdek, licencja MIT, wdrożenie na Vercela jednym kliknięciem i szesnaście obsługiwanych dostawców modeli — własny czat firmowy na własnych kluczach API zamiast abonamentu za stanowisko. Omawiamy język konfiguracji listy modeli, bez którego klient utknął na modelach z połowy 2025 roku, hasło dostępu, którego brak wystawia Twój klucz API całemu internetowi, oraz to, co dokładnie w tym projekcie jest darmowe, a co sprzedażą.

Pytanie wraca u nas w co drugim projekcie: klient chce, żeby jego zespół mógł korzystać z Claude'a i GPT w jednym miejscu, z zachowaniem historii rozmów i bez wysyłania firmowych danych do losowej aplikacji. Abonament za stanowisko przy dziesięciu osobach robi się kosztem stałym, a przy dwudziestu — pozycją w budżecie, o której ktoś zapyta.

Alternatywa jest prosta i mało kto z niej korzysta: własny interfejs czatu na własnych kluczach API, gdzie płaci się za zużyte tokeny, a nie za krzesła. Rozmowy zostają w przeglądarce, klucz zostaje na serwerze, a wdrożenie kosztuje kwadrans.

NextChat (github.com/ChatGPTNextWeb/NextChat) jest najpopularniejszym narzędziem tej klasy — aplikacją w Next.js na licencji MIT, którą stawia się na Vercelu jednym kliknięciem, w Dockerze albo jako pięciomegabajtową aplikację desktopową w Tauri. Obsługuje szesnastu dostawców modeli, trzyma dane lokalnie w przeglądarce i ma jeden mechanizm konfiguracji, bez którego całe wdrożenie utknie na modelach z połowy 2025 roku. Od niego zacznę, bo to najbardziej praktyczna rzecz w tym tekście.

Stan projektu

Dane z API GitHuba na 30 września 2026:

  • 88 716 gwiazdek i — co jest liczbą zdumiewającą — 59 108 forków. Stosunek forków do gwiazdek bliski dwóm trzecim znaczy, że ludzie nie tyle obserwują ten projekt, ile go klonują i wdrażają u siebie,
  • utworzony 10 marca 2023, licencja MIT, kod w TypeScripcie,
  • ostatnie wydanie v2.16.1 z 29 lipca 2025 — czternaście miesięcy temu,
  • commity z ostatniego roku to głównie testy jednostkowe od osób z zewnątrz (lipiec 2026) i aktualizacja README (sierpień 2026); prac nad funkcjami praktycznie nie ma,
  • 859 otwartych zgłoszeń.

Czternaście miesięcy bez wydania to przy kliencie do modeli językowych zauważalny problem, bo modele i ich identyfikatory zmieniają się co kwartał. Za chwilę pokażę, dlaczego w tym konkretnym przypadku nie jest to blokada — ale trzeba o tym wiedzieć przed wdrożeniem, nie po.

Trzeba też powiedzieć, czym ten projekt stał się komercyjnie, bo zmieniło się to zauważalnie. Opis repozytorium jest dziś reklamą usługi hostowanej — obiecuje czat bez własnego klucza API, po rejestracji, z rozliczeniem za zużycie. README prowadzi do aplikacji w App Store, do wersji SaaS na nextchat.club i do edycji Enterprise z personalizacją marki, panelem administracyjnym, kontrolą uprawnień, integracją bazy wiedzy i audytem bezpieczeństwa, z adresem kontaktowym dla firm. Są też dwa banery sponsorskie, a jeden ze sponsorów ma w kodzie własne zmienne środowiskowe.

Sprawiedliwie: klient open source pozostaje na MIT i jest w pełni funkcjonalny. Nie ma tu okrojenia funkcji ani paywalla w kodzie — lej sprzedażowy jest w README, nie w repozytorium. Ale kierunek uwagi zespołu widać po tym, gdzie od czternastu miesięcy nie ma wydań.

Szesnastu dostawców w jednym interfejsie

Trasy API w kodzie zdradzają zakres integracji lepiej niż lista marketingowa. Klient ma osobne ścieżki dla: OpenAI, Azure OpenAI, Anthropic, Google, DeepSeek, xAI, Moonshot, ChatGLM, SiliconFlow, Baidu, ByteDance, Alibaba, Tencent, iFlytek, Stability oraz platformy sponsora. Każdy dostawca ma własne zmienne środowiskowe na klucz i — co ważniejsze — na adres bazowy:

OPENAI_API_KEY=sk-...
BASE_URL=https://twoje-proxy.example.com
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_URL=https://...
GOOGLE_API_KEY=...
DEEPSEEK_API_KEY=...
AZURE_URL=https://twoj-resource.openai.azure.com/openai
AZURE_API_KEY=...
AZURE_API_VERSION=...

Możliwość nadpisania adresu bazowego przy każdym dostawcy jest praktyczniejsza, niż wygląda. Pozwala wstawić przed model własne proxy — do logowania zapytań, limitowania kosztów albo trzymania ruchu w jednej jurysdykcji — nie dotykając kodu klienta. Klucze można też podać po kilka, rozdzielone przecinkiem.

Warto przy tym zauważyć, kim jest połowa tej listy: Baidu, ByteDance, Alibaba, Tencent, iFlytek, ChatGLM i Moonshot to dostawcy chińscy. To nie jest wada, ale mówi o pochodzeniu projektu i o tym, dla kogo był pisany. W naszych wdrożeniach użyjemy czterech, może pięciu tras z szesnastu.

Rzecz najważniejsza: lista modeli i jak ją naprawić

Wbudowana lista modeli w gałęzi głównej kończy się tam, gdzie skończyły się wydania. Dla Anthropic ostatnie pozycje to claude-sonnet-4-20250514 i claude-opus-4-20250514, dla Google gemini-2.5-pro-preview-06-05, a dla OpenAI wpisy z rodziny gpt-5 w wariancie zapowiedzianym na początek 2025 roku. Wszystko, co wyszło później — a wyszło dużo — w domyślnej liście nie istnieje.

Gdyby na tym się kończyło, nie warto byłoby o tym projekcie pisać. Kończy się jednak na czymś innym: na zmiennej CUSTOM_MODELS, która jest małym językiem konfiguracji listy modeli i rozwiązuje problem w całości, bez dotykania kodu. Składnia ma cztery operatory:

  • +nazwa dodaje model do listy,
  • -nazwa ukrywa model,
  • nazwa=etykieta zmienia nazwę wyświetlaną,
  • -all wyłącza wszystkie modele domyślne, +all włącza je z powrotem.

W praktyce najlepszym wzorcem dla wdrożenia firmowego jest wyzerowanie listy i wpisanie dokładnie tego, co ma być dostępne:

CUSTOM_MODELS=-all,+claude-opus-5=Claude Opus 5,+claude-sonnet-5=Claude Sonnet 5,+gpt-5
DEFAULT_MODEL=claude-sonnet-5

Zysk jest podwójny. Po pierwsze, lista przestaje być zależna od wydań projektu — identyfikator modelu podajesz sam, więc nowy model jest dostępny w dniu premiery, a nie w dniu wydania klienta. Po drugie, użytkownicy widzą trzy modele zamiast osiemdziesięciu, w tym żadnego przeterminowanego i żadnego, którego koszt kogoś zaskoczy. Przy Azure jest jeszcze wariant nazwa@Azure=deployment, mapujący identyfikator modelu na nazwę wdrożenia — czyli dokładnie to, czego wymaga Azure OpenAI.

Dodatkowo VISION_MODELS pozwala dorzucić obsługę obrazów modelom, których wbudowane wykrywanie po nazwie nie rozpoznaje. Wykrywanie działa na wzorcach nazw, więc każdy model nazwany inaczej niż oczekiwano trzeba dopisać ręcznie.

Hasło dostępu, którego brak kosztuje

To jest część, na której robi się najgroźniejszy błąd wdrożenia, a mechanizm jest jedną zmienną. Wdrożenie na Vercela daje publiczny adres, a klucz API leży w zmiennej środowiskowej na serwerze. Bez ochrony każdy, kto trafi na ten adres, rozmawia z modelem na Twój rachunek — bez limitu i bez śladu, kto to był.

CODE=haslo-zespolu,haslo-zarzadu
HIDE_USER_API_KEY=1
DISABLE_FAST_LINK=1
  • CODE to hasło dostępu, można podać kilka po przecinku. Nie jest to system kont — nie ma tu użytkowników, ról ani rejestru logowań. To wspólne hasło, nie uwierzytelnianie, i tak trzeba je traktować: nadaje się do zespołu, w którym wszyscy mają ten sam poziom dostępu, i nie nadaje się do niczego, co wymaga rozliczalności,
  • HIDE_USER_API_KEY=1 zabiera użytkownikom możliwość wpisania własnego klucza,
  • DISABLE_FAST_LINK=1 wyłącza wczytywanie ustawień z adresu URL. Warto to zrobić: skoro ustawienia da się przekazać linkiem, to linkiem da się też komuś podmienić konfigurację,
  • DISABLE_GPT4=1 odcina drogie modele, jeśli wdrożenie ma być tanie z założenia,
  • ENABLE_BALANCE_QUERY pozwala użytkownikom sprawdzić stan konta u dostawcy — przy wdrożeniu firmowym raczej rzecz do zostawienia wyłączoną.

Kolejność jest tu jedyna właściwa: CODE ustawia się przed pierwszym wdrożeniem, nie po. Publiczny adres z aktywnym kluczem, choćby na kwadrans, wystarczy, żeby ktoś go znalazł — takie instancje są skanowane automatycznie.

Wdrożenie: trzy drogi i jedna zalecana

Wymagania są skromne: Node.js 18 lub nowszy, Docker 20 lub nowszy. Dokumentacja podaje trzy drogi wdrożenia i wskazuje Dockera jako zalecaną — słusznie, bo daje najmniej niespodzianek:

docker run -d -p 3000:3000 \
   -e OPENAI_API_KEY=sk-xxxx \
   -e CODE=twoje-haslo \
   yidadaa/chatgpt-next-web

Jeśli ruch wychodzący ma iść przez proxy — a w części wdrożeń firmowych musi — służy do tego PROXY_URL, także w wariancie z uwierzytelnianiem, gdzie użytkownika i hasło podaje się po spacji w tej samej zmiennej. Obsługę MCP w obrazie Dockera włącza się zmienną kontenera ENABLE_MCP=true; przy budowaniu z kodu README każe ustawić ją przed budowaniem, więc przy własnym pipeline'ie trzeba o niej pamiętać na etapie budowy obrazu, nie uruchomienia.

Druga droga to Vercel jednym kliknięciem — najszybsza i jednocześnie ta, w której najłatwiej zapomnieć o CODE. Trzecia to skrypt instalacyjny uruchamiany przez potok z curl do bash; działa, ale to jest dokładnie ten wzorzec, którego w firmowej infrastrukturze nie wykonujemy bez przeczytania skryptu — tym bardziej że pobiera go ze starego adresu repozytorium.

Ta ostatnia uwaga dotyczy zresztą całej dokumentacji wdrożeniowej: obraz Dockera nadal nazywa się yidadaa/chatgpt-next-web, czyli poprzednią nazwą projektu. Wszystko działa, ale warto wiedzieć, że sięgasz po obraz z konta o innej nazwie niż repozytorium — przy weryfikacji pochodzenia obrazu w firmie z procedurami to bywa pytanie do wyjaśnienia.

Do rozwoju lokalnego wystarczy plik .env.local z kluczem, yarn install i yarn dev — projekt jest zwykłą aplikacją Next.js bez własnego narzędziowania, więc jeśli ktoś w zespole robi frontend w React, poczuje się od razu jak u siebie i zmiana marki jest kwestią godzin.

Gdzie mieszkają dane

Model przechowywania jest prosty i to jego zaleta: rozmowy leżą lokalnie w przeglądarce użytkownika, nie na serwerze. Serwer jest pośrednikiem do API i niczym więcej, więc wdrożenie nie tworzy nowego zbioru danych do zabezpieczenia — co przy rozmowach o RODO z klientem skraca dyskusję o połowę.

Konsekwencja jest jednak dwustronna i trzeba ją powiedzieć wprost: wyczyszczenie danych witryny kasuje całą historię, a rozmowy nie przenoszą się między przeglądarkami ani urządzeniami. Synchronizacja jest opcjonalna i ma dwa warianty: WebDAV oraz UpStash, czyli hostowany Redis, na który dokumentacja ma osobną stronę w pięciu językach.

Przy WebDAV kluczowa jest zmienna WHITE_WEBDAV_ENDPOINTS, ustalająca listę dopuszczonych adresów. To sensowne domyślne ograniczenie i warto rozumieć, dlaczego istnieje: bez niego dowolny użytkownik mógłby w ustawieniach skonfigurować wysyłanie całej historii rozmów na dowolny serwer w internecie. Przy wdrożeniu, w którym w rozmowach pojawiają się dane klientów, ta lista nie jest opcją — jest wymogiem.

Co jeszcze dostajesz w pudełku

  • Aplikacja desktopowa w Tauri — około pięciu megabajtów na Windowsa, macOS i Linuksa. Dla porównania: klient Electronowy tej samej klasy waży zwykle sto kilkadziesiąt,
  • PWA, tryb ciemny, projekt responsywny i pierwsze wczytanie w okolicach stu kilobajtów,
  • Szablony rozmów („maski") — zapisane zestawy promptu systemowego, modelu i parametrów. To jest funkcja, która w firmie robi najwięcej dobrego: „odpowiedz na reklamację", „streść notatkę ze spotkania", „przepisz na prostszy polski" jako gotowe wejścia, zamiast każdorazowego pisania instrukcji od zera,
  • Artefakty — podgląd, kopiowanie i udostępnianie wygenerowanych stron w osobnym oknie,
  • Wtyczki z wyszukiwaniem sieciowym i kalkulatorem oraz możliwością podpięcia własnego API,
  • Obsługa MCP — włączana zmienną ENABLE_MCP=true przed budowaniem, nie w ustawieniach. Łatwo to przeoczyć i uznać, że funkcji nie ma,
  • Markdown z LaTeksem, diagramami mermaid i kolorowaniem kodu, automatyczne streszczanie długiej historii rozmowy, żeby oszczędzać tokeny,
  • Interfejs w czternastu językach — z polskim niestety nie w tym zestawie,
  • Generowanie obrazów przez API Stability, jako osobna sekcja.

Minimalna konfiguracja, którą bym wdrożył

Zbierając wszystko powyżej w jedno miejsce — tak wyglądałby zestaw zmiennych dla firmowego wdrożenia na dziesięć osób, gdzie żadna z decyzji nie jest przypadkowa:

ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-...

CODE=haslo-zespolu
HIDE_USER_API_KEY=1
DISABLE_FAST_LINK=1

CUSTOM_MODELS=-all,+claude-sonnet-5=Claude Sonnet 5,+claude-opus-5=Claude Opus 5,+gpt-5
DEFAULT_MODEL=claude-sonnet-5

WHITE_WEBDAV_ENDPOINTS=https://webdav.firma.example/dav

Trzy pierwsze bloki zamykają wdrożenie przed światem, czwarty uwalnia je od tempa wydań projektu, a piąty pilnuje, żeby historia rozmów nie mogła zostać zsynchronizowana byle gdzie. To jest cała konfiguracja — nie ma tu bazy danych, migracji ani panelu administracyjnego do skonfigurowania.

Pułapki

  • Czternaście miesięcy bez wydania i prace ograniczone do testów oraz README. Projekt działa, ale nie rozwija się,
  • Wbudowana lista modeli jest zamrożona na połowie 2025 roku. Bez CUSTOM_MODELS wdrożenie startuje z przeterminowanym menu,
  • CODE to wspólne hasło, nie konta. Brak rozliczalności, brak ról, brak rejestru dostępu. Do audytu i uprawnień służy płatna edycja Enterprise — i to jest uczciwa granica między wersją darmową a komercyjną,
  • Wdrożenie jednym kliknięciem daje publiczny adres z aktywnym kluczem API. Bez CODE to jest rachunek wystawiony internetowi,
  • Historia rozmów żyje w przeglądarce — czyszczenie danych witryny ją kasuje, a synchronizacja wymaga WebDAV,
  • MCP wymaga flagi środowiskowej — w obrazie Dockera jako zmiennej kontenera, przy własnym budowaniu przed budowaniem — a nie przełącznika w interfejsie,
  • Dokumentacja ma dziury dokładnie tam, gdzie byłaby przydatna. Przewodnik po wdrożeniu na Vercela istnieje wyłącznie po chińsku, podręcznik użytkownika też i jest oznaczony jako niedokończony, a instrukcja wdrożenia na Cloudflare jest wprost opisana jako przestarzała. Po angielsku są FAQ, synchronizacja rozmów i instrukcja dodawania tłumaczeń,
  • Obraz Dockera i skrypt instalacyjny wskazują na starą nazwę projektu, a skrypt uruchamia się potokiem z curl do bash — w firmowej infrastrukturze do przeczytania przed uruchomieniem,
  • Aplikacja na iOS nie jest open source — README zapowiada kod źródłowy, ale wskazane repozytorium go nie zawiera,
  • 859 otwartych zgłoszeń przy 59 tysiącach forków. Zgłoszenie błędu raczej nie doczeka się odpowiedzi,
  • Linki do wydań desktopowych w README prowadzą do starej nazwy repozytorium (Yidadaa/ChatGPT-Next-Web) — działają przez przekierowanie, ale są śladem, jak dawno nikt nie czytał tego pliku od początku do końca,
  • Brak polskiego w interfejsie przy czternastu innych językach.

Gdzie to ma sens w naszej pracy

  • Wspólny czat firmowy na jednym kluczu. Dziesięć osób, rozliczenie za tokeny, hasło dostępu, lista trzech modeli. Przy typowym użyciu biurowym koszt tokenów jest wielokrotnie niższy od abonamentów za stanowiska,
  • Czat pod marką klienta. MIT plus Next.js znaczy, że zmiana logo, kolorów i domeny to praca na godziny, nie na dni. Klient dostaje narzędzie ze swoim szyldem, bez opłaty licencyjnej,
  • Porównywanie modeli na własnych zadaniach. Jedna instancja z Claude'em, GPT i Gemini pozwala wkleić ten sam prompt trzy razy i zobaczyć różnicę na własnych treściach, a nie na benchmarkach,
  • Biblioteka promptów jako maski. Powtarzalne zadania zespołu zapisane jako gotowe szablony — najprostsza droga, żeby ludzie nietechniczni korzystali z modeli sensownie,
  • Instancja z własnym proxy, jeśli klient wymaga logowania zapytań albo trzymania ruchu w określonej jurysdykcji. Nadpisywalny adres bazowy przy każdym dostawcy jest do tego wystarczający.

Czego NextChat nie zastąpi: platformy AI dla firmy z kontami, SSO, uprawnieniami do baz wiedzy i audytem. Tego w wersji open source nie ma i nie udaje, że ma — jest to zakres płatnej edycji Enterprise. Jeśli klient potrzebuje rozliczalności „kto zapytał o co i kiedy", to jest inny projekt i inny budżet.

Podsumowanie

  • MIT, Next.js, wdrożenie na Vercela jednym kliknięciem, Docker albo pięciomegabajtowa aplikacja desktopowa w Tauri,
  • Szesnastu dostawców z osobnymi kluczami i — co przydatniejsze — nadpisywalnymi adresami bazowymi,
  • Ustaw CUSTOM_MODELS z -all i jawną listą modeli. To jedna zmienna, która uwalnia wdrożenie od tempa wydań projektu,
  • Ustaw CODE przed pierwszym wdrożeniem, a razem z nim HIDE_USER_API_KEY i DISABLE_FAST_LINK,
  • Dane rozmów zostają w przeglądarce — mniej do zabezpieczenia, ale i mniej trwałości; synchronizacja przez WebDAV z listą dopuszczonych adresów,
  • Maski są najbardziej niedocenianą funkcją przy wdrożeniu dla zespołu nietechnicznego,
  • MCP włącza się flagą przed budowaniem,
  • Projekt jest w trybie utrzymania, a uwaga zespołu przeniosła się na usługę hostowaną i edycję Enterprise. Klient open source działa i jest kompletny, ale nowych funkcji nie oczekuj,
  • Konta, role i audyt to zakres płatny — jeśli ich potrzebujesz, wybierz świadomie, nie po wdrożeniu.

Licencja: NextChat jest na MIT, czyli w najbardziej wygodnym możliwym układzie dla agencji: wolno używać komercyjnie, modyfikować, zmieniać marki i kolory, wdrażać u klientów i redystrybuować, przy zachowaniu noty licencyjnej i tekstu licencji. Nie ma tu open core — cały klient, aplikacja desktopowa, wtyczki i obsługa MCP są w tym samym repozytorium na tej samej licencji, a płatna edycja Enterprise nie odbiera niczego wersji otwartej; dokłada osobny produkt z kontami, uprawnieniami i audytem. Trzy rzeczy warto natomiast rozdzielić, bo łatwo je pomylić z licencją kodu. Po pierwsze, aplikacja na iOS nie jest objęta tym repozytorium i jej kodu nie ma, mimo zapowiedzi w README. Po drugie, usługa hostowana na nextchat.club to zupełnie osobna umowa z własnym regulaminem i własnym przetwarzaniem danych — z tego, że klient jest na MIT, nie wynika nic o tym, co dzieje się z rozmowami w wersji SaaS. Po trzecie i najważniejsze przy rozmowie z klientem: licencja klienta nie mówi nic o warunkach dostawców modeli. Regulaminy OpenAI, Anthropic czy Google'a, ich zasady przetwarzania danych i retencji obowiązują tak samo, jak przy każdej innej integracji — a to one, nie licencja interfejsu, decydują o tym, czy dane klienta mogą wyjść z jego infrastruktury.