flatlink. Kurzlinks, die dir gehören.
Ein Kurzlink-Dienst mit QR-Generator, den du selbst betreibst. Reines PHP – kein Datenbank-Server, kein Composer, kein Build-Schritt. Kopieren, konfigurieren, läuft.
Auf GitHub ansehen Installation English
Warum offen?
Weil „wir tracken nicht" sonst nur eine Behauptung ist
Jeder Kurzlink-Dienst kann behaupten, keine Besucher zu verfolgen. Überprüfbar wird es erst mit dem Quelltext daneben. Das hier ist alles, was flatlink zu einem Kurzlink speichert:
Kein Datensatz für einzelne Aufrufe – also keine IP-Adressen, keine Uhrzeiten, keine gespeicherten Browser-Kennungen. Die unteren drei Zeilen sind Summen: Aus jeder Anfrage werden drei grobe Merkmale genommen und unmittelbar aufaddiert, vom Verweis nur der Hostname (nie der Pfad, in dem eine Suchanfrage stehen kann). Das beantwortet „woher kommen meine Klicks", ohne einen einzigen Besuch festzuhalten – und wem selbst das zu viel ist, schaltet es mit einer Zeile in der Konfiguration ab.
Der Weiterleitungspfad startet nicht einmal eine Sitzung, solange kein Passwortschutz auf dem Link liegt. Nachprüfen ist ausdrücklich erwünscht – genau dafür liegt der Code offen: Die ganze Zählung steht in inc/store.php.
Ein Blick hinein
Wie sich das anfühlt
Die Aufnahmen zeigen die deutsche Oberfläche; die Instanz-Sprache lässt sich auf Englisch stellen.
Nachgemessen
Der Bestand kostet drei Prozent
Eine Datei statt eines Datenbank-Servers klingt nach einer Grenze. Nachgemessen an fünfzig Millionen Kurzlinks (13-GB-Datei), durchgehend mit dem auf Shared Hosting üblichen Speicherlimit von 128 MB:
| Vorgang | 2 Links | 50 Mio. Links |
|---|---|---|
| Weiterleitung, gezählt | 0,208 ms | 0,214 ms |
| Erste Seite der Verwaltung | – | 0,04 ms |
| Letzte Seite (Seite 1.000.000) | – | 0,74 ms |
| Durchlauf über den ganzen Bestand | – | 50 s bei 2 MB |
Ein Kurzlink wird über seinen Primärschlüssel gefunden – ob daneben zwei oder fünfzig Millionen andere liegen, ändert daran nichts. Was mit dem Bestand wächst, wird gestreamt statt geladen: Aufräumen, Suche und Export gehen Zeile für Zeile bei gleichbleibendem Speicher.
Ehrlich dazu: Geschrieben wird nacheinander, nicht parallel – SQLite kennt einen Schreiber. Und auf Shared Hosting begrenzt am Ende das Inode-Kontingent des Vertrags, nicht die Datenbank. Beides steht mitsamt Zahlen in der README.
Was drin ist
Ein vollständiger Dienst, kein Codeschnipsel
QR-Codes ohne Fremdcode
Eigener Encoder nach ISO/IEC 18004. Formen, Farben, Logo in der Mitte, Rahmen mit freiem Text – als SVG, PNG und druckfertiges PDF.
Gedruckt und trotzdem änderbar
Ein gedruckter Code lässt sich nicht zurückrufen, sein Ziel schon. Jede Änderung wird mitgeschrieben – die letzten zwanzig je Link.
Ein Code, mehrere Ziele
Link-in-Bio-Seiten mit eigener Gestaltung, dazu Weichen nach Sprache oder Gerät und Zeitfenster je Link.
Erweiterung für den Browser
Die geöffnete Seite mit einem Klick kürzen – gegen die eigene Instanz, für Chrome und Firefox.
WLAN, Kontakt, Termin
Statische QR-Codes, deren Inhalt unmittelbar im Code steht: Sie funktionieren, auch wenn es die Instanz nicht mehr gibt.
Für Organisationen
Anmeldung am vorhandenen Verzeichnis (LDAP, Active Directory) oder über den Webserver (Shibboleth, SAML, OIDC).
Ordnung ab dem hundertsten Link
Schlagworte, Arbeitsgruppen mit eigenen Rechten und Limits, Namensräume je Abteilung, Massenimport per CSV.
Mehrere Domains
Ein flatlink-Server bedient beliebig viele Adressen, jede mit eigenem Namensraum: kunde-a.link/shop und kunde-b.link/shop sind zwei verschiedene Kurzlinks. Kunden bringen ihre Domain mit, ohne sich über Codes abzustimmen.
Passkeys statt Codes
Anmeldung in zwei Schritten: Ein Passkey tritt an die Stelle des Passworts, ein Einmalkennwort tritt daneben.
Schnittstelle und Umzug
REST-Schnittstelle mit OpenAPI-Beschreibung und eingeschränkten Schlüsseln. Exporte von Bitly, YOURLS, Shlink und Kutt lassen sich unverändert einlesen.
Keine Datenbank einzurichten
Links und Konten liegen in einer SQLite-Datei. Kein Server, den jemand aufsetzen und pflegen muss, keine Migrationsschritte beim Update – und eine Sicherung ist ein Kopiervorgang.
Missbrauchsschutz
Rate-Limits, Meldeformular, Sperren und optional Google Safe Browsing – auch als Wiederholungslauf über den Bestand.
Auskunft und Löschung
Jedes Konto lädt seine Daten als JSON herunter und löscht sich selbst – ohne den Betreiber zu fragen.
Sitzungen und Protokoll
Angemeldete Geräte einzeln abmelden; Verwaltungshandlungen bleiben nachvollziehbar – Besucher tauchen dort nie auf.
Barrierefrei und zweisprachig
Oberfläche auf Deutsch oder Englisch, Selbsteinschätzung nach WCAG 2.1 AA samt Muster-Erklärung für öffentliche Stellen.
Für wen
Wer so etwas selbst betreiben will
Vereine, Praxen, Gastronomie
Einen QR-Code drucken und das Ziel später ändern, ohne den Aufkleber zu tauschen. Genau dafür lohnt sich ein Kurzlink auf Papier.
Bibliotheken, Schulen, Verwaltungen
Kurzlinks, die das Haus nicht verlassen dürfen. Anmeldung über das vorhandene Verzeichnis, Gruppen je Abteilung, eigene Namensräume.
Agenturen
Mehrere Marken unter einem Dach: eigene Domain je Kunde, gemeinsame Arbeitsgruppen, Schnittstelle für die Automatisierung.
Zwei Instanzen laufen öffentlich: 1337.kiwi als kostenloser Dienst und hfmt.art an der Hochschule für Musik und Theater Hamburg, deren Anforderungen einen guten Teil dessen geprägt haben, was flatlink kann – Verzeichnis-Anmeldung, Gruppen, Namensräume, der CSV-Import aus YOURLS.
Installation
Kopieren, konfigurieren, läuft
Kein Composer, kein Build-Schritt, kein Datenbank-Server. Vorausgesetzt wird PHP 8.1 (mit pdo_sqlite, praktisch immer dabei) und ein Webserver, der Pfade umschreiben kann.
Wer lieber Container fährt: Ein Dockerfile und eine compose-Datei liegen im Repository, dazu ein Kubernetes-Manifest. Der Container läuft ohne Root-Rechte und mit beliebiger Benutzerkennung.
Für den ernsthaften Betrieb gibt es eine ausführliche Deployment-Anleitung – von Dateirechten über Mailversand bis zur kompletten Shibboleth-Einrichtung – und eine Anpassungs-Anleitung für eigene Farben und Logos.
Lizenz
Frei benutzbar, mit zwei Bedingungen
flatlink steht unter der GNU AGPL v3 mit einer Zusatzbedingung zur Namensnennung nach § 7(b) der Lizenz. Benutzen, selbst betreiben, ändern, weitergeben, umbenennen, einfärben – alles erlaubt, auch kommerziell und ohne zu fragen. Zwei Dinge bleiben:
Die Herkunftszeile bleibt
Jede Oberfläche nennt „flatlink" und verlinkt auf dieses Projekt. Übersetzen, umformulieren, klein und dezent setzen – alles erlaubt. Verstecken nicht.
Änderungen bleiben offen
Wer eine geänderte Fassung als Dienst anbietet, macht deren Quelltext seinen Nutzern zugänglich. Wer unverändert betreibt, muss nichts veröffentlichen.
Warum nicht MIT: Weil MIT erlaubt, den Quelltext zu schließen und daraus einen Dienst zu machen, bei dem niemand mehr nachsehen kann, was mit den Klickdaten passiert. Genau das nachsehen zu können ist der Punkt dieses Projekts.
Für eine Fassung ohne Herkunftszeile – etwa als White-Label – gibt es eine schriftliche Freistellung. Eine kurze Mail genügt.
Mitmachen
Fehlerberichte und Pull Requests sind willkommen – mit einer Bitte vorab: Die Abhängigkeitsfreiheit ist kein Zufall, sondern der Kern des Projekts. Ein Patch, der Composer, einen Build-Schritt oder einen Datenbank-Server voraussetzt, wird nicht übernommen, auch wenn er die Sache eleganter macht.
Sicherheitslücken bitte nicht als öffentliches Issue, sondern über den Weg in der SECURITY.md.