Wat er echt in een met AI gebouwde app zit: een rondleiding voor niet-ontwikkelaars
Als je iets hebt gelanceerd met een AI-appbouwer en wilt begrijpen waar je naar kijkt, hier is een vriendelijke rondleiding langs de onderdelen — zonder het jargon.
Je typte een beschrijving, klikte op start, en twintig minuten later had je een werkende app. Mooi. Maar nu heb je op “bekijk bestanden” geklikt en staar je naar een mappenboom die eruitziet alsof hij in een andere taal is geschreven. Wat is package.json? Waarom staan er veertig dingen in node_modules? Wat betekent “schema” en waarom heb je er een?
Deze post is een rondleiding. Geen tutorial — een rondleiding. Na het lezen weet je niet hoe je een van deze bestanden zelf moet schrijven, maar de volgende keer dat iets er vreemd uitziet, weet je naar welke hoek van de app je moet wijzen.
Ik ga overal drie doorlopende voorbeelden gebruiken, zodat de abstracte delen iets concreets hebben om aan vast te haken:
- Maya, een marketinglead, die een verwijzingsklassement voor haar team bouwde.
- Jordan, een yogadocent, die een lesreserveringssite bouwde.
- Sam, die een bakkerij runt, die een “bestel de croissants van morgen vooruit”-pagina bouwde.
Alle drie gebruikten een AI-appbouwer. Alle drie de apps zien er voor een klant compleet anders uit. Onder de motorkap zijn ze verrassend vergelijkbaar gevormd.
De frontend: wat je klant echt ziet
De frontend is alles dat in iemands browser laadt. Knoppen, lay-outs, lettertypes, animaties, de manier waarop een formulier zichzelf leegmaakt nadat je hebt ingediend. Als je het kunt zien, is het frontend.
Voor Maya is de frontend een klassement met rang, naam en aantal verwijzingen. Voor Jordan is het een lesagenda met een “reserveer”-knop. Voor Sam is het een lijst met gebakjes met kleine plus-en-minknoppen naast elk.
Binnen het project leeft de frontend meestal in een map met een naam als app/, pages/ of src/. Je ziet bestanden die eindigen op .tsx of .jsx. Elk ervan is ruwweg “één scherm” of “één stuk van een scherm”. De klassementsrij is één bestand. De koptekst is een ander bestand. De pagina die het allemaal aan elkaar knoopt is een derde.
Wanneer je de AI-bouwer vraagt om “de knoppen ronder te maken” of “het klassement naar rechts te verplaatsen”, is dit het deel dat verandert.
De backend: het deel dat denkt
De backend is het deel dat niemand ziet, maar waar iedereen op vertrouwt. Het is de code die ergens anders draait — op een server, niet in de browser van de klant — wanneer er iets moet gebeuren dat de browser van de klant niet alleen vertrouwd zou moeten worden te doen.
Waarom kan de browser niet alles doen? Omdat de browser de machine van de klant is, en je hem niet kunt vertrouwen. Als Maya’s klassement de verwijzingsaantallen puur in de browser bijwerkte, kon iedereen rechtsklikken en zichzelf 9.000 verwijzingen toevoegen. Dus de backend is waar de regels leven: “deze persoon kan dit doen, maar dat niet”, “sla dit echt op in de database”, “stuur deze e-mail”.
De backend leeft meestal in een map met een naam als api/, server/ of app/api/. De bestanden daar zijn meestal kort. Elk ervan handelt een specifiek verzoek af: “maak een boeking aan”, “toon de croissants van vandaag”, “voeg een verwijzing toe”.
Wanneer iets werkt in je app maar het resultaat niet blijft hangen — je klikt op indienen, je ziet een bevestiging, maar morgen is de data weg — is de backend bijna altijd waar de bug zit.
De database: het geheugen van je app
Stel je het geheugen van je app voor als een rij archiefkasten. Elke kast heeft een label op de voorkant. Een zegt “gebruikers”. Een zegt “boekingen”. Een zegt “croissant_bestellingen”. Binnen elke kast is elke lade één rij. Elke lade heeft dezelfde set vakjes: een naam, een e-mail, een created_at, een status.
Die structuur — “welke kasten er bestaan, welke vakjes elke rij heeft” — heet een schema. Het is het belangrijkste bestand in het project, ook al ziet het er waarschijnlijk ook het saaist uit. Vind een bestand genaamd schema.ts, schema.prisma, of iets binnen een map genaamd db/ of migrations/. Open het. Je ziet een lijst die weerspiegelt wat je app echt onthoudt over de wereld.
Jordan’s schema heeft een classes-tabel, een bookings-tabel, en een users-tabel. Sam’s heeft products, orders en order_items. Maya’s heeft members en referrals. De vorm van het schema is de vorm van het product, en daarom is het later veranderen moeilijker dan veranderen hoe de knoppen eruitzien.
Een nuttige truc: als je in gewone woorden kunt beschrijven wat je app onthoudt, kun je meestal het schema beschrijven. “Ik onthoud de naam en e-mail van elke klant. Voor elke klant onthoud ik de bestellingen die ze plaatsten. Voor elke bestelling onthoud ik welke gebakjes en hoeveel van elk.” Die zin is, bijna woord voor woord, het schema.
Auth: de uitsmijter aan de deur
“Auth” is twee woorden samengeperst: authenticatie (wie ben je?) en autorisatie (wat mag je doen?). Beide worden meestal afgehandeld door een kleine set bestanden in een map genaamd auth/, of door een dienst waarvan je de naam misschien herkent: Clerk, Auth0, Supabase Auth, NextAuth.
De twee vragen zijn verschillend. Authenticatie beantwoordt: “is dit echt Maya?” — meestal met een wachtwoord, een Google-login, of een magic link die naar haar wordt gemaild. Autorisatie beantwoordt: “mag Maya andermans verwijzingen verwijderen?” — en het eerlijke antwoord voor de meeste met AI gebouwde apps in hun eerste week is “we vergaten te checken”.
Dit is het deel dat het vaakst stilletjes kapot is. Het loginscherm werkt, dus het voelt veilig. Maar de backend checkt niet altijd dat de ingelogde persoon dezelfde persoon is wiens data ze proberen te lezen. Als je app enig concept van “mijn data versus jouw data” heeft, vraag de AI-bouwer expliciet: “Zorg dat gebruikers alleen hun eigen data kunnen zien en bewerken.” Je zult verrast zijn hoe vaak die ene zin een ontbrekende check onthult.
Integraties: de dingen die je niet bouwde maar toch gebruikt
Hier onderschatten de meeste niet-ontwikkelaars wat er echt gebeurt. Het ding dat Sam’s “je croissants zijn klaar”-e-mail stuurt, is geen code — het is een account bij SendGrid of Resend. Het ding dat Jordan’s lesbetaling verwerkt, is geen code — het is Stripe. Het ding dat de foto’s op Maya’s klassement host, is geen code — het is een opslagdienst zoals S3 of Cloudinary.
Elke integratie duikt op twee plekken op. Er is een klein stukje code in de backend dat zegt “hé, Stripe, belast deze kaart”. En er is een sleutel — een lange geheime string — ergens veilig opgeslagen (meestal een bestand genaamd .env dat niemand ooit zou moeten committen) die aan Stripe bewijst dat het verzoek van Sam’s bakkerij kwam en niet van een vreemde.
Als je je ooit afvraagt waarom je app opeens stopt met e-mails sturen of stopt met betalingen accepteren, is de oorzaak bijna altijd een van: een verlopen sleutel, een bereikte gebruikslimiet, of een verandering in het beleid van de integratie. De code brak niet. De handdruk brak.
De deploy: hoe het op het internet komt
Het laatste stuk is het deel dat de map op je schijf verandert in een ding dat je klant kan bezoeken op een URL. Dit betekent meestal drie kleine dingen die samenwerken:
- De host: een dienst als Vercel, Netlify, Fly of Render die je backend draait en je frontend serveert.
- Het domein: een naam als
mayas-klassement.comdie naar je host wijst. - De build: het recept dat je rommelige bronbestanden neemt en ze omzet in de slankere, snellere versie die echt draait.
Wanneer iets lokaal werkt maar in productie breekt, zit het probleem meestal hier. Een sleutel die op je laptop is ingesteld maar niet op de host. Een bibliotheek die in ontwikkeling is geïnstalleerd maar niet in productie. Een database die in je browser bestaat maar niet op de live site.
De vijf-minuten-gewoonte die zichzelf terugverdient
Je hoeft niet elk bestand in je project te lezen. Je hoeft niet te weten wat de meeste ervan doen. Maar je zou, eens per week, een vijf-minuten-rondgang moeten doen waarin je elk van de mappen hierboven opent en de AI-bouwer in gewone woorden vraagt wat er veranderde.
Maya doet dit elke vrijdagmiddag. Ze typt: “Wat veranderde er deze week in het schema, en waarom?” En: “Zijn er nieuwe integraties in deze app die ik niet vroeg?” De antwoorden zijn bijna altijd geruststellend. De paar keer dat ze dat niet zijn, vangt ze problemen terwijl ze nog klein zijn.
Dat is het hele punt van de onderdelen begrijpen. Niet om een ontwikkelaar te worden. Gewoon om betere vragen te kunnen stellen.
Waar je vervolgens heen gaat
Als deze rondleiding hielp, zijn twee vervolgstukken je tijd waard. De ‘ziet er goed uit’-bug behandelt wat te doen wanneer een van deze onderdelen stilletjes kapot is, en demo-klaar versus productieklaar behandelt hoe je bepaalt wanneer je app van de eerste fase naar de tweede is verhuisd. Dezelfde kaart, andere gebruiken ervoor.