Een QR-code is een plaatje met een link erin. Zodra hij gegenereerd is, verandert er niets meer aan de code zelf. Toch verkopen de meeste tools hem als een abonnement.
Gratis tools verdienen aan een advertentie bij elke scan, vaak via een tussenpagina met een aftelklok voordat je bij de eigenlijke link komt. Betaalde tools vragen tien tot twintig euro per maand voor "onbeperkte dynamische codes" en zetten die codes vast aan dat abonnement: stop je met betalen, dan stopt de code met werken. Elke menukaart, elk visitekaartje, elke poster die ooit is gedrukt, dood, omdat een incasso is gestopt.
Geen van beide gaat over de QR-code. Allebei gaan ze over het abonnement.
Dus bouwde ik Scanoo.
Een gedrukte code is geen software
Een QR-code op papier is inkt. Zodra hij op een menukaart staat, op een bord in de voortuin of op een sticker op een etalageruit, kun je hem niet meer patchen. Het enige wat je nog kunt veranderen is waar hij naartoe wijst.
Daar zit precies de waarde van een dynamische code, en precies de reden dat de markt hem gijzelt: het is de enige knop die je nog hebt nadat de drukker is geweest.
Bij Scanoo maakt de gratis versie codes die gewoon werken, punt. Er zit een tussenpagina op gratis scans — dat is wat de tool gratis houdt — maar de codes blijven werken, ook als je nooit een cent betaalt, en de gratis versie verloopt niet. Betaal je wel, dan gaat die tussenpagina eraf en krijg je waar mensen echt om vragen: SVG-export, bestandshosting, scanstatistieken en AI-gegenereerde artistieke codes. Negen euro per maand, geen limiet op het aantal scans, maandelijks opzegbaar.
Eén schrijver, veel lezers, en een SQLite-bestand
De backend is een FastAPI-service, opgesplitst in aparte reader- en writer-deployments boven op SQLite.
Dat klinkt als vragen om problemen, want SQLite en meerdere processen gaan berucht slecht samen. De splitsing is precies wat dat oplost. Readerpods bedienen het API-verkeer en beantwoorden queries rechtstreeks tegen de database. Schrijfacties raken de lokale kopie van een reader nooit: die gaan via een commandobus over een Redis-stream naar één writer, en dat is het enige proces dat de database ooit verandert.
Wat dat oplevert: lezen schaalt horizontaal mee, deploys gaan zonder downtime, en er is nooit meer dan één schrijver op dat bestand. Je houdt de bedrijfszekerheid van SQLite over zonder de ellende die er meestal bij hoort.
Het is dezelfde vorm als bij profotograaf — één schrijver, meerdere lezers — maar daar staat Postgres onder en gebeurt de splitsing binnen één binary. Hier ligt er een Redis-stream tussen. Zelfde idee, andere schaal.
Waar het draait
Op onze eigen Kubernetes (k3s), op Europese servers die we zelf beheren. Geen PaaS, geen managed Kubernetes van een hyperscaler. Traefik ervoor, TLS overal via Let's Encrypt, en geen onversleuteld pad naar de app.
Wat eromheen hangt is bewust klein gehouden. Inloggen gaat via onze eigen identity provider, IAMBarn, in plaats van een auth-dienst die accountgegevens vasthoudt. Betalingen lopen via Stripe, zodat kaartgegevens onze servers nooit raken. De artistieke codes komen van ControlNet via Replicate. Fouten, productanalytics en traces gaan naar BugBarn, FunnelBarn en SpanBarn — allemaal zelf gehost, geen externe trackers.
Secrets staan versleuteld met SOPS en age, nooit in platte tekst in de repo en nooit in een logregel. Een push naar main bouwt en test automatisch; naar productie gaat het pas als iemand daar bewust op drukt.
Waarom we het zelf draaien
Omdat het kan, en omdat het goedkoper is. Veel meer is het niet. Er is geen reden om klantgegevens door een stapel externe leveranciers te sturen voor een product dat vooral één ding betrouwbaar moet doen: doorverwijzen.
Het maakt de belofte ook waar. "Je codes blijven werken" is makkelijk roepen als je zelf op andermans platform zit. Het betekent iets meer als je de servers, de deploys en de back-ups in eigen hand hebt.
Wat er nog komt
Alles wat er uitgaat komt op de changelog, inclusief de afweging erachter en niet alleen de featurelijst. Dat is bedoeld als eerlijkheid over wat er werkelijk in zit.
Ik gebruik het zelf nog steeds voor precies het soort werk waar het mee begon: kleine ondernemers die een QR-code nodig hebben die het gewoon doet, zonder abonnementsval eraan vast.