Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik12 min czytania

v0, generowanie interfejsów i koszt tokenów

v0 zamienia opis na komponenty React z Tailwindem i shadcn/ui. Rozliczanie tokenami i kredytami, praca z wygenerowanym kodem i realne granice narzędzia.

v0, generowanie interfejsów i koszt tokenów

v0 to narzędzie Vercela, które z opisu tekstowego generuje komponenty React używające Tailwinda i biblioteki shadcn/ui. Wynik da się obejrzeć na żywo, poprawiać kolejnymi poleceniami i skopiować do własnego projektu.

Sensowna ocena tego narzędzia zaczyna się od tego, czego ono nie robi. Nie zastępuje pracy nad architekturą, nie zna Twojej domeny i nie wie, jak wyglądają pozostałe ekrany Twojej aplikacji. Skraca drogę od pomysłu do klikalnego układu, i to jest konkretna, mierzalna wartość, o ile nie oczekuje się od niego gotowego produktu.

Rozliczanie tokenami i co to zmienia

Najważniejsza zmiana z ostatniego czasu dotyczy nie generowania, tylko rachunku.

Wcześniej plany dawały określoną liczbę wiadomości albo generowań, więc koszt dawał się przewidzieć przez policzenie, ile razy dziennie ktoś naciśnie przycisk. Od zmiany ogłoszonej przez Vercel w maju 2025 rozliczenie idzie od zużytych tokenów wejścia i wyjścia przeliczanych na kredyty, a nie od stałej liczby wiadomości. To znaczy, że pojedyncze polecenie kosztuje tyle, ile wynika z jego złożoności i wielkości kontekstu.

Praktyczne skutki są trzy. Prosta poprawka odstępów kosztuje ułamek tego, co wygenerowanie całego widoku, więc drobne iteracje przestały być kosztowne. Długa rozmowa nad jednym projektem kosztuje coraz więcej z każdym krokiem, bo rośnie kontekst. Oraz: budżet miesięczny przestał dawać się przewidzieć z liczby generowań i trzeba go obserwować.

Dochodzi do tego wybór modelu. Warianty nazywają się v0 Mini, v0 Pro, v0 Max i v0 Max Fast, a różnica w stawce jest większa, niż sugeruje nazewnictwo: milion tokenów wyjścia kosztuje 1,20 USD na najtańszym i 50 USD na najdroższym. Do drobnych poprawek opłaca się więc schodzić na tańszy, a mocniejszy zostawić na pierwszy szkic złożonego ekranu. To ta sama zasada, która obowiązuje przy pracy z modelami przez API: dopasowuj model do kroku, nie do całego procesu.

Układ planów zaskakuje, bo wyższy plan nie znaczy większa pula. W cenniku ze stanu na sierpień 2026 plan darmowy daje 5 USD kredytów miesięcznie i limit siedmiu wiadomości dziennie, plan Plus za 30 USD miesięcznie od użytkownika daje 30 USD kredytów, a plan Business za 100 USD od użytkownika daje dokładnie te same 30 USD kredytów. Różnica między dwoma planami płatnymi leży w domyślnej rezygnacji z trenowania na danych i w udogodnieniach dla firm, nie w limicie generowania. Powyżej tego jest jeszcze wycena indywidualna.

Osobno warto wiedzieć, co dzieje się na granicy puli, bo to najczęściej pomijana część rachunku. Po wyczerpaniu kredytów generowanie zatrzymuje się do czasu dokupienia kolejnych, a nie przechodzi cicho na rachunek. Niewykorzystana pula miesięczna przechodzi na planach płatnych o jeden miesiąc i dalej się nie kumuluje, natomiast kredyty dokupione poza abonamentem wygasają po roku. Same stawki zmieniają się razem z modelami, więc przed decyzją zakupową i tak sprawdź aktualny cennik u dostawcy.

Jak z tego korzystać, żeby miało sens

Największa różnica w skuteczności bierze się z tego, co dajesz na wejściu, a nie z tego, jak zręcznie formułujesz zdania.

Opis funkcjonalny działa lepiej niż opis wizualny. „Tabela zamówień z filtrowaniem po statusie i dacie, wiersz rozwijany pokazujący pozycje" daje lepszy wynik niż „ładna tabela z nowoczesnym wyglądem", bo drugie zdanie nie zawiera żadnej informacji, którą da się przełożyć na kod.

Zrzut ekranu istniejącego widoku działa jeszcze lepiej niż opis. Narzędzie przyjmuje obrazy, więc pokazanie, jak wygląda reszta aplikacji, ustawia styl skuteczniej niż akapit przymiotników.

Trzecia rzecz to iteracja małymi krokami. Polecenie zmieniające jedną rzecz naraz daje przewidywalny wynik. Polecenie zmieniające pięć rzeczy zwykle psuje dwie z nich, a rozstrzygnięcie, która zmiana zawiniła, kosztuje więcej niż zrobienie tego osobno.

Czwarta to podawanie danych zamiast wymyślania. Wklejenie prawdziwego kształtu obiektu z Twojego API sprawia, że komponent operuje na Twoich polach, a nie na wymyślonych, i odpada ręczne przepisywanie nazw.

Co dostajesz na wyjściu

Kod używa Reacta z Tailwindem i komponentów shadcn/ui, czyli tych samych, które kopiujesz do repozytorium zamiast instalować jako zależność.

Code
TypeScript
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'

export function KartaZamowienia({ numer, status, kwota }: Props) {
  return (
    <Card>
      <CardHeader className="flex flex-row items-center justify-between">
        <CardTitle className="text-base">{numer}</CardTitle>
        <Badge variant={status === 'oplacone' ? 'default' : 'secondary'}>{status}</Badge>
      </CardHeader>
      <CardContent className="text-2xl font-semibold">{kwota} zl</CardContent>
    </Card>
  )
}

To jest zaleta i ograniczenie jednocześnie. Zaleta, bo jeśli Twój projekt stoi na shadcn/ui i Tailwindzie, wygenerowany kod pasuje bez tłumaczenia. Ograniczenie, bo jeśli używasz innej biblioteki komponentów albo własnego systemu wizualnego, dostajesz kod do przepisania, a wtedy zysk czasowy topnieje.

Warto to sprawdzić przed wpisaniem narzędzia do procesu zespołu. Przy projekcie zbudowanym na innym zestawie komponentów v0 nadal ma sens jako szkicownik układu, ale nie jako źródło kodu wchodzącego do repozytorium.

Granice, o których warto wiedzieć

Wygenerowany komponent wygląda kompletnie i to jest jego najbardziej mylące działanie.

Dostępność bywa powierzchowna. Elementy wyglądające jak przyciski nie zawsze nimi są, kolejność ogniskowania potrafi być przypadkowa, a kontrast dobrany pod estetykę zamiast pod czytelność. Do przejrzenia przez narzędzie sprawdzające i klawiaturę, zanim to trafi do użytkowników.

Stan i dane są zaślepkami. Komponent renderuje przykładową listę, a podpięcie prawdziwych danych, obsługa ładowania, błędu i pustego wyniku to praca, której nikt za Ciebie nie zrobił. Przy realnym ekranie ta część bywa większa niż sam układ.

Zachowanie na małych ekranach wymaga sprawdzenia. Klasy responsywne zwykle są, natomiast to, czy tabela z ośmioma kolumnami zachowuje się rozsądnie na telefonie, rozstrzyga się w przeglądarce, nie w podglądzie.

Spójność między ekranami jest po Twojej stronie. Każde generowanie zaczyna się w dużej mierze od nowa, więc trzy widoki wygenerowane osobno będą miały trzy nieco różne odstępy, promienie i wysokości przycisków. Przy jednym ekranie to nieistotne, przy dwudziestu robi się z tego dług.

Przenoszenie kodu do projektu

Moment, w którym wygenerowany widok trafia do repozytorium, decyduje o tym, czy narzędzie oszczędziło czas, czy tylko przesunęło pracę.

Zacznij od podziału. Wygenerowany plik zawiera zwykle cały ekran: układ, dane przykładowe, obsługę zdarzeń i style w jednym miejscu. Rozbicie go na komponent prezentacyjny i warstwę pobierającą dane zajmuje kwadrans, a bez tego pierwsza zmiana wymagań każe grzebać w pliku na czterysta linii.

Podział polega na tym, że komponent dostaje gotowe dane w właściwościach i nie wie, skąd pochodzą.

Code
TypeScript
export function ListaZamowien({ zamowienia }: { zamowienia: Zamowienie[] }) {
  return (
    <ul className="flex flex-col gap-2">
      {zamowienia.map((z) => (
        <li key={z.id}>{z.numer}{z.status}</li>
      ))}
    </ul>
  )
}

export default async function Strona() {
  const zamowienia = await pobierzZamowienia()
  return <ListaZamowien zamowienia={zamowienia} />
}

Zysk widać dopiero przy drugiej zmianie. Komponent przyjmujący dane w właściwościach da się pokazać w katalogu komponentów, przetestować bez bazy i użyć ponownie na innym ekranie, a wygenerowany plik z pobieraniem w środku nie nadaje się do żadnej z tych trzech rzeczy.

Druga rzecz to nazwy. Generator nadaje je opisowo i po angielsku, często niezgodnie z konwencją projektu. Zmiana na etapie wklejania kosztuje minutę, a zostawiona na później zostaje na zawsze, bo nikt nie wraca do działającego kodu, żeby poprawić nazwę.

Trzecia to zależności. Wygenerowany kod potrafi sięgnąć po komponent shadcn/ui, którego jeszcze nie masz w projekcie, albo po ikonę z biblioteki, której nie używasz. Warto sprawdzić listę importów przed uruchomieniem, bo brakująca zależność zgłosi się jako błąd budowania, a niepotrzebna po prostu urośnie w pakiecie.

Czwarta to style. Wartości wpisane wprost, na przykład konkretne odcienie szarości albo odstępy spoza Twojej skali, wyglądają dobrze na jednym ekranie i rozjeżdżają się na dziesiątym. Zamiana ich na zmienne projektu przy wklejaniu jest tanim ubezpieczeniem.

Ostatnia rzecz dotyczy Next.js. Wygenerowany komponent bywa oznaczony jako kliencki, nawet gdy nic w nim tego nie wymaga. Sprawdzenie, czy dyrektywa jest potrzebna, i usunięcie jej tam, gdzie nie jest, zmniejsza kod wysyłany do przeglądarki bez żadnej innej zmiany.

v0 kontra alternatywy

NarzędzieCo robiGdzie działaKiedy wybrać
v0Generuje komponenty z opisuPrzeglądarka, plus APISzybki szkic układu w stosie Vercela
CursorZmienia kod w istniejącym projekcieEdytorPraca nad kodem, który już masz
Gotowe szablonyDostarcza gotowe układyKopiujesz do projektuStandardowy ekran, zero czekania
Projekt w narzędziu graficznymWarstwa wizualna bez koduOsobne narzędziePotrzebujesz zgody na wygląd przed kodem

Drugi wiersz to najczęstsze nieporozumienie. Te narzędzia nie konkurują, tylko obsługują różne momenty. v0 startuje od pustego miejsca i produkuje nowy widok. Asystent w edytorze pracuje na tym, co jest, widzi resztę projektu i utrzymuje spójność, której v0 z natury nie widzi.

Sensowny układ w praktyce wygląda tak: v0 do pierwszej wersji ekranu, którego jeszcze nie ma, a potem przeniesienie kodu do projektu i dalsza praca w edytorze. Próba prowadzenia całego rozwoju w narzędziu generującym kończy się na tym, że dwudziesty prompt naprawia to, co zepsuł osiemnasty.

Trzeci wiersz warto rozważyć uczciwie. Formularz logowania, panel z listą i kartami czy strona cennika istnieją w setkach gotowych wariantów, dostępnych od ręki i za darmo. Generowanie ich od zera bywa dłuższe niż znalezienie i dostosowanie. Zbiory takie jak TailGrids dają całe sekcje w klasach Tailwinda do skopiowania do siebie, przy czym darmowa na licencji MIT jest tylko część biblioteki, a reszta to jednorazowy zakup.

API i użycie programistyczne

Poza pracą w przeglądarce dostępny jest interfejs programistyczny, wpięty w plany płatne. Pozwala wywoływać generowanie z własnego kodu, czyli zbudować funkcję, w której użytkownik Twojej aplikacji opisuje układ, a Ty pokazujesz mu wynik.

Wywołanie sprowadza się do kilku wierszy, bo dostawca publikuje własną bibliotekę na licencji permisywnej. Klucz czytany jest ze zmiennej środowiskowej, więc nie trafia do kodu.

Code
TypeScript
import { v0 } from 'v0'

const wynik = await v0.chats.create({
  message: 'Panel administracyjny z lista zamowien i filtrem po statusie',
})

if (wynik.error) {
  throw new Error(wynik.error.message)
}

console.log('Utworzono rozmowe:', wynik.data.chat.id)

Zwrócony identyfikator rozmowy jest tu ważniejszy niż sam kod. Pozwala wrócić do tego samego wątku i poprosić o poprawkę, zamiast generować wszystko od nowa, a przy rozliczeniu tokenami to jest różnica w rachunku, nie tylko w wygodzie.

To ma sens w wąskim zestawie przypadków: narzędzia dla twórców treści, kreatory szablonów, wewnętrzne generatory widoków administracyjnych. W typowej aplikacji produktowej nie ma po co, bo generowanie interfejsu w czasie działania rozwiązuje problem, którego nie masz.

Przy takim wdrożeniu koszt trzeba policzyć osobno i wcześnie. Rozliczenie tokenami znaczy, że rachunek rośnie z liczbą użytkowników korzystających z tej funkcji, a nie z liczby Twoich programistów. Przy funkcji dostępnej dla wszystkich to jest zupełnie inna skala niż praca zespołu w przeglądarce.

Warto też przemyśleć, co się dzieje z kodem generowanym na żądanie. Uruchamianie w przeglądarce użytkownika kodu powstałego z jego własnego opisu jest bezpieczne, dopóki ten kod nie dotyka Twoich danych ani sesji. W izolowanej ramce jest to wykonalne, bezpośrednio w aplikacji zwykle nie.

Izolacja opiera się tu na dwóch atrybutach, z których drugi bywa pomijany, a jest ważniejszy.

Code
HTML
<iframe
  src="https://podglad.twojadomena.pl/abc123"
  sandbox="allow-scripts"
  referrerpolicy="no-referrer"
></iframe>

Pierwszy atrybut odbiera ramce wszystko poza wykonywaniem skryptów, więc kod nie sięgnie po ciasteczka ani po magazyn lokalny strony nadrzędnej. Kluczowe jest to, czego na liście nie ma: bez pozwolenia na to samo źródło ramka pozostaje obcym pochodzeniem, a dodanie go obok zezwolenia na skrypty znosi izolację w całości. Dlatego podgląd warto podawać z osobnej domeny, a nie z katalogu w aplikacji.

Wdrożenie do pracy zespołu

Kilka rzeczy oszczędza tarcia, jeśli narzędzie ma zostać na dłużej niż na jeden projekt.

Ustal, co wchodzi do repozytorium. Kod wygenerowany trafia do przeglądu tak samo jak napisany ręcznie, a nie obok niego. Bez tej zasady w projekcie pojawia się warstwa, której nikt nie czytał.

Zbuduj wspólny punkt startowy. Opis stosu, konwencji nazw i kształtu danych, wklejany na początku, daje bardziej spójne wyniki niż powtarzanie tego samego w każdym poleceniu przez każdą osobę osobno.

Pilnuj systemu wizualnego. Jeśli macie własne zmienne kolorów i skalę odstępów, podaj je w opisie, inaczej dostaniesz wartości domyślne z biblioteki i ktoś będzie je ręcznie zamieniał po każdym generowaniu.

Ostatnia rzecz to oczekiwania. Narzędzie skraca drogę do pierwszej wersji, a nie do wersji gotowej. Zespół, który tego nie ustali, prędzej czy później trafi na ekran wyglądający na skończony i wypuści go bez przejrzenia stanów brzegowych.

Typowe błędy

Pierwszy to traktowanie wyniku jako kodu produkcyjnego bez przeglądu. Wygląda kompletnie, a stany ładowania, błędu i pustej listy zwykle nie istnieją.

Drugi to prowadzenie długiej rozmowy nad jednym projektem zamiast przeniesienia kodu do repozytorium. Kontekst rośnie, koszt rośnie, a skuteczność poprawek spada.

Trzeci to generowanie od zera rzeczy, które istnieją jako gotowe szablony. Standardowy ekran szybciej znaleźć niż opisać.

Czwarty to pomijanie dostępności. Ogniskowanie klawiaturą i kontrast to dwie rzeczy, które warto sprawdzić za każdym razem, bo generator dobiera je pod wygląd.

Piąty to pięć zmian w jednym poleceniu. Wynik trzeba wtedy rozplątywać, a to kosztuje więcej niż pięć osobnych kroków.

Szósty to brak kontroli zużycia po zmianie na rozliczanie tokenami. Budżet nie wynika już z liczby generowań, więc bez patrzenia na zużycie miesiąc potrafi zaskoczyć.

Siódmy to używanie najmocniejszego modelu do wszystkiego. Poprawka odstępu nie wymaga tego samego, co pierwszy szkic złożonego widoku, a sama stawka za milion tokenów wyjścia dzieli najtańszy i najdroższy wariant mniej więcej czterdziestokrotnie, przy wyniku często nie do odróżnienia.

FAQ

Ile kosztuje v0?

Plan darmowy daje 5 USD kredytów miesięcznie i siedem wiadomości dziennie, a plany płatne kosztują 30 USD i 100 USD miesięcznie od użytkownika, przy czym oba dają te same 30 USD kredytów. Rozliczenie idzie od zużytych tokenów, a nie od liczby generowań, więc rachunek zależy od wybranego modelu i długości kontekstu. Po wyczerpaniu puli generowanie się zatrzymuje do czasu dokupienia kredytów.

Czy wygenerowany kod nadaje się do produkcji?

Jako punkt wyjścia tak, jako produkt końcowy rzadko. Układ i style zwykle są w porządku, natomiast obsługa stanów ładowania, błędu i pustych danych, dostępność oraz podpięcie prawdziwych danych pozostają do zrobienia.

Czy v0 działa poza stosem Vercela?

Kod to zwykły React z Tailwindem i komponentami shadcn/ui, więc wkleisz go do dowolnego projektu w tym stosie, niekoniecznie hostowanego w Vercelu. Przy innej bibliotece komponentów wynik trzeba przepisać i zysk czasowy maleje.

Czym różni się od asystenta w edytorze?

Momentem użycia. v0 tworzy nowy widok od zera i nie widzi reszty projektu. Asystent w edytorze pracuje na istniejącym kodzie, zna konwencje projektu i utrzymuje spójność, więc do rozwijania tego, co już działa, nadaje się lepiej.

Jak uzyskać spójny wygląd między ekranami?

Podawaj ten sam opis stosu, zmiennych kolorów i skali odstępów przy każdym generowaniu, a najlepiej dołączaj zrzut istniejącego ekranu. Każda sesja startuje w dużej mierze od nowa, więc spójność nie pojawi się sama.

Dokumentacja i opis interfejsu programistycznego stoją na stronie narzędzia, a warunki planów w cenniku Vercela.