Nocly.fr
Back to projects

Tessera — privacy-first dynamic QR codes

Repoint a QR after it's printed, measure without tracking, and self-host all of it

Client
Open-source
Period
2026
Tech stack
Symfony 7API Platform 4AngularPostgreSQLRedisDocker

Context

A printed QR code is forever — unless it's dynamic. Tessera routes every code through a short link you control, so you can change the destination anytime without reprinting. It was designed from the start to be open-source, self-hostable and privacy-first.

The challenge

Deliver low-latency dynamic redirects and genuinely useful analytics without ever breaking the privacy promise or locking users in: their codes must keep working even if they leave the service, and their scans must leave no identifying trace.

Before

Most dynamic-QR services hold users hostage: if the subscription lapses, codes point to a marketing page (or die), and every scan feeds a third-party tracker.

After

Codes that always resolve to an owner-chosen fallback, country-level analytics with no IP storage at all, and a fully self-hostable stack under the MIT license.

The approach

Symfony 7 / API Platform 4 backend, but the redirect endpoint is a plain controller (outside API Platform) for latency, backed by a Redis slug cache. Redirects are always 302 — the destination is mutable, and a cached 301 would break the product. Scan logging is asynchronous via Symfony Messenger so it never blocks the redirect. Geolocation is limited to country via a local GeoLite2 database: the IP is used to derive a country, then discarded — never stored. Angular frontend with runtime i18n (5 languages: EN/FR/ES/IT/DE) via Transloco. One-command deployment with Docker Compose.

Previews

Account dashboard with the code list and their analytics
Per-code detail: scans over time, country, device, referrer
QR generator and export (PNG / SVG)

Outcome

Version 1.0.0 shipped and working end to end, self-hostable in a single command, with a public guided demo (session-isolated data). A real community-grade open-source project: MIT license, continuous integration and CodeQL analysis, a contribution guide and a security policy. The billing layer (custom domain, branding, teams) is designed but disabled behind a flag — self-host stays the free offer.

Key numbers

5
UI languages, switchable at runtime
302
redirects always mutable, never 301
0
IP addresses stored
MIT
open-source license
Open-sourcePrivacy-firstSelf-host