Dwa tygodnie. Dziesięć dni roboczych. Dokładnie tyle potrzeba, żeby mieć działający produkt w rękach pierwszych użytkowników — jeśli masz właściwy stack, wiesz co ciąć i nie próbujesz budować wszystkiego naraz.
To nie jest teoria. Poniżej jest konkretny plan, który stosujemy przy projektach klientów i własnych.
Czego NIE budować w v1
Większość MVP nie ginie przez zły kod. Ginie przez zły zakres.
Founder chce: pełny onboarding z email verification, dashboard z wykresami, system notyfikacji, zaawansowane filtry, eksport do CSV, zarządzanie rolami użytkowników, dark mode, aplikację mobilną.
V1 potrzebuje: jedno flow, które rozwiązuje jeden problem dla jednego segmentu użytkowników.
Konkretna lista rzeczy, które wycinasz z MVP bez dyskusji:
**Nie buduj uwierzytelniania od zera.** Supabase Auth lub Clerk dają Ci login, rejestrację, OAuth z Google w 30 minut. Nie ma powodu pisać własnego JWT flow w pierwszej iteracji.
**Nie buduj panelu admina.** Przeglądaj dane bezpośrednio przez Supabase Studio lub Drizzle Studio. Panel admina to tygodnie pracy dla funkcji, którą używasz raz dziennie.
**Nie optymalizuj.** Caching, CDN dla zasobów dynamicznych, query optimization — to problemy skalowania. Najpierw udowodnij, że ktoś chce używać produktu.
**Nie buduj integracji.** Slack, Zapier, webhooks — to funkcje v2. V1 ma działać samodzielnie.
**Nie buduj płatności dopóki nie masz użytkowników.** Jeśli Twój MVP wymaga płatności na dzień pierwszy — możesz obsłużyć pierwsze transakcje ręcznie przez PayPal lub przelew. Stripe wchodzi gdy masz powtarzalny ruch.
Stack który daje 2-tygodniowe MVP
Wybór technologii ma ogromne znaczenie dla tempa. Każda niestandardowa decyzja technologiczna kosztuje czas.
**Frontend: Astro lub Next.js**
Astro jest właściwym wyborem gdy produkt to głównie content z interaktywnymi wyspami — landing page, blog, dokumentacja z formularzem. Zero JavaScript po stronie klienta domyślnie, szybki start, deployment na Vercel lub Netlify w minuty.
Next.js wybierasz gdy produkt jest aplikacją — dashboard, SaaS z logowaniem, cokolwiek gdzie użytkownik ma stan sesji i widoki zmieniają się dynamicznie. Server Components redukują ilość kodu klienckiego, App Router daje intuicyjny routing.
```bash # Nowy projekt Astro npm create astro@latest my-mvp
# Nowy projekt Next.js npx create-next-app@latest my-mvp --typescript --tailwind --app ```
**Styling: Tailwind CSS**
Nie ma tutaj dyskusji. Tailwind pozwala stylować bez przełączania między plikami i bez wymyślania nazw klas. Z shadcn/ui masz gotowe komponenty (Button, Dialog, Table, Form) które wklejasz i modyfikujesz.
```bash # Dodanie shadcn/ui do projektu Next.js npx shadcn@latest init npx shadcn@latest add button dialog table form ```
**Backend: Hono na Vercel Edge Functions**
Dla prostych MVP Supabase często wystarczy bez dedykowanego backendu — klient Supabase działa po stronie serwera w Next.js Server Actions. Ale jeśli potrzebujesz własnej logiki biznesowej, Hono na Vercel jest najszybszą ścieżką do działającego API.
```typescript import { Hono } from 'hono' import { handle } from 'hono/vercel'
const app = new Hono().basePath('/api')
app.get('/status', (c) => { return c.json({ status: 'ok', version: '0.1.0' }) })
app.post('/submit', async (c) => { const body = await c.req.json() // logika biznesowa return c.json({ success: true }) })
export const GET = handle(app) export const POST = handle(app) ```
**Baza danych: Supabase**
Supabase daje Ci PostgreSQL, uwierzytelnianie, storage na pliki i realtime w jednym miejscu. Free tier wystarczy na MVP — 500MB bazy, 1GB storage, 50 000 aktywnych użytkowników miesięcznie.
```typescript import { createClient } from '@supabase/supabase-js'
const supabase = createClient( process.env.NEXT_PUBLIC_SUPABASE_URL!, process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY! )
// Przykład zapytania z typowaniem const { data, error } = await supabase .from('submissions') .insert({ email, message, created_at: new Date() }) .select() ```
**Deployment: Vercel**
Git push → automatyczny deployment → URL działający w minutę. Vercel obsługuje Astro, Next.js, Edge Functions. Dla MVP jest bezpłatny z bardzo hojnym limitem.
Podział na tygodnie
**Tydzień 1: Fundament i core flow**
Dni 1–2: Setup i szkielet.
Zainicjuj projekt, skonfiguruj Tailwind i shadcn, połącz Supabase, ustaw zmienne środowiskowe, deploy na Vercel (zrób to od razu — deployment nie może być niespodzianką na koniec). Napisz schemat bazy danych dla core feature.
```sql -- Przykładowy schemat dla aplikacji zbierającej zgłoszenia create table submissions ( id uuid default gen_random_uuid() primary key, email text not null, message text not null, status text default 'new', created_at timestamptz default now() );
-- Row Level Security alter table submissions enable row level security;
create policy "Authenticated users can read submissions" on submissions for select using (auth.role() = 'authenticated'); ```
Dni 3–5: Core user flow.
Jedna ścieżka, od początku do końca, działająca. Jeśli to aplikacja do wysyłania zgłoszeń — formularz, zapisanie do bazy, email potwierdzający. Jeśli to SaaS z logowaniem — rejestracja, panel główny, jedna kluczowa akcja użytkownika.
Nic więcej. Nie zaglądaj do backlogu.
**Tydzień 2: Polish i pierwsi użytkownicy**
Dni 6–7: Error handling i edge cases.
Co się dzieje gdy formularz nie działa? Co gdy baza jest niedostępna? Co gdy użytkownik wpisze nieprawidłowe dane? Obsłuż te przypadki — nie musi być pięknie, musi być przewidywalnie.
Walidacja po stronie klienta z react-hook-form + Zod:
```typescript import { useForm } from 'react-hook-form' import { zodResolver } from '@hookform/resolvers/zod' import { z } from 'zod'
const schema = z.object({ email: z.string().email('Nieprawidłowy email'), message: z.string().min(10, 'Wiadomość musi mieć min. 10 znaków'), })
type FormData = z.infer
export function SubmitForm() {
const { register, handleSubmit, formState: { errors } } = useForm
const onSubmit = async (data: FormData) => { const res = await fetch('/api/submit', { method: 'POST', body: JSON.stringify(data), }) // obsługa odpowiedzi }
return (
) } ```Dni 8–9: Landing page i onboarding.
Opisz co robisz w jednym zdaniu. Pokaż zrzut ekranu lub demo. Dodaj formularz kontaktowy lub przycisk "Zacznij". To jest różnica między produktem a projektem.
Dzień 10: Pierwsi użytkownicy.
Wyślij 10 wiadomości do znajomych, którzy pasują do grupy docelowej. Nie do wszystkich — do tych, którzy mają problem, który rozwiązujesz. Zbieraj feedback bezpośrednio, nie przez ankietę.
Najczęstsze błędy founderów
**Perfekcjonizm designu.** MVP ma pokazać, że mechanizm działa — nie że wygląda jak produkt Apple. Użytkownicy powiedzą Ci co jest ważne, reszta to zgadywanie.
**Zbyt szeroki zakres.** "Dodamy to w dwa dni" — nie dodacie. Każda dodatkowa funkcja to nie tylko kod, to decyzje UX, edge cases, testy, dokumentacja. Jeden feature zrobiony dobrze > pięć zrobionych połowicznie.
**Brak prawdziwych użytkowników.** Feedback od rodziny i znajomych jest obciążony. Potrzebujesz kogoś, kto ma realny problem — i nie zna Cię osobiście.
**Zmiana stacku w trakcie.** Jeśli zacząłeś z Next.js, kończ z Next.js. Przechodzenie na inny framework w połowie projektu to restart, nie optymalizacja.
**Budowanie bez deploymentu.** MVP, który działa tylko lokalnie, nie istnieje. Deploy na Vercel od dnia 1 — każda iteracja trafia na prawdziwy URL.
Dwa tygodnie to wystarczająco
Dwa tygodnie to wystarczająco dużo czasu, żeby mieć odpowiedź na najważniejsze pytanie: czy ktoś chce używać tego co budujesz?
Stack — Astro lub Next.js, Tailwind, Supabase, Hono, Vercel — jest sprawdzony i eliminuje większość decyzji technicznych zanim zaczniesz. Zostaje tylko jedna decyzja: co dokładnie ma robić v1.
Odpowiedz na to pytanie przed pierwszym commitem. Reszta to wykonanie.
Potrzebujesz podobnego rozwiązania?
Porozmawiajmy o Twoim projekcie
Pierwsza rozmowa jest bezpłatna. Opisz nam swój pomysł — odpowiemy w ciągu jednego dnia roboczego.
Umów bezpłatną rozmowę