Blog
Low-code18 min czytania

ToolJet — budowa narzędzi wewnętrznych metodą drag-and-drop

Platforma do paneli administracyjnych i aplikacji operacyjnych działających na istniejących bazach i API: 80 komponentów, 90 źródeł danych, JavaScript i Python w środku, a od niedawna także budowanie agentem kodującym przez serwer MCP. Rozbieramy dokładnie podział na edycję społecznościową i płatną — bo workflowy, GitSync, wiele środowisk i RBAC są po stronie enterprise — konfigurację produkcyjną z workerami i Redisem oraz rachunek z AGPL-3.0. Plus uczciwe porównanie z Filamentem: kiedy klikać, a kiedy pisać.

Klient prosi o panel do przeglądania zamówień, zmiany statusu i wysłania maila do kuriera. Zbudowanie tego w Laravelu z Filamentem to dzień, może dwa, i jest to dobra robota — panel dzieli modele z aplikacją, korzysta z jej polityk i walidacji, a zmiana w domenie propaguje się sama.

Są jednak zadania, w których ta droga jest przerostem. Panel potrzebny na tydzień, do jednorazowej migracji danych. Widok łączący informacje z trzech różnych systemów, do których nie mamy modeli i nie chcemy ich mieć. Narzędzie dla dwóch osób z działu obsługi, które ma powstać na jutro i będzie się zmieniać co tydzień, bo proces jeszcze się nie ustalił. W każdym z tych przypadków warto zadać pytanie, czy tego nie da się po prostu wyklikać.

ToolJet (github.com/ToolJet/ToolJet) jest platformą do dokładnie tego: paneli administracyjnych, dashboardów i aplikacji operacyjnych działających na istniejących bazach, API i systemach SaaS. Buduje się je wizualnie, promptem — albo, i to jest najświeższa część, agentem kodującym przez serwer MCP.

Poniżej: co realnie dostajemy w wersji darmowej, gdzie dokładnie przebiega granica z płatną (to jest najważniejsza część wpisu, bo granica leży w nieoczywistym miejscu), jak wygląda konfiguracja produkcyjna, oraz uczciwe porównanie z Filamentem — bo dla zespołu piszącego w Laravelu to jest prawdziwa alternatywa, którą trzeba rozważyć.

Stan projektu

Dane z API GitHuba na 23 września 2026:

  • 40 870 gwiazdek i 5442 forki, kod w JavaScripcie, licencja AGPL-3.0,
  • repozytorium założone 30 marca 2021, ostatni commit z 9 września 2026,
  • 89 commitów w dwa i pół tygodnia — rozwój prowadzi firma i tempo jest wysokie,
  • 1202 otwarte zgłoszenia,
  • dwa kanały wydań: LTS i beta, z wydaniami niemal codziennymi. Na dzień pisania: v3.20.225-lts z 9 września i v3.21.69-beta z 7 września.

Do produkcji dokumentacja zaleca wersję LTS, nie najnowszą — z uzasadnieniem, że LTS zapewnia stabilność z poprawkami błędów produkcyjnych, łatkami bezpieczeństwa i usprawnieniami wydajności. Przy kanale beta wydawanym co drugi dzień jest to rada, którą warto potraktować dosłownie.

Gdzie przebiega granica między darmowym i płatnym

To jest część, którą trzeba przeczytać przed jakąkolwiek decyzją, bo granica nie leży tam, gdzie zwykle w modelu open core. Zacznijmy od tego, co jest w edycji społecznościowej na AGPL-3.0:

  • Wizualny builder z ponad 80 responsywnymi komponentami — tabele, wykresy, formularze, listy, paski postępu i dalej,
  • ToolJet Database — wbudowana baza bez kodu, gdy dane nie mają jeszcze swojego miejsca,
  • aplikacje wielostronicowe i edycja wieloosobowa w czasie rzeczywistym,
  • ponad 90 źródeł danych — bazy, API, magazyny chmurowe, narzędzia SaaS,
  • wdrożenie na Dockerze, Kubernetesie, AWS, GCP i Azure,
  • komentarze w miejscu, wzmianki i granularna kontrola dostępu,
  • rozszerzalność — własne wtyczki i konektory przez ToolJet CLI,
  • JavaScript i Python wewnątrz aplikacji — czyli tam, gdzie klikanie się kończy, wpisuje się kod,
  • szyfrowanie AES-256-GCM, przepływ danych wyłącznie przez proxy i obsługa SSO.

To jest kompletny zestaw do budowania aplikacji. A teraz lista tego, co jest w edycji płatnej — i warto na nią spojrzeć uważnie:

  • Generowanie aplikacji z promptu, AI query builder, AI debugging, Agent Builder,
  • Workflows — automatyzacja procesów wieloetapowych z logiką warunkową, na harmonogramie albo z webhooka,
  • Modules — reużywalne jednostki interfejsu i logiki, budowane raz i używane w wielu aplikacjach,
  • RBAC z grupami własnymi i SCIM, granularne uprawnienia do aplikacji i danych,
  • wiele środowisk — dev, stage, prod,
  • GitSync i CI/CD — integracja z GitHubem i GitLabem, historia wersji aplikacji, uporządkowane wdrożenia,
  • kontrola dostępu na poziomie wiersza, komponentu, strony i zapytania,
  • white-label, własne domeny i motywy, aplikacje osadzane w innych systemach,
  • audyt, gotowość SOC 2 i RODO, wsparcie z SLA.
Zwróć uwagę na cztery pozycje z tej drugiej listy: Workflows, GitSync, wiele środowisk i RBAC. To dokładnie te rzeczy, których profesjonalne wdrożenie chce najbardziej — automatyzacja, review zmian, rozdział dev od produkcji i porządne uprawnienia. Edycja społecznościowa jest kompletna do budowania narzędzi, ale nie do zarządzania ich cyklem życia w zespole. To nie jest zarzut wobec modelu biznesowego — to informacja, którą trzeba mieć przed wyceną.

Sam podział jest przy tym czysty: repozytorium ma jedną licencję AGPL-3.0, a kod edycji płatnej nie leży w nim wcale (wpis frontend/ee jest zaślepką, nie katalogiem z kodem). Nie ma więc sytuacji z plikami objętymi inną licencją wewnątrz tego samego drzewa, którą widzieliśmy przy n8n.

Źródła danych — co konkretnie jest w zestawie

Liczba „ponad 90 źródeł danych" z materiałów marketingowych obejmuje warianty i typy zapytań, więc warto zajrzeć do samego repozytorium. Katalog wtyczek zawiera 49 pakietów, a ich lista mówi o narzędziu więcej niż jakikolwiek opis:

  • Bazy relacyjne: PostgreSQL, MySQL, MariaDB, MS SQL, OracleDB, IBM Db2, SAP HANA, Snowflake, Databricks, BigQuery, Athena, ClickHouse,
  • Bazy nierelacyjne i wyszukiwanie: MongoDB, Redis, Elasticsearch, Typesense, CouchDB, RethinkDB, DynamoDB, CosmosDB, Firestore, InfluxDB,
  • Magazyny obiektowe: S3, MinIO, Google Cloud Storage, Azure Blob Storage,
  • Protokoły ogólne: REST API, GraphQL, gRPC (w dwóch wersjach), OpenAPI — czyli cokolwiek, co ma API, wchodzi bez pisania wtyczki,
  • Arkusze i bazy „no-code": Google Sheets (dwie wersje), Airtable, Baserow, NocoDB, Notion, Appwrite,
  • Poczta i komunikacja: SMTP, SendGrid, Mailgun, Amazon SES, Twilio, Slack,
  • Systemy biznesowe: Stripe, WooCommerce, Zendesk,
  • Automatyzacja: n8n — czyli platforma, którą opisywaliśmy w tej serii, jest tu źródłem danych.

Dla naszego stacku istotne są trzy pozycje z tej listy. PostgreSQL i MySQL oznaczają, że panel operacyjny można postawić bezpośrednio nad bazą aplikacji w Laravelu. REST API oznacza, że można to zrobić czyściej — nad naszymi endpointami, z zachowaniem walidacji i polityk po stronie PHP. A n8n pozwala złożyć układ, w którym ToolJet jest interfejsem, a n8n silnikiem procesu — co przy edycji społecznościowej ToolJeta, gdzie workflowy są płatne, jest realną alternatywą architektoniczną, nie obejściem.

Do tego dochodzi ToolJet CLI do pisania własnych wtyczek i konektorów, gdy czegoś na liście brakuje — dostępne w edycji społecznościowej.

Model bezpieczeństwa danych

Dwa elementy z listy funkcji zasługują na rozwinięcie, bo decydują o tym, czy narzędzie wolno wpuścić do produkcyjnej bazy.

Szyfrowanie AES-256-GCM obejmuje zapisane poświadczenia do źródeł danych — i tu wraca sprawa klucza LOCKBOX_MASTER_KEY, o którym niżej. To on jest kluczem głównym tego szyfrowania, więc jego utrata oznacza nie tylko brak dostępu, ale konieczność wpisania od nowa wszystkich haseł do wszystkich systemów podłączonych do platformy.

Przepływ danych wyłącznie przez proxy to deklaracja, że dane ze źródeł nie są przechowywane w ToolJecie — przechodzą przez serwer aplikacji do przeglądarki użytkownika i tam kończą. Konsekwencja praktyczna jest istotna przy rozmowie z klientem: ToolJet nie staje się kolejną kopią jego bazy, a serwer platformy nie jest miejscem, z którego wyciekną dane historyczne, bo ich tam nie ma. Za to staje się miejscem, z którego wyciekłyby poświadczenia — i dlatego to tam trzeba skupić uwagę.

Z tego wynika reguła, którą powtórzymy jeszcze w podsumowaniu: użytkownik bazy danych dla ToolJeta jest dedykowany i ma minimalny możliwy zakres uprawnień. Panel do przeglądania zamówień nie potrzebuje prawa DROP, a bardzo często nie potrzebuje nawet DELETE. To jest jedyna warstwa, która działa niezależnie od tego, kto i jak zmieni aplikację w builderze.

Budowanie agentem przez MCP

Najświeższa i najciekawsza część projektu, warta uwagi niezależnie od tego, czy ToolJet nas interesuje — bo pokazuje sposób integracji agentów z platformą, który nie polega na generowaniu kodu.

ToolJet wystawia serwer Model Context Protocol, dzięki któremu agent kodujący buduje aplikacje ToolJeta bezpośrednio: generuje strony, zapytania i komponenty z promptu oraz modyfikuje istniejące aplikacje w miejscu. Działa to jako wtyczki dołączające skill buildera ToolJeta dla Claude Code, Codeksa i Grok Build, a dla Cursora i innych klientów — przez sam serwer MCP.

Kluczowe zdanie z dokumentacji jest jednak inne i warto je rozłożyć: agenci budują na podstawie rzeczywistych kontraktów komponentów i danych platformy, a nie emitują dowolny kod. Skutek jest taki, że wynikiem nie jest kod do utrzymania, a prawdziwa aplikacja ToolJeta — którą zespół dalej edytuje w builderze wizualnym, pod tymi samymi uprawnieniami, środowiskami i historią wersji co wszystko inne.

To jest istotna różnica wobec podejścia „poproś model o wygenerowanie panelu w Reakcie". Tam dostajemy kod, którego nikt nie recenzował i który od razu staje się długiem. Tu dostajemy artefakt platformy, z którym platforma umie dalej pracować — i który człowiek może poprawić klikaniem, bez czytania cudzego kodu.

Dwa szczegóty praktyczne. Pierwszy, finansowy: operacje idą na naszej własnej subskrypcji modelu, a nie z kredytów ToolJet AI — czyli agent kodujący, który już mamy, wystarcza. Drugi, ostrożnościowy: ToolJet MCP jest w wersji beta.

Uruchomienie

Do sprawdzenia narzędzia wystarczy jedno polecenie, z Postgresem wewnątrz kontenera:

docker run \
  --name tooljet \
  --restart unless-stopped \
  -p 80:80 \
  --platform linux/amd64 \
  -v tooljet_data:/var/lib/postgresql/13/main \
  tooljet/try:ee-lts-latest

Do produkcji obraz i konfiguracja są inne, a wymagania warto znać przed pierwszym wdrożeniem:

  • Dwa sekrety generowane skryptami wdrożeniowymiLOCKBOX_MASTER_KEY i SECRET_KEY_BASE. To one chronią zapisane poświadczenia do źródeł danych, więc ich utrata oznacza utratę wszystkich konfiguracji połączeń,
  • PostgreSQL — poświadczenia podawane zmiennymi; można użyć bazy wbudowanej w obraz albo zewnętrznej (na produkcji: zewnętrznej),
  • TOOLJET_HOST musi zaczynać się od http:// albo https:// — drobiazg, który przy pominięciu daje niejasne objawy,
  • Przy wielu workerach zewnętrzny Redis jest wymagany, nie opcjonalny — kolejka zadań potrzebuje wspólnego miejsca. Dokumentacja podaje konkretne flagi trwałości: --appendonly yes --maxmemory-policy noeviction,
  • Workery uruchamia się z WORKER=true i bez wystawionych portów, z równoległością sterowaną przez TOOLJET_WORKFLOW_CONCURRENCY (domyślnie 5); serwer webowy dostaje SERVE_CLIENT: true,
  • przy certyfikacie samopodpisanym trzeba wskazać go zmienną NODE_EXTRA_CA_CERTS.

Dwie uwagi o obrazach i o tym, co z nich wynika. Dokumentacja wdrożeniowa podaje jako domyślny obraz tooljet/tooljet:ee-lts-latest oraz wersje w konwencji v3.x.x-lts — czyli dokumentowana ścieżka to obraz edycji płatnej, uruchamiany bez licencji w zakresie edycji społecznościowej. Obraz społecznościowy istnieje osobno (tooljet/tooljet-ce), ale w tej części dokumentacji nie jest wymieniony. Nie jest to problem, tylko rzecz, którą lepiej wybrać świadomie niż odkryć.

Rzecz druga jest ważniejsza i dotyczy prywatności. Dokumentacja wymaga, żeby dla funkcji AI odblokować w sieci ruch do api-gateway.tooljet.ai i python-server.tooljet.ai. Oznacza to, że także w instalacji na własnym serwerze część funkcji rozmawia z infrastrukturą dostawcy. Klientowi, który wybrał self-hosting właśnie po to, żeby nic nie wychodziło poza jego sieć, trzeba to powiedzieć wprost — funkcje AI albo pozostają wyłączone, albo warunek „nic nie wychodzi" przestaje być spełniony.

Gdzie to postawić

Elastyczność wdrożenia jest tu realną zaletą i warto ją wypunktować, bo przy narzędziach tej kategorii często kończy się na „Docker albo chmura dostawcy". ToolJet ma osobne przewodniki dla:

  • Dockera i DigitalOcean — najkrótsza droga dla jednego serwera,
  • AWS EC2, AWS ECS i AWS EKS, GCP GKE, Azure AKS, Azure Container, Google Cloud Run,
  • Helm — dla istniejącego klastra Kubernetesa,
  • OpenShift — rzadko spotykane w projektach open source i istotne przy klientach korporacyjnych,
  • wdrożenie samego klienta osobno oraz wdrożenie na podścieżce — to drugie ratuje sytuację, gdy klient nie da osobnej subdomeny.

Projekt jest też obecny na AWS Marketplace i Azure Marketplace, co w praktyce oznacza jedno: przy kliencie, który ma budżet chmurowy i procedurę zakupową opartą o marketplace dostawcy, wdrożenie ToolJeta da się przeprowadzić bez oddzielnej umowy. Dla agencji pracującej z korporacjami to potrafi być argument rozstrzygający — nie techniczny, ale decydujący o tym, czy projekt w ogóle wystartuje.

Model rozgałęzień w repozytorium to git-flow z gałęzią bazową develop; stabilnych wersji szuka się w gałęzi main i w tagach. Warto o tym pamiętać, jeśli kiedykolwiek przyjdzie budować obraz z własnej gałęzi.

Uwaga na marginesie: instrukcje dla agentów w repozytorium

Rzecz, która przy trzecim projekcie w tej serii przestaje być przypadkiem i zaczyna być wzorcem. Repozytorium ToolJeta zawiera katalogi .agents/ i .claude/ oraz pliki AGENTS.md i CLAUDE.md we froncie, a jeden z ostatnich commitów nosi tytuł „standardise skill placement and symlink layout".

Ten sam wzorzec widzieliśmy w tej serii u Prowlera (21 reguł zadaniowych plus zewnętrzne repozytorium skilli) i w szablonie storefrontu Saleora (21 reguł z plikiem blokującym wersje). Trzy niezależne projekty, trzy różne kategorie, ta sama decyzja: instrukcje dla asystentów kodujących leżą w repozytorium, są wersjonowane razem z kodem i podlegają tym samym regułom co reszta — łącznie z porządkowaniem układu katalogów w osobnym commicie.

Warto to odnotować niezależnie od ToolJeta, bo jest to praktyka, którą da się przenieść do dowolnego projektu w jeden wieczór, a jej wartość rośnie z każdą osobą w zespole używającą asystenta.

ToolJet czy Filament — uczciwe porównanie

Dla zespołu pracującego w Laravelu to jest właściwe pytanie, a odpowiedź nie jest jednoznaczna w żadną stronę.

Filament wygrywa, gdy narzędzie ma żyć razem z aplikacją. Dzieli z nią modele, polityki dostępu, reguły walidacji, obserwatory i testy. Dodanie pola do modelu pojawia się w panelu, a nie wymaga równoległej zmiany w drugim systemie. Panel jest częścią kodu, więc podlega review, przechodzi tę samą drogę wdrożenia i jest objęty tymi samymi testami. Przy narzędziu, które będzie żyło trzy lata i rosło razem z produktem, to jest przewaga trudna do przebicia.

ToolJet wygrywa w trzech konkretnych sytuacjach:

  • Dane są w kilku systemach, do których nie mamy modeli — i nie chcemy ich mieć. Widok łączący zamówienia z naszej bazy, wysyłki z API kuriera i zgłoszenia z systemu obsługi to w Laravelu trzy integracje i warstwa spinająca; w ToolJecie to trzy skonfigurowane źródła danych i jedno zapytanie,
  • Narzędzie jest tymczasowe albo eksperymentalne — na tydzień, na jedną migrację, na sprawdzenie hipotezy. Nie chcemy go wdrażać razem z aplikacją ani utrzymywać po tym, jak przestanie być potrzebne,
  • Narzędzie ma zmieniać się bez nas — przez osobę z działu operacyjnego, która sama dołoży kolumnę albo filtr.

Ten trzeci punkt jest najmocniejszy i najbardziej niedoceniany, więc warto go dopowiedzieć: niska bariera wejścia nie jest zaletą dla programisty — jest zaletą dla klienta. Panel, który klient poprawi sobie sam, nie generuje zgłoszenia, nie czeka w sprincie i nie kosztuje nikogo kontekstu.

Ale ta sama właściwość ma drugą stronę i uczciwość wymaga jej nazwania. Niska bariera oznacza, że powstanie coś, czego nikt nie recenzował. W edycji społecznościowej nie ma GitSync ani wielu środowisk, więc zmiana w aplikacji dzieje się od razu, w tym samym miejscu, bez pull requesta i bez etapu testowego. Przy narzędziu operującym na produkcyjnej bazie — z prawem zapisu — to jest realne ryzyko. Da się je obudować procesem (osobna instancja do eksperymentów, ograniczone uprawnienia użytkownika bazy danych) albo pieniędzmi (edycja płatna z GitSync i środowiskami), ale nie da się go zignorować.

Praktyczna rekomendacja: Filament do narzędzi, które są częścią produktu; ToolJet do narzędzi, które są częścią operacji. I w obu przypadkach — dedykowany użytkownik bazy danych z minimalnym zakresem uprawnień, bo to jedyna warstwa, która chroni przed pomyłką niezależnie od wybranej platformy.

Pułapki

  • Cztery kluczowe funkcje wdrożeniowe są płatne — workflowy, GitSync, wiele środowisk i RBAC. Wycena wdrożenia dla klienta musi to uwzględniać albo świadomie z tego rezygnować,
  • Funkcje AI wymagają połączeń do serwerów dostawcy, także przy self-hostingu. Przy wymogu izolacji sieciowej trzeba je wyłączyć,
  • Dokumentowany obraz produkcyjny to edycja płatna uruchamiana w zakresie darmowym; obraz społecznościowy jest osobny,
  • Bez GitSync nie ma review ani środowisk — aplikacja zmienia się natychmiast i nieodwracalnie,
  • Zewnętrzny Redis z trwałością AOF jest wymagany przy wielu workerach, a nie zalecany,
  • Utrata LOCKBOX_MASTER_KEY oznacza utratę wszystkich zapisanych poświadczeń do źródeł danych. Ten klucz należy do kategorii sekretów, które trzyma się w menedżerze i backupuje osobno,
  • Do produkcji tylko kanał LTS. Beta wychodzi co drugi dzień,
  • 1202 otwarte zgłoszenia przy bardzo wysokim tempie rozwoju — to jest projekt, który dużo dodaje, ale też dużo ma na liście,
  • Zaklinowanie na platformie jest realne. Aplikacja zbudowana wizualnie nie jest kodem, który przeniesiemy gdzie indziej — jest konfiguracją ToolJeta. Wyjście z platformy oznacza napisanie narzędzia od nowa, i to trzeba wliczyć w decyzję przy narzędziach, które mają żyć długo,
  • AGPL-3.0 — szczegóły niżej, ale w skrócie: instancja dla siebie i dla klienta jest w porządku, oferowanie ToolJeta jako własnej usługi już nie.

Podsumowanie

ToolJet jest dojrzałą platformą do narzędzi wewnętrznych i jednym z niewielu projektów w tej kategorii, które da się postawić u siebie w rozsądnym czasie. Ma przy tym granicę między wersją darmową i płatną w miejscu, które trzeba znać zawczasu. Co z tego wynika:

  • Projekt jest duży i bardzo aktywny — 40 870 gwiazdek, 89 commitów w dwa i pół tygodnia, dwa kanały wydań. Do produkcji wybieraj LTS,
  • Edycja społecznościowa jest kompletna do budowania — 80 komponentów, 90 źródeł danych, wbudowana baza, edycja wieloosobowa, JavaScript i Python w środku, wtyczki przez CLI,
  • Ale zarządzanie cyklem życia jest płatne — workflowy, GitSync, dev/stage/prod i RBAC ze SCIM. Bez nich zmiana w aplikacji dzieje się od razu na produkcji,
  • Serwer MCP to najciekawszy element — agent buduje aplikację ToolJeta na kontraktach platformy, nie generuje kodu do utrzymania, i działa na naszej własnej subskrypcji modelu. Status: beta,
  • Zabezpiecz LOCKBOX_MASTER_KEY i SECRET_KEY_BASE — pierwszy z nich chroni wszystkie zapisane poświadczenia do źródeł danych,
  • Przy wielu workerach postaw zewnętrzny Redis z --appendonly yes --maxmemory-policy noeviction,
  • Funkcje AI wymagają ruchu do api-gateway.tooljet.ai i python-server.tooljet.ai — przy wymogu izolacji sieciowej pozostają wyłączone,
  • Filament do narzędzi będących częścią produktu, ToolJet do narzędzi będących częścią operacji,
  • Zawsze dedykowany użytkownik bazy z minimalnymi uprawnieniami — to jedyna warstwa chroniąca przed pomyłką w narzędziu, którego nikt nie recenzuje,
  • Rozważ układ ToolJet plus n8n — n8n jest jednym z 49 dostępnych źródeł danych, więc interfejs można zbudować w ToolJecie, a proces w n8n, bez wchodzenia w płatne workflowy,
  • Policz koszt wyjścia. Aplikacja wizualna jest konfiguracją platformy, nie przenośnym kodem.

Licencja: ToolJet jest rozpowszechniany na GNU Affero General Public License v3.0 — pełnoprawnej licencji open source z najsilniejszym copyleftem w powszechnym użyciu. Kluczowa jest tu sekcja 13: udostępnianie zmodyfikowanej wersji programu użytkownikom przez sieć rodzi obowiązek udostępnienia im kodu źródłowego tych zmian. Przełożenie na typowe scenariusze wygląda tak samo jak przy OpenPanelu. Własna instancja obsługująca narzędzia wewnętrzne naszej firmy albo postawiona klientowi na jego infrastrukturze mieści się w licencji bez zastrzeżeń — a jeśli nie modyfikujemy kodu, nie ma nawet czego udostępniać. Aplikacje zbudowane w ToolJecie nie są dziełem pochodnym platformy; są jej konfiguracją i danymi. Natomiast udostępnienie samego ToolJeta jako usługi — hostowanie instancji dla wielu klientów jako element naszej oferty, zwłaszcza po zmianach w kodzie — uruchamia obowiązek z sekcji 13 i wymaga udostępnienia tym użytkownikom kodu razem z modyfikacjami. Przy modelu biznesowym zbliżającym się do tej granicy pytanie do prawnika albo do autorów projektu jest tańsze niż każda inna droga. Warto też zauważyć, że AGPL jest tu spójna z modelem biznesowym: ToolJet zarabia na edycji płatnej i na wersji chmurowej, a silny copyleft chroni go dokładnie przed tym, żeby ktoś inny sprzedawał tę samą platformę jako swoją.