Self-hosted service
shlinkio/shlink avatar
shlinkio/shlink

Shlink: short URLs under your own domain, from a PHP server you own

The definitive self-hosted URL shortener

5,309 stars421 forksPHPMIT

At a glance

What is it?
Shlink is an MIT-licensed PHP-based self-hosted URL shortener serving shortened URLs under your own domain, with PHP 8.4 or 8.5, five database options from MySQL to SQLite, a CLI and a REST API for the same operations, and a companion web client. It ships as per-PHP-version dist packages or an official Docker image with RoadRunner as an alternative runtime, includes GeoLite2-powered visit geolocation, and released v5.1.7 in September 2026.
Who is it for?
Use Shlink when shortened links must live under a domain you control, with your own database, your own rate of feature change and no third party learning your traffic, whether for a personal site or a product's campaign links. Keep using a hosted shortener when operating any server at all is not worth it, since self-hosting is the entire point here.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly PHP, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 30, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The definitive self-hosted shortener, as it describes itself

Shlink's one-line description is the definitive self-hosted URL shortener, a PHP-based service for serving shortened URLs under your own domain, and every design choice follows from self-hosting being the point rather than a deployment option. The links belong to a domain you control, the data lives in a database you chose, from MySQL, MariaDB, PostgreSQL and Microsoft SQL Server down to plain SQLite, and the geolocation of visits comes from the bundled GeoLite2 data by MaxMind, whose attribution the README carries as a legal notice, with no external analytics service in the loop. The current line is v5.1.x with three patch releases across June and September 2026, the repository's default branch is develop, and the project publishes a full searchable documentation site beyond the README's deliberately minimal getting-started, the shape of a tool that expects operators, not just developers.

Requirements: PHP 8.4 and the extension checklist

The self-hosted requirements read like a sysadmin's worksheet. PHP 8.4 or 8.5, with the json, curl, pdo, intl, gd and gmp or bcmath extensions as the baseline. The apcu extension is recommended unless you plan to run RoadRunner, the alternative PHP application server, an either-or that signals the two supported performance profiles. Sockets and bcmath become required if you want to integrate with a RabbitMQ instance, the message-queue option for event-driven setups. The database side needs the matching pdo variation, pdo_mysql, pdo_pgsql, pdo_sqlsrv or pdo_sqlite, for whichever of the five databases you select. The breadth here is deliberate, a shortener wants to run on whatever the operator already has, and the Docker image encodes the same list, its Dockerfile compiling the pdo extensions for every supported database plus the Microsoft sqlsrv driver on x86_64 builds, so the container is equally at home in any database estate.

A dist zip per PHP version, or build it yourself

Getting a built version offers two documented paths. The easy one downloads a pre-bundled distributable package from the latest release, a shlink dist zip published for every supported PHP version, decompressed wherever it will run. Building from source is three steps, clone with git, download Composer into the project, and run the build script with a version number:

bash
git clone https://github.com/shlinkio/shlink.git

The build script, invoked as ./build.sh with the version you intend to build, produces a dist file in the build directory to decompress in place, and the README notes this is precisely the release process itself, a GitHub workflow tags a version, builds the dist and attaches it to the release automatically. That symmetry, the maintainer's release pipeline and the user's build path being the same script, removes an entire class of works-on-my-machine divergence, and the dist-per-PHP-version packaging means the operator picks the binary matching the interpreter already installed rather than managing a runtime first.

The installer runs on the server, then the API key

Configuration is a four-step ritual with one emphatic rule. If the database is one of the server varieties, create an empty database first. Recursively grant write permissions to the data directory, which Shlink uses to cache information. Then run the installer:

bash
vendor/bin/shlink-installer install

The bold warning around this step is unusual and specific, the tool has to be run directly on the server where you plan to host Shlink, not before uploading or moving it there, because the guided configuration writes values tied to the final environment. The last step generates the first API key:

bash
bin/cli api-key:generate

which is required to interact with the REST API at all, security bootstrap expressed as an explicit command rather than a default credential. The split matters, the installer is infrastructure-specific and single-run, while the API key is the ongoing credential that unlocks everything the web client and external integrations will do.

Two front doors: bin/cli and the REST API

Once installed, Shlink offers two main interaction surfaces, and the README states their relationship precisely, the API and CLI allow mostly the same operations, except for API key management, which is CLI-only. The command line begins with bin/cli to list every command, each accepting --help for its options, and the README suggests symlinking the entry point into your path so shlink runs from any directory, the small ergonomics that decide whether an operator actually uses the CLI daily. The REST API's complete documentation lives on the project site with an interactive sandbox at the api-spec portal documenting every endpoint, and rather than consuming the raw API, most users point the companion web client at it, usable directly from app.shlink.io or self-hosted, a separate repository keeping server and interface independently deployable. The parity-plus-exceptions design means automation scripts and the web UI drive the same server, and credentials rotation stays a terminal task.

Docker with RoadRunner, and the dev-compose menagerie

The official Docker image is the recommended modern deployment, configured entirely through environment variables, with a runtime flag selecting between the classic PHP setup and RoadRunner, the Go-based application server that keeps PHP workers resident. The development docker-compose file reveals the project's test surface, a php container and a roadrunner container both linked to eight backing services, MySQL, PostgreSQL, MariaDB and Microsoft SQL Server simultaneously, two Redis variants including one with ACL, Mercure for server-sent events with and without proxy, RabbitMQ and Matomo, the whole compatibility matrix runnable on one machine. That development topology doubles as a statement of supported integrations, caching, message queuing, real-time updates and web analytics all have first-class wiring, and the phpunit configuration splits the suite into api, cli and db files matching the surfaces, with a mago static-analysis configuration and baseline completing the quality tooling.

Release discipline and the surrounding ecosystem

The maintenance rhythm is steady and transparent, v5.1.5 in June 2026, v5.1.6 on September 6 and v5.1.7 on September 21, the same day as the last repository push, with a CHANGELOG, an UPGRADE guide for moving between versions and a SECURITY policy in place, the documentation triad that separates operable software from code that happens to run. JetBrains supports the project with IDE licenses, donation links sit beside Fediverse and Bluesky accounts, and the ecosystem around the core includes the web client already noted and the API sandbox. Set against hosted shorteners the value is ownership, links that cannot be deprecated out from under you because the company pivoted, and set against other self-hosted shorteners the differentiator is breadth, five databases, two runtimes, queue and cache integrations, and a web client, the accumulated features of a project that has been the reference answer in its category for years.

Editorial conclusion

Use Shlink when shortened links must live under a domain you control, with your own database, your own rate of feature change and no third party learning your traffic, whether for a personal site or a product's campaign links. Keep using a hosted shortener when operating any server at all is not worth it, since self-hosting is the entire point here. Verify first that your host meets the PHP 8.4 or 8.5 requirement with the listed extensions, choose your database before running the installer because it configures the pdo driver accordingly, run the installer on the server itself as documented, and generate an API key immediately or the REST API stays locked.

Frequently asked questions

What is shlink?

Shlink is a PHP-based self-hosted URL shortener that serves shortened URLs under your own domain, storing data in MySQL, MariaDB, PostgreSQL, Microsoft SQL Server or SQLite and geolocating visits with bundled GeoLite2 data. It offers a CLI and a REST API for the same operations, plus a companion web client.

How do you install shlink?

Download a shlink dist zip for your PHP version from the latest GitHub release, or build from source by cloning, installing Composer and running the build script. Then create the database if needed, grant write access to the data directory, run vendor/bin/shlink-installer install on the server itself, and generate an API key with bin/cli api-key:generate.

How do you use shlink?

Through the command line, starting with bin/cli to list commands, each documented via --help, or through the REST API documented at the api-spec sandbox, with the official web client at app.shlink.io or self-hosted for a graphical interface. API key management is available from the CLI only.

Is shlink free?

Yes, it is MIT-licensed open source, free to self-host from the dist packages or the official Docker image. The costs are operational, a server meeting the PHP 8.4 or 8.5 requirements and a database, and the project accepts donations alongside its commercial sponsorships.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. shlinkio/shlink on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/shlinkio-shlink.svg)](https://hysenlabs.com/projects/shlinkio-shlink)