Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

liblin

libl.in (libre link) is a URL shortner built for hackers by a hacker. If you have a Codeberg account, you are already a libl.in user.

liblin is a free software, released under GPLV3 or later, and it’ll remain library forever. It stores know none of your data, yet it adds as your URL shortner. However in the future, for performance reasons, we could be storing your short links for a period of time.

The Idea

Most URL shorteners keep a database that maps a short code to a destination. liblin flips that around: your git repository is the database.

A liblin link has the shape:

https://libl.in/<username>/<document>

With the default libl.in mapping, <username> is a Codeberg account and <document> is a text file on the main branch of that account’s liblin repository. liblin fetches that file and redirects the visitor to the URL on its first line. The rest of the file is ignored, so it can hold notes.

For example, Alice creates demo.txt in her liblin repository with this first line:

https://example.com/a/very/long/url

Then https://libl.in/alice/demo redirects to that URL. The filename without the .txt suffix becomes the last part of the short link. If Alice later edits and commits demo.txt, the short URL stays the same and points to the new destination.

How a request flows

sequenceDiagram
    autonumber
    actor V as Visitor
    participant L as liblin
    participant R as domain-slurps.edn
    participant G as Git host
    participant D as Destination

    V->>L: GET https://libl.in/alice/demo
    L->>L: domain = libl.in:80<br/>paths = ["alice", "demo"]
    L->>R: look up libl.in:80
    R-->>L: URL template
    L->>L: render template
    L->>G: GET /alice/liblin/raw/branch/main/demo.txt
    G-->>L: first line = destination URL
    L-->>V: 302 Found<br/>Location: destination URL
    V->>D: follow redirect
    D-->>V: destination page
  1. Receive the short URL. The browser requests /alice/demo from libl.in.
  2. Find the domain mapping. liblin reads the RDL file named by LIBLIN_DOMAINS and looks up the host and port, libl.in:80. The path segments become paths, here ["alice", "demo"].
  3. Render the file location. The RDL template turns those segments into the raw URL of a file on the git host. In the default mapping, the first segment selects the repository owner and the remaining segments form the file path inside the repository. So alice/demo means demo.txt in Alice’s liblin repository, and alice/docs/demo means docs/demo.txt. With no document segment, index-if-empty falls back to index.txt.
  4. Fetch the file. liblin downloads that text file from the git host.
  5. Read the first line. That line is the real destination; later lines are ignored.
  6. Redirect. liblin returns 302 Found with the destination in the Location header. The browser follows it.

liblin reads both the RDL file and the destination file on every request, so without a caching proxy a commit is visible on the next request. liblin itself keeps no link cache. A future version of liblin may cache links briefly for performance, but the repository would remain the source of truth. If you put Nginx in front of liblin, see Hosting for optional cache settings and their trade-offs.

Why git?

Using a repository as the link store has several advantages:

  • No account or dashboard. Your existing Codeberg account and repository are all you need.
  • Versioned by default. Every link change is a commit, so you can inspect, revert, and audit it.
  • Editable anywhere. Use the Codeberg web editor, git, or any tool that can write a text file.
  • Portable. The redirects are plain text in a repository you control; you can fork, back up, or move them.
  • Stateless server. liblin can restart or be replaced without migrating a database.

Because the destination lives in your repository, a short link is only as private as that repository. On the hosted service the file must be publicly readable, since liblin fetches it without your credentials. Do not put secrets in a destination URL.

One server, many domains

RDL is what connects a hostname to a repository layout. The hosted service uses an entry like this:

{"libl.in:80"
 "https://codeberg.org/{{ paths[0] }}/liblin/raw/branch/main/{{ paths | rest | join | index-if-empty }}.txt"}

Change the template to support a different git host, repository name, branch, or file layout. See Redirect Language for the template language and Hosting for running your own instance.

Ready to create a link? See Getting Started.