Je hebt met Lovable, Bolt, Replit of v0 iets gebouwd dat werkt, of met Cursor op je eigen machine. Het ziet er goed uit, de demo overtuigt en je hebt er geen ontwikkelaar bij nodig gehad. Dan komt het moment dat er echte gebruikers op moeten, of echte klantgegevens in, en gaat het wringen. Er breken dingen die eerst werkten, en niemand kan precies uitleggen waarom.
Dat betekent niet dat je iets verkeerd hebt gedaan. Snel iets werkends neerzetten, vibe coding zoals het inmiddels heet, is waar deze tools goed in zijn. Alleen is “het doet het bij mij op het scherm” iets anders dan “hier kunnen klanten op”, en dat verschil zit in werk waar AI je nauwelijks bij helpt. Merk je dat je vaker repareert dan toevoegt, dan gaat dit stuk over jou.
Wat je al hebt
De meeste softwareprojecten beginnen bij een document vol wensen dat niemand kan uitproberen. Jij begint bij iets dat klikt. De schermen staan er, de stappen die een gebruiker doorloopt zijn uitgedacht en de bedrijfsregels die ertoe doen zitten er al in, ook al staan ze nergens opgeschreven.
Dat is een voorsprong. Een werkend prototype zegt meer dan een document met wensen, want je kunt het aanwijzen in plaats van beschrijven. Het is geen weggooiwerk, en ik behandel het ook niet zo.
Wat je in een demo niet ziet
De losse stukken zijn meestal prima. Nette functies, leesbare namen, gangbare patronen. Wat ontbreekt, is samenhang: het geheel is stukje bij beetje gegroeid zonder dat iemand het overzicht bewaakte. Wat de punten hieronder gemeen hebben, is dat je er in een demo niets van ziet.
Geheime sleutels in de browser
De geheime sleutels van je betaalprovider, mailprovider of AI-leverancier horen nooit in de browser, en de beheerssleutel van je database al helemaal niet: die mag langs alle beveiligingsregels heen die je in het volgende punt leest. Andere sleutels horen er wel, want die zijn bedoeld om openbaar te zijn en beschermen niets. Bij snel bouwen belanden de geheime sleutels regelmatig aan de verkeerde kant, waar iedereen die je app opent erbij kan. Verstoppen helpt niet. Ze moeten naar de serverkant, bij deze platformen meestal een edge function, een klein stukje code dat bij je leverancier draait, met de sleutel in de instellingen daarvan. En omdat ze ook in de geschiedenis van het project staan, zijn de oude hoe dan ook gelekt en moeten ze vervangen worden.
Ingelogd zijn is niet hetzelfde als iets mogen (row level security)
Bijna elk prototype krijgt inloggen werkend, want dat merk je meteen als het niet zo is. Wat vaak ontbreekt, is de laag daarna: mag deze ingelogde gebruiker ook echt bij dit dossier, deze factuur, deze klant? Die controle hoort aan de kant die de gebruiker niet in handen heeft. Bij een Lovable- of Bolt-app praat je browser vaak rechtstreeks met de database, dus dan is dat niet je server maar de regels in de database zelf, in Supabase de row level security. Alles wat alleen op het scherm gebeurt, kan een gebruiker omzeilen.
Dit kun je zelf nakijken, in vijf minuten. Maak een tweede account aan. Open iets van je eerste account, kopieer het ID uit de adresbalk, log in met het tweede account en plak dat ID erin. Zie je iets wat je niet hoort te zien, dan heb je dit probleem. Lukt het niet, dan is dat goed nieuws, maar het bewijst weinig: het scherm kan netjes filteren terwijl de database alles meestuurt. Wat er echt naar de browser gestuurd wordt, is met de juiste blik zo nagekeken.
De database is meegegroeid zonder plan
Bij elke nieuwe functie kwam er een veld of een tabel bij. Zolang de database nog leeg is, merk je daar niets van. Zodra er echte gegevens in zitten en je iets moet veranderen, blijkt niemand zo’n wijziging ooit geoefend te hebben. Er is geen testomgeving, en de back-up is nooit teruggezet. Elke wijziging is dan een gok met de gegevens die je al hebt verzameld.
Dezelfde logica staat op vijf plekken
Een AI-tool ziet bij elke vraag maar een deel van je project. Wat hij niet ziet, kan hij niet hergebruiken, dus schrijft hij iets nieuws dat op zichzelf werkt. Het resultaat werkt ook, maar één wijziging is nooit één wijziging. Je past de prijsberekening aan op de plek die je kent, en op de vier andere plekken blijft de oude staan. Er zijn ook geen tests die vastleggen wat het gedrag hoort te zijn, dus durft niemand iets weg te halen en groeit er van alles omheen. Daarom gaat doorontwikkelen op een gegeven moment steeds langzamer.
Het gaat een keer mis, en niemand monitort het
Wat gebeurt er als de betaalprovider er even uit ligt, als een upload halverwege afbreekt, of als twee mensen tegelijk dezelfde gegevens opslaan? In een prototype kom je dat nooit tegen. In productie is het een kwestie van tijd. Het vervelende is niet dat het gebeurt, maar dat niemand het merkt: er is niets dat fouten opvangt en meldt, dus je hoort het van je gebruikers. Dat is het verschil tussen binnen een uur repareren en drie weken lang stilletjes bestellingen kwijtraken.
Niets hiervan is exotisch. Het is het werk dat een ontwikkelaar normaal ongemerkt meeneemt en dat in een gesprek met een AI-tool nooit ter sprake komt, omdat je er niet naar vraagt als je niet weet dat het bestaat.
Dit is trouwens geen pleidooi tegen AI. Ik bouw er zelf ook mee, alleen op de plekken waar ik kan nakijken wat eruit komt. De platformen zijn er ook beter in geworden: sommige zetten de beveiligingsregels standaard aan en waarschuwen je voordat je publiceert. Wat zo’n controle niet kan weten, is wat de regels bij jou horen te zijn. Dat een accountmanager alleen zijn eigen klanten mag zien, staat in geen enkele scan. Dat staat alleen in jouw hoofd.
Vibe coding werkt, tot je iets moet veranderen
Vibe coding brengt je verrassend ver. Maar er is een grens, en die ligt bij het moment waarop je iets verandert en er ergens anders iets stukgaat, en je niet meer kunt overzien waar. Vanaf dat punt lossen extra vragen aan de AI het niet meer op: elke nieuwe prompt legt een laag over de vorige heen, en de app wordt niet stabieler maar groter.
Meestal merk je het aan één bug die niet weggaat. Je vraagt de AI om hem op te lossen, je hoort dat het gelukt is, en het is niet gelukt. Na de vijfde ronde heb je vijf dingen veranderd, weet je nog steeds niet wat er precies misging, en durf je niets meer terug te draaien. Dat ligt niet aan hoe je het vraagt. De tool kan alleen niet zien wat hij de vorige keer heeft aangepast, en jij kunt dat inmiddels ook niet meer.
Wanneer kun je veilig live?
Er is geen keurmerk en niemand die het voor je afvinkt. Productieklaar zijn komt neer op zes dingen die je zonder aarzelen moet kunnen bevestigen:
- Een gebruiker kan niet bij de gegevens van een ander, ook niet als hij het expres probeert.
- Er staan geen geheime sleutels in de code die je bezoekers binnenhalen.
- Er is een back-up, en die is een keer teruggezet om te kijken of dat werkt.
- Je kunt iets aan de database veranderen zonder dat bestaande gegevens sneuvelen.
- Als er iets misgaat, weet jij het voordat een klant belt.
- Je weet waar de klantgegevens staan en wie erbij kan.
De eerste drie zijn wat mij betreft niet onderhandelbaar zodra er echte gebruikers op zitten. De andere drie kun je inplannen, zolang je maar weet dat ze er nog niet zijn.
En de AVG
Staan er persoonsgegevens in, dan komt daar de AVG bij. Drie dingen zijn in een prototype vrijwel nooit geregeld: je weet niet in welk land de gegevens staan, er is geen verwerkersovereenkomst met de vier of vijf partijen die ze voor je verwerken, en je kunt de gegevens van één persoon niet gericht verwijderen. Het eerste is het vervelendst, want de regio kies je bij de meeste platformen één keer, bij het aanmaken van het project. Staat je app al in de Verenigde Staten, dan kost verhuizen downtime.
Twijfel je bij een paar van die zes, leg het me dan voor. Dat kost je niets, en dan zeg ik welke ik als eerste zou aanpakken.
Opnieuw beginnen is bijna nooit nodig
De reflex is dat het dan wel helemaal opnieuw moet. Dat is meestal niet zo, en het is bijna altijd de duurste optie. Wat er wel gebeurt, is dat het fundament stap voor stap wordt vervangen terwijl de applicatie blijft doen wat die deed.
Dat is hetzelfde werk als bestaande software overnemen van iemand anders, met één verschil dat in jouw voordeel werkt. Bij een gewone overname gaan mijn eerste weken op aan puzzelen: waarom staat dit hier, wat deed die ontwikkelaar hiermee, durf ik dit weg te halen. Bij een AI-prototype zit die persoon aan tafel. Jij weet nog waarom elk scherm er zo uitziet en welke regel er ooit voor één klant bij is gekomen. Daardoor duren zulke trajecten korter dan een gewone overname.
Hoe lang het precies duurt, verschilt sterk, maar het valt vaak mee. Is de beveiliging het enige echte probleem, dan kun je met een week of twee werk live. Zit de database in de knoop of hangen er koppelingen aan, dan loopt het op. Soms is opnieuw bouwen toch verstandiger, en dan zeg ik dat ook.
Hoe we beginnen
Je kunt me eerst gewoon mailen wat je hebt. Soms is daarmee al duidelijk dat je verder niets van mij nodig hebt.
Wat er in jouw geval moet gebeuren, weet ik pas als ik de app heb zien draaien. Daarna gaan de scherpe randen voor, de eerste drie hierboven, dan het fundament, en dan staat alles op jouw eigen GitHub en hosting. Vendor lock-in is daarmee weg: je zit aan geen enkel platform meer vast. Elke stap heeft een vaste prijs en na elke stap kun je stoppen, en de code is van jou, ook halverwege. Vanaf dat punt is het gewoon software die je kunt doorontwikkelen, met AI of zonder.
Hoe dat per stap werkt, staat op AI-prototype laten doorontwikkelen.
Je Lovable- of Bolt-app live krijgen
Heb je met AI iets gebouwd dat werkt, maar durf je er nog geen echte klantgegevens in te zetten? Stuur me een bericht met wat je gebouwd hebt en waar het wringt. Een paar zinnen is genoeg. Ik reageer binnen een werkdag met wat ik ervan vind, en dat kost je niets. Wil je liever bellen, zeg dat er dan bij.
Gaat het bij jou juist om AI toevoegen aan software die je al hebt, dan is AI integreren in je software het betere startpunt.
Ik werk als zelfstandig ontwikkelaar vanuit Groningen. Mijn afgeronde Upwork-projecten staan allemaal op vijf sterren; die beoordelingen staan ook op de homepage.