Vibe coding w Elixirze - dlaczego AI pisze lepszy kod w Phoenix niż w React
Poniedziałek, 9:00. Otwierasz terminal. Piszesz do Claude: „Zbuduj moduł obsługi zamówień z walidacją, statusami i powiadomieniami email. Phoenix, Ecto, Oban." Piętnaście sekund później masz 4 pliki: kontekst, schemat, kontroler, worker. Kompilujesz. Zero ostrzeżeń. Odpalasz testy. Zielono. Commit, push, deploy.
Brzmi jak fantazja? W 2026 roku to jest codzienna rzeczywistość tysięcy programistów. Nazywają to vibe coding - opisujesz co chcesz, AI pisze kod.
Ale jest haczyk. Ten sam programista, ten sam prompt, ten sam AI - tylko zamiast Elixira pisze w React + Express. Wynik: 12 plików, 3 niejawne zależności, brak walidacji po stronie serwera, SQL injection w endpoincie wyszukiwania, node_modules z 847 paczkami. Kompilacja? Nie ma - JavaScript nie kompiluje. Testy? AI ich nie napisał, bo nie było o nich mowy.
Problem nie leży w AI. Problem leży w tym, w jakim języku AI pisze.
Czym jest vibe coding
Termin ukuł Andrej Karpathy (współtwórca OpenAI, były szef AI w Tesli) w lutym 2025. Definicja jest prosta: opisujesz „vibe" - klimat, funkcjonalność, flow - tego, co chcesz zbudować, a AI zajmuje się resztą.
Rok później vibe coding to nie eksperyment. To mainstream:
| Statystyka | Źródło |
|---|---|
| 42% commitowanego kodu to kod wygenerowany przez AI | Sonar State of Code 2026 |
| 87% firm z Fortune 500 używa platform do vibe codingu | Second Talent 2026 |
| 72% programistów używa AI do kodowania codziennie | Sonar State of Code 2026 |
| 65% kodu będzie generowane przez AI do 2027 roku (prognoza) | Sonar State of Code 2026 |
Narzędzia: Claude Code, GitHub Copilot, Cursor, Windsurf, Codex. Wszystkie robią to samo - biorą prompt w języku naturalnym i generują kod. Różnica jest w jakości tego kodu. A jakość zależy od dwóch rzeczy: modelu AI i języka docelowego.
Problem: 96% nie ufa, 48% nie sprawdza
Sonar przebadał ponad 1100 programistów enterprise. Wyniki:
- 96% programistów nie ufa w pełni kodowi wygenerowanemu przez AI
- Tylko 48% zawsze weryfikuje kod AI przed commitem
- 38% twierdzi, że review kodu AI zajmuje więcej czasu niż review kodu ludzkiego
- 20% kodu AI zawiera błędy
- 8x więcej duplikatów w kodzie generowanym przez AI niż w pisanym ręcznie
Jest na to termin: comprehension debt - dług zrozumienia. Tradycyjny dług techniczny to „wiem jak to działa, ale jest bałagan". Comprehension debt to „nie wiem jak to działa, bo napisał to AI, a ja to zaakceptowałem". Karpathy sam przyznaje, że projekty vibe-coded „szybko przerastają zwykłe zrozumienie".
To jest prawdziwe ryzyko. Nie to, że AI pisze zły kod - tylko to, że nikt go nie rozumie i nikt go nie weryfikuje.
I tutaj Elixir zmienia zasady gry.
Dlaczego AI pisze lepszy kod w Elixirze
Elixir ma pięć cech, które sprawiają, że jest strukturalnie lepszym celem dla generowania kodu przez AI niż JavaScript, Python czy Java.
1. Kompilacja łapie błędy AI natychmiast
JavaScript, Python, Ruby - języki interpretowane. AI generuje kod, który „wygląda dobrze", ale rzuca wyjątek w runtime. Dowiadujesz się o błędzie, gdy użytkownik kliknie przycisk.
Elixir kompiluje. Każdy błąd - brakujący moduł, zły typ argumentu, niezaimplementowany callback - jest wykryty zanim uruchomisz aplikację:
# AI wygenerował:
defmodule MyApp.Orders do
def create(params) do
%Order{}
|> Order.changeset(params)
|> Repo.inser() # literówka: inser zamiast insert
end
end
# Kompilator:
# ** (CompileError) undefined function Repo.inser/1
# (did you mean Repo.insert/1?)
#
# AI dostaje ten komunikat, poprawia i próbuje ponownie.
# Zero interwencji programisty.Od Elixira 1.17 kompilator idzie dalej - wnioskuje typy z pattern matchingu i wywołań funkcji. W wersji 1.20 (2026) wnioskowanie obejmuje wszystkie konstrukcje języka. Kompilator wykrywa, że AI przekazał string tam, gdzie powinna być liczba - bez ani jednej adnotacji typu w kodzie.
Feedback loop: prompt → kod → kompilacja → błąd → poprawka → kompilacja → sukces. W językach kompilowanych ten loop jest automatyczny. W JavaScript go nie ma.
2. Konwencje Phoenix eliminują zgadywanie
AI działa najlepiej, gdy zasady są jasne i jednolite. Phoenix ma sztywną strukturę projektu:
lib/
├── my_app/ # Logika biznesowa (konteksty)
│ ├── orders.ex # Kontekst zamówień (publiczne API)
│ └── orders/
│ └── order.ex # Schemat Ecto
├── my_app_web/ # Warstwa webowa
│ ├── controllers/ # Kontrolery
│ ├── live/ # LiveView
│ └── components/ # Komponenty UI
├── my_app/repo.ex # Baza danych
└── my_app/application.ex # Supervision treeKażdy projekt Phoenix wygląda tak samo. AI nie musi zgadywać, gdzie umieścić logikę biznesową (kontekst), gdzie walidację (changeset), gdzie routing (router.ex). Konwencja eliminuje klasę błędów, w których AI umieszcza kod w złym miejscu.
Porównaj z Express.js, gdzie nie ma narzuconej struktury - AI musi zgadywać, a każdy projekt wygląda inaczej.
3. Mniej kodu = mniej miejsca na błędy AI
Im więcej kodu AI musi wygenerować, tym więcej błędów popełni. Elixir z Phoenix i LiveView wymaga dramatycznie mniej kodu niż alternatywy:
| Funkcja | Express + React | Phoenix + LiveView |
|---|---|---|
| Pliki do wygenerowania | 8-12 | 3-4 |
| Linie kodu | ~400 | ~120 |
| Zewnętrzne zależności | 15-30 paczek | 5-10 paczek |
| Osobna warstwa API | Tak (REST/GraphQL) | Nie (LiveView) |
| Zarządzanie stanem klienta | Redux/Zustand/React Query | Brak (stan na serwerze) |
AI generujący 120 linii kodu w Elixirze ma 3x mniej okazji do popełnienia błędu niż AI generujący 400 linii w React + Express. A mniej plików oznacza mniej szans na niespójność między frontendem a backendem - bo w LiveView nie ma osobnego frontendu.
4. Dokumentacja wbudowana w język
Elixir ma doctesty - dokumentacja, która jest jednocześnie testem:
defmodule MyApp.Pricing do
@doc """
Oblicza cenę z rabatem.
## Examples
iex> MyApp.Pricing.apply_discount(100_00, 15)
85_00
iex> MyApp.Pricing.apply_discount(100_00, 0)
100_00
iex> MyApp.Pricing.apply_discount(100_00, 110)
{:error, :invalid_discount}
"""
def apply_discount(price, discount_percent)
when is_integer(price) and discount_percent in 0..100 do
price - div(price * discount_percent, 100)
end
def apply_discount(_price, _discount), do: {:error, :invalid_discount}
endAI widzi te doctesty i uczy się z nich jak używać funkcji. Nie halucynuje API, nie wymyśla argumentów - ma konkretne przykłady z oczekiwanymi wynikami. A mix test weryfikuje, czy doctesty nadal przechodzą po zmianach AI.
5. Funkcyjny paradygmat = mniejsza przestrzeń błędów
Funkcje w Elixirze to transformacje danych. Wejście → wyjście, bez efektów ubocznych, bez mutowania stanu. Dla AI to idealne środowisko:
# Elixir: dane przepływają przez pipeline
order_params
|> Orders.validate() # {:ok, valid} lub {:error, changeset}
|> Orders.calculate_total() # dodaj podatki, rabaty
|> Orders.save() # zapisz do bazy
|> Orders.notify_customer() # wyślij email przez ObanAI nie musi śledzić, który obiekt zmutował jaki stan, która zmienna została nadpisana w innym wątku, który middleware zmodyfikował request. Każda funkcja jest izolowana - AI może generować je niezależnie, a kompilator i testy weryfikują, czy pasują do siebie.
W Javie AI musi zarządzać mutable state, dependency injection, class hierarchy, try-catch-finally, synchronized blocks. W JavaScript - closures, this-binding, callback hell, prototype chain. Każdy z tych mechanizmów to dodatkowa przestrzeń błędów, w której AI się gubi.
AGENTS.md - framework, który uczy AI pisać w Phoenix
Phoenix 1.8 (2025) wprowadził coś bezprecedensowego: plik AGENTS.md generowany automatycznie z każdym nowym projektem. To instrukcja dla AI - jakie konwencje stosować, jakich błędów unikać, jak używać API frameworka.
Chris McCord (twórca Phoenixa):
„Whether you're using Phoenix.new, Tidewave.ai, Cursor's or Zed's Agent — providing AGENTS.md to the underlying LLM brings a night-and-day difference to the LLM assisted dev experience."
Co zawiera AGENTS.md w Phoenix:
- Korekty składniowe - typowe błędy, które LLM-y popełniają w Elixirze
- Idiomy Phoenix - jak używać kontekstów, changesety, LiveView
- Krytyczne API - poprawne użycie Ecto, Router, Components
- Reguły zależności - dzięki integracji z pakietem
usage_rules, AGENTS.md agreguje wytyczne ze wszystkich bibliotek w projekcie
To nie jest README dla ludzi. To README dla AI - i Phoenix jest pierwszym frameworkiem na świecie, który to robi oficjalnie.
AGENTS.md, CLAUDE.md, .cursorrules - ekosystem plików kontekstowych
AGENTS.md to otwarty standard (Linux Foundation), wspierany przez OpenAI Codex, Google Jules, Cursor, Amp i Factory. Ale narzędzia mają też własne formaty:
| Plik | Narzędzie | Zakres |
|---|---|---|
AGENTS.md | Standard otwarty (40 000+ projektów) | Uniwersalne wytyczne dla AI |
CLAUDE.md | Claude Code | Preferencje per-projekt, workflow |
.cursorrules | Cursor | Reguły generowania kodu |
.windsurfrules | Windsurf | Reguły generowania kodu |
Phoenix generuje AGENTS.md. Ale nic nie stoi na przeszkodzie, żeby mieć też CLAUDE.md z wytycznymi specyficznymi dla Twojego projektu: „używaj Oban do wszystkich zadań w tle", „walidacja zawsze w changesetach", „testy integracyjne dla każdego endpointu".
Tidewave - AI z dostępem do Twojej aplikacji
AGENTS.md to statyczny plik. Tidewave idzie dalej - to serwer MCP (Model Context Protocol) uruchomiony wewnątrz Twojej aplikacji Phoenix, dający AI dostęp do runtime'u.
Stworzony przez Dashbit (firma José Valima, twórcy Elixira), Tidewave pozwala AI:
- Czytać logi aplikacji w czasie rzeczywistym
- Wykonywać zapytania SQL i analizować wyniki
- Inspekcja WebSocket i połączeń LiveView
- Podglądać procesy BEAM - supervised, running, crashed
- Analizować telemetrię - czas odpowiedzi, throughput, błędy
# Dodanie Tidewave do projektu Phoenix
# mix.exs
defp deps do
[
{:tidewave, "~> 0.1", only: :dev}
]
endRóżnica jest fundamentalna. Bez Tidewave AI analizuje statyczny kod - pliki na dysku. Z Tidewave AI widzi żywą aplikację - zapytania do bazy, logi błędów, stan procesów. Gdy powiesz „ten endpoint jest wolny, zoptymalizuj go", AI nie zgaduje - patrzy na pg_stat_statements i widzi, które zapytanie trwa najdłużej.
Workflow: vibe coding w Phoenix w praktyce
Oto jak wygląda vibe coding w Elixirze, krok po kroku:
Krok 1: Prompt
Zbuduj system zarządzania zadaniami dla zespołu.
Wymagania:
- Zadania z tytułem, opisem, statusem (todo/in_progress/done), priorytetem
- Przypisanie do użytkownika
- LiveView z drag-and-drop między kolumnami Kanban
- Powiadomienie email gdy ktoś przypisze mi zadanie
- Soft deleteKrok 2: AI generuje kod
AI (z AGENTS.md) tworzy:
# lib/my_app/tasks.ex - kontekst biznesowy
defmodule MyApp.Tasks do
import Ecto.Query
def list_tasks_by_status(team_id) do
Task
|> where([t], t.team_id == ^team_id and is_nil(t.deleted_at))
|> order_by([t], [asc: t.priority, desc: t.inserted_at])
|> Repo.all()
|> Enum.group_by(& &1.status)
end
def update_status(task, new_status, user) do
task
|> Task.status_changeset(%{status: new_status})
|> Repo.update()
|> tap(fn
{:ok, updated} -> maybe_notify_assignee(updated, user)
_ -> :ok
end)
end
defp maybe_notify_assignee(%{assignee_id: id} = task, %{id: changer_id})
when not is_nil(id) and id != changer_id do
%{task_id: task.id, assignee_id: id}
|> MyApp.Workers.TaskNotification.new()
|> Oban.insert()
end
defp maybe_notify_assignee(_, _), do: :ok
endKrok 3: Kompilator weryfikuje
$ mix compile
# Compiled 4 files (0 errors, 0 warnings)Zero błędów. Gdyby AI popełnił literówkę, użył nieistniejącej funkcji, albo przekazał zły typ - kompilator by to złapał. AI dostałby komunikat, poprawił i spróbował ponownie. Automatycznie, bez Twojej interwencji.
Krok 4: Testy weryfikują logikę
$ mix test
..........
Finished in 0.8 seconds (0.2s async, 0.6s sync)
10 tests, 0 failuresAI wygenerował testy razem z kodem (bo Phoenix ma mix phx.gen z testami i AGENTS.md mówi, żeby zawsze pisać testy). Testy sprawdzają edge cases: co gdy zadanie nie istnieje, co gdy użytkownik nie ma uprawnień, co gdy status jest nieprawidłowy.
Krok 5: Narzędzia jakości
$ mix format --check-formatted # Formatowanie kodu
$ mix credo # Statyczna analiza / linter
$ mix deps.audit # Audyt bezpieczeństwa zależnościTrzy komendy. Automatyczne. Mogą być w CI/CD. AI wygenerował kod, ale toolchain Elixira go zweryfikował na czterech poziomach: kompilacja, testy, formatowanie, analiza statyczna.
Porównanie: vibe coding w różnych technologiach
| Wymiar | Elixir + Phoenix | JavaScript + React | Python + Django | Java + Spring |
|---|---|---|---|---|
| Kompilacja łapie błędy AI | Tak (+ typy od 1.17) | Nie | Nie | Tak |
| Konwencja struktury projektu | Sztywna (Phoenix) | Brak (Express) | Luźna (Django) | Luźna (Spring) |
| AGENTS.md z frameworka | Tak (Phoenix 1.8) | Nie | Nie | Nie |
| Serwer MCP w runtime | Tak (Tidewave) | Nie | Nie | Nie |
| Testy wbudowane w framework | Tak (ExUnit + doctest) | Nie (osobny Jest/Vitest) | Tak (pytest) | Nie (osobny JUnit) |
| Doctesty (doc = test) | Tak | Nie | Tak (doctest) | Nie |
| Linter z pudełka | Tak (mix format + Credo) | Nie (osobny ESLint + Prettier) | Nie (osobny Black + Ruff) | Nie (osobny Checkstyle) |
| Audyt zależności | Tak (mix deps.audit) | Tak (npm audit) | Tak (pip-audit) | Tak (OWASP) |
| Ilość kodu do wygenerowania | Mała | Duża (front + back + API) | Średnia | Duża |
| Boilerplate | Minimalny | Duży (Redux, hooks, API) | Średni | Ogromny |
Phoenix jest jedynym frameworkiem, który łączy kompilację, AGENTS.md, MCP runtime (Tidewave), doctesty i konwencje w jeden spójny pipeline weryfikacji kodu AI. Żaden inny stack nie ma tego zestawu.
Ryzyka vibe codingu i jak Elixir je mityguje
Comprehension debt
Ryzyko: Akceptujesz kod AI, którego nie rozumiesz. Za 3 miesiące musisz go zmienić i nie wiesz jak.
Mitygacja w Elixirze: Elixir jest czytelny jak pseudokod. Pattern matching, pipe operator, opisowe nazwy funkcji. Kod AI w Elixirze jest czytelny nawet bez komentarzy:
# Co robi ten kod? Przeczytaj go jak zdanie:
order
|> calculate_subtotal()
|> apply_discount(coupon)
|> add_shipping(address)
|> charge_payment(payment_method)
|> send_confirmation()Porównaj z kodem AI w React + Redux, gdzie logika jest rozrzucona między reducery, selektory, hooki, middleware, thunki i saga. Zrozumienie wymaga śledzenia 8 plików jednocześnie.
Bezpieczeństwo
Ryzyko: AI generuje kod z lukami. SQL injection, XSS, brak autoryzacji.
Mitygacja w Elixirze:
| Luka | Phoenix/Elixir | Express/React |
|---|---|---|
| SQL injection | Niemożliwy (Ecto parametryzuje domyślnie) | Możliwy (raw queries) |
| XSS | Niemożliwy (HEEx escapuje domyślnie) | Możliwy (dangerouslySetInnerHTML) |
| CSRF | Wbudowany (automatyczne tokeny) | Ręczna konfiguracja |
| Brak autoryzacji | Scopes (Phoenix 1.8, secure-by-default) | Ręczna implementacja |
| Niezwalidowane dane | Changesets (walidacja wymuszona przez Ecto) | Ręczna walidacja |
Phoenix jest secure by default. AI musiałby celowo obejść zabezpieczenia, żeby wprowadzić lukę. W Express AI musi celowo dodać zabezpieczenia - a jeśli o nich zapomni (a zapomni), luka zostaje.
Duplikaty i nieoptymalna architektura
Ryzyko: AI generuje 8x więcej duplikatów niż człowiek. Tworzy redundantne moduły, powtarza logikę.
Mitygacja w Elixirze:
mix credo- wykrywa duplikaty, zbyt długie funkcje, brak doctestów- Konteksty Phoenix - wymuszają separację odpowiedzialności. AI nie wrzuci logiki bazodanowej do kontrolera, bo AGENTS.md mówi „logika w kontekstach"
- Pattern matching - naturalnie eliminuje duplikaty:
# Zamiast 4 if-else (typowe dla AI w JS):
def process(%{status: :pending} = order), do: start_processing(order)
def process(%{status: :paid} = order), do: ship(order)
def process(%{status: :shipped} = order), do: complete(order)
def process(%{status: :cancelled}), do: {:error, :already_cancelled}Kto powinien korzystać z vibe codingu w Elixirze
Dla zespołów, które już znają Elixira
Vibe coding to mnożnik produktywności, nie zamiennik wiedzy. Zespół, który zna Phoenix, wykorzysta Claude Code / Cursor z AGENTS.md do:
- Scaffoldingu nowych modułów (konteksty, schematy, LiveView)
- Pisania testów (AI jest w tym zaskakująco dobry)
- Refaktoringu (zmiana struktury, ekstrakcja kontekstów)
- Dokumentacji (doctesty, @moduledoc, @doc)
Programista, który spędzał 2 godziny na boilerplate, teraz spędza 15 minut na weryfikacji tego, co AI wygenerował.
Dla firm rozważających Elixira
Jedna z głównych obiekcji wobec Elixira brzmi: „nie znajdziemy programistów". Vibe coding zmienia tę kalkulację:
- Programista Python/Ruby uczy się Elixira szybciej z AI - Claude Code z AGENTS.md generuje idiomatyczny kod Phoenix, programista uczy się przez code review
- Mniejszy zespół jest jeszcze mniejszy - tam, gdzie bez AI potrzebujesz 2 programistów Elixir, z AI wystarczy 1.5
- Onboarding jest szybszy - nowy programista ma AGENTS.md, CLAUDE.md i Tidewave. Kontekst projektu jest w plikach, nie w głowie Tomka
Kiedy vibe coding to zły pomysł
Uczciwie - vibe coding nie jest rozwiązaniem na wszystko:
- Systemy krytyczne dla życia - medyczne, lotnicze, nuklearne. AI-generated code nie przejdzie certyfikacji
- Kryptografia i bezpieczeństwo niskopoziomowe - AI halucynuje implementacje algorytmów. Użyj zweryfikowanych bibliotek
- Zespół zero-person - vibe coding wymaga kogoś, kto rozumie wygenerowany kod. „Zbuduj mi SaaS" jako prompt do Claude nie zadziała
- Optymalizacja wydajności - AI pisze poprawny, nie optymalny kod. Profiling i tuning to nadal praca człowieka
Praktyczny starter: vibe coding w Phoenix w 10 minut
# 1. Nowy projekt Phoenix (z AGENTS.md)
mix phx.new my_app --live
# 2. Dodaj Tidewave (opcjonalnie, dev-only)
# W mix.exs: {:tidewave, "~> 0.1", only: :dev}
mix deps.get
# 3. Otwórz Claude Code / Cursor / Zed w katalogu projektu
# AI automatycznie odczyta AGENTS.md i zrozumie konwencje
# 4. Prompt:
# "Zbuduj CRUD dla produktów z cenami, kategoriami
# i soft delete. LiveView z tabelą i filtrami.
# Testy dla kontekstu i LiveView."
# 5. Weryfikacja:
mix compile && mix test && mix format --check-formatted && mix credoPięć komend. Jeden prompt. Kompletny moduł z testami, walidacją i UI.
Liczby: produktywność z AI vs bez AI
| Zadanie | Bez AI | Z AI + Phoenix | Oszczędność |
|---|---|---|---|
| CRUD moduł (kontekst + schemat + LiveView + testy) | 3-4 h | 30-45 min | ~80% |
| Integracja z API zewnętrznym | 4-6 h | 1-2 h | ~70% |
| Refaktoring kontekstu (ekstrakcja modułu) | 2-3 h | 30-45 min | ~75% |
| Napisanie testów do istniejącego kodu | 2-4 h | 30-60 min | ~80% |
| Dokumentacja (doctesty + @doc) | 1-2 h | 15-30 min | ~80% |
To nie są liczby z marketingowego slajdu. To nasze doświadczenie z codziennej pracy z Claude Code i Phoenix. Oszczędność 70-80% na powtarzalnych zadaniach pozwala skupić się na tym, co AI nie potrafi: architektura, decyzje biznesowe, optymalizacja, rozmowy z klientem.
Chcesz zobaczyć, jak vibe coding z Elixirem i Phoenix przyspiesza budowę Twojego systemu? Porozmawiajmy - pokażemy workflow na żywo, na Twoim przypadku biznesowym.