Wij plakten QR-codes op gedrukte menukaarten. Elke tool die we probeerden was óf opgeblazen, óf duur, óf hield de codes gegijzeld.
De tool die we gebruikten vroeg €25 per maand voor "onbeperkte" dynamische codes. Elke scan ging eerst langs een tussenpagina met een aftelklok van vijf seconden en een reclamebanner — nogal gênant naast het merk van een restaurant. En toen we het abonnement opzegden, stopte elke code die we ooit hadden laten drukken met werken. Menukaarten, tafelkaartjes, alles dood, omdat een incasso was gestopt.
Dat is het patroon in deze markt. Gratis tools verdienen aan een advertentie bij elke scan. Betaalde tools houden je gedrukte codes vast aan een maandelijkse afschrijving. Geen van beide gaat eigenlijk 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.