Profile
Back to NewsBack
GitHub Trending 10 min
Reader Mode
Manak-hash/LinkBreeze: The self-hosted Linktree alternative. Import from any competitor in 30 seconds. Multi-page, privacy-respecting analytics, one-line install.

Manak-hash/LinkBreeze: The self-hosted Linktree alternative. Import from any competitor in 30 seconds. Multi-page, privacy-respecting analytics, one-line install.

7 hours ago


Stop paying $15/mo for Linktree. LinkBreeze gives you links, analytics,
QR codes, themes, and a real admin panel — free, forever, in one Docker command.

🔗 Live Demo — see the public page in action.

🔐 Demo Dashboard — see the dashboard with all features (read-only).

✨ Features

  • 🔗 Link Management — Add, reorder, and customize unlimited links with drag-and-drop
  • 🌐 Multi-Page Support — Create unlimited pages, each with its own slug, theme, links, analytics, SEO, and QR code
  • 🎨 Auto-Favicon Links — Links automatically show the target site's favicon — no manual icon uploads needed
  • 📥 Migration Wizard — Import existing links and social profiles from Linktree, Bento, Hopp.bio, LittleLink, or any HTML/JSON export
  • 🖼️ Link Thumbnails — Add images to your links for visual preview cards
  • 🎵 Embed Widgets — Embed YouTube, Spotify, SoundCloud, Vimeo, or Bandcamp directly on your page
  • ⏰ Link Scheduling — Schedule links to appear/disappear automatically with date/time controls
  • 🏷️ Custom Redirect Slugs — Give any link a stable, shareable /go/your-name URL that survives delete-and-recreate. Reserved names and pure numbers are blocked so app routes can never be shadowed; a deactivated link with a slug redirects visitors to your public page instead of a 404
  • 📊 Privacy-Respecting Analytics — Views, clicks, referrers, device type. Cookieless by design. Visitor IPs are hashed with a daily-rotating salt, never stored. Data older than 90 days is pruned automatically by default (Settings → Data; set 0 to keep everything).
  • 📈 External Analytics — Inject Plausible, Umami, Matomo, or Google Analytics with one paste
  • 🔔 Update Notifications — Dashboard banner notifies you when a new version is available (no phone-home, no auto-update)
  • 🎨 Themes — 11 built-in presets (Aurora, Glassmorphism, Neon Cyberpunk, Editorial Paper, Terminal Mono, Pastel Soft, Brutalist, Retro Sunset, Minimal Light, 8-Bit Retro, Frutiger Aero) + full customizer with CSS token system (colors, 15 fonts + custom font upload, 8 background types, 8 card styles, layout controls, effects) + theme duplicate/import/export
  • ✏️ Custom CSS — Fine-tune your page with raw CSS injection
  • 📧 Email Capture — Collect subscriber emails on your public page, export to CSV
  • 📱 Mobile-First — Gorgeous on every screen. Loads in under 300ms. Zero client-side JS bundles.
  • 🎯 QR Codes — Auto-generated for your page. Download as SVG or PNG. Customize colors, embed your avatar or favicon in the center, export up to 1024 px for print.
  • 🔒 Self-Hosted — Your data, your server. No third-party trackers. No ads. No subscription.
  • 🐳 One-Command Deploy — Docker compose and you're live

🚀 Quick Start

One command — zero config — live in 30 seconds:

curl -fsSL https://linkbreeze.omnirise.dev/install.sh | bash

or pull the multi-arch image directly:

docker run -d --name linkbreeze --restart unless-stopped -p 3000:3000 -v linkbreeze-data:/app/data docker.io/omnirise/linkbreeze:latest

The script detects Docker or Podman, pulls the image, starts the container, and optionally sets up a systemd service for auto-start on boot. Want auto-start on boot? Run it with sudo bash instead and answer y when prompted.

Don't like piping to bash?

curl -fsSL https://linkbreeze.omnirise.dev/install.sh -o install.sh
less install.sh
bash install.sh

Then open http://localhost:3000 — the setup wizard takes under 30 seconds.

Prefer a different method? Expand one below:

🐳  Docker

No Node.js, no npm, no config files needed. Multi-arch images: linux/amd64 and linux/arm64 (Raspberry Pi 3/4/5, Apple Silicon, ARM VPS).

Linux / macOS / Windows CMD:

docker run -d --name linkbreeze --restart unless-stopped -p 3000:3000 -v linkbreeze-data:/app/data docker.io/omnirise/linkbreeze:latest

Windows PowerShell — use backticks for line breaks:

docker run -d 
  --name linkbreeze 
  --restart unless-stopped 
  -p 3000:3000 
  -v linkbreeze-data:/app/data 
  docker.io/omnirise/linkbreeze:latest
Database migrations run automatically on container startup — no manual
drizzle-kit migrate needed for Docker deployments.

🧩  Docker Compose

Best if you want to customize ports, add a reverse proxy, or manage updates easily.

Option A — Pull the pre-built image:

Create a docker-compose.yml:

services:
  linkbreeze:
    image: docker.io/omnirise/linkbreeze:latest
    ports:
      - "3000:3000"
    volumes:
      - linkbreeze-data:/app/data
    restart: unless-stopped

volumes: linkbreeze-data:

docker compose up -d

Option B — Build from source:

git clone https://github.com/Manak-hash/LinkBreeze.git
cd LinkBreeze
docker compose up -d --build

Upgrade anytime: docker compose pull && docker compose up -d

Logs: docker compose logs -f linkbreeze

☁️  Coolify

Running Coolify on your VPS?

  1. + New Resource → Docker Compose Empty
  2. Paste:
services:
  linkbreeze:
    image: docker.io/omnirise/linkbreeze:latest
    ports:
      - "3000:3000"
    volumes:
      - linkbreeze-data:/app/data
    restart: unless-stopped

volumes: linkbreeze-data:

  1. Set a domain (e.g., links.yourdomain.com) for automatic SSL
  2. Click Deploy — Coolify handles Let's Encrypt automatically

📦  Synology NAS

Running Synology DiskStation with Container Manager (DSM 7.2+)?

  1. Open Container Manager → Container → Create
  2. Image: docker.io/omnirise/linkbreeze:latest (pull it first via Image → Add if not found)
  3. Container settings:
- Name: linkbreeze - Port: Local 3000 → Container 3000 - Volume: Create /docker/linkbreeze/data and map to /app/data - Restart policy: Unless stopped
  1. Click Done — live at http://:3000
Update later: pull the latest image, stop and recreate the container. Data persists in the volume.

🔧  Podman

Using Podman instead of Docker (RHEL, Fedora, CentOS)? Replace docker with podman:

podman run -d --name linkbreeze --restart unless-stopped -p 3000:3000 -v linkbreeze-data:/app/data docker.io/omnirise/linkbreeze:latest

If you get permission errors on the volume, create it first: podman volume create linkbreeze-data

For systemd integration with rootless Podman: podman generate systemd after starting the container.

The one-line install script at the top of this section detects Podman automatically.

🖥️  Portainer

Using Portainer to manage containers? Deploy as a Stack.

  1. Go to your environment → Stacks → Add stack
  2. Name it linkbreeze and paste:
services:
  linkbreeze:
    image: docker.io/omnirise/linkbreeze:latest
    ports:
      - "3000:3000"
    volumes:
      - linkbreeze-data:/app/data
    restart: unless-stopped

volumes: linkbreeze-data:

  1. Click Deploy the stack
Update: Stacks → linkbreeze → Editor → click Pull and redeploy.

🔨  Manual (without Docker)

Requires Node.js 18+.

git clone https://github.com/Manak-hash/LinkBreeze.git
cd LinkBreeze

npm install

cp .env.example .env

Edit .env to set your SECRET_KEY and DATABASE_PATH if needed

npm run db:migrate npm run dev

For production: npm run build && npm start

🌐 Making Your Page Public

LinkBreeze runs on your server. Once deployed, your page is accessible to anyone at https://your-domain.com/your-slug. Here's how to get it online:

Quick start: Point your domain

  1. Point your domain's A record to your server IP
  2. Expose port 3000 or add a reverse proxy
  3. Done — your page is live at https://your-domain.com/your-slug

Advanced deployment scenarios

For production setups — reverse proxies with automatic TLS, zero-trust tunnels, Kubernetes, scheduled backups — see the examples/ directory. Each example is a single, self-contained file with a header comment explaining when to use it.

Quick reference: which example for which scenario?

| What you want | Use this file | |---------------|---------------| | Automatic TLS without manual config | docker-compose.caddy.yml or docker-compose.https-portal.yml | | Automatic TLS with a dashboard (Traefik) | docker-compose.traefik.yml | | Expose without opening ports (zero-trust) | docker-compose.cloudflare-tunnel.yml | | You already use Nginx + Certbot | docker-compose.nginx.yml | | Scheduled SQLite backups | docker-compose.with-backup.yml | | Running on Kubernetes cluster | kubernetes.yaml |

Option 1: Reverse Proxy with Your Domain

Point your domain's A record to your server IP, then use a reverse proxy with automatic HTTPS:

Caddy (recommended — auto HTTPS)

links.example.com {
    reverse_proxy localhost:3000
}

For a complete Docker Compose setup with Caddy, see examples/docker-compose.caddy.yml.

nginx

server {
    server_name links.example.com;
    location / {
        proxy_pass http://localhost:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

For a complete Docker Compose setup with Nginx, see examples/docker-compose.nginx.yml.

Option 2: Cloudflare Tunnel (no open ports)

No domain purchase or port forwarding needed:

cloudflared tunnel --url http://localhost:3000

For a complete Docker Compose setup with Cloudflare Tunnel, see examples/docker-compose.cloudflare-tunnel.yml.

📸 Screenshots

Click to expand

Public Page Admin Dashboard
Public Page [Aurora Theme] Admin Dashboard
Links Profile
Links Page Profile Page
Theme Live Preview Pane
Theme Page Live Preview Pane
Settings [General] Settings [Appearance]
Settings Page [General Tab] Settings Page [Appearance Tab]
Settings [Security] Settings [Data]
Settings Page [Security Tab] Settings Page [Data Tab]

🆚 Comparison

| Feature | Linktree | LinkStack | LittleLink | Shako | LinkBreeze | |---------|----------|-----------|------------|-------|----------------| | Price | $15/mo | Free | Free | Free | Free | | Admin Panel | ✅ | Slow | ❌ | ❌ | ✅ Fast | | Multi-Page | ✅ (paid) | ❌ | ❌ | ❌ | ✅ | | Auto-Favicon Links | ❌ | ❌ | ❌ | ❌ | ✅ | | Migration Wizard | ❌ | ❌ | ❌ | ❌ | ✅ | | Database | Theirs | MySQL | None | None | SQLite | | Built-in Analytics | Paid | Basic | ❌ | ❌ | ✅ Full | | External Analytics | ✅ | ✅ | ❌ | ❌ | ✅ | | Email Capture | Paid | ❌ | ❌ | ❌ | ✅ | | Embed Widgets | Paid | ❌ | ❌ | ❌ | ✅ | | Link Thumbnails | ✅ | ❌ | ❌ | ❌ | ✅ | | QR Codes | ✅ | ✅ | ❌ | ❌ | ✅ | | Link Scheduling | Paid | ❌ | ❌ | ❌ | ✅ | | Themes | Paid | Limited | CSS only | Config | ✅ Full Token System + Import/Export | | Custom CSS | ❌ | ❌ | ✅ | ❌ | ✅ | | Self-Hosted | ❌ | ✅ | ✅ | ✅ | ✅ | | Language | Closed | PHP | HTML | Astro | TypeScript | | Docker Deploy | N/A | Complex | Simple | Simple | One command | | Page Load | ~2-3s | ~1-2s | Fast | Fast | <300ms | | License | Closed | AGPL | MIT | GPL | MIT |

🛠️ Tech Stack

| Layer | Technology | |-------|-----------| | Framework | Next.js 16 (App Router, Server Components, ISR) | | Database | SQLite via better-sqlite3 (WAL mode) | | ORM | Drizzle ORM (type-safe, zero overhead) | | Auth | Cookie-based HMAC sessions, Argon2id (legacy bcrypt hashes upgrade on login) | | UI | shadcn/ui + Tailwind CSS 4 | | Drag & Drop | dnd-kit | | Charts | Recharts | | QR Codes | qrcode (server-side SVG/PNG) | | Validation | Zod | | Icons | Lucide + custom social SVGs |

📖 Documentation

🛳️ Repositories & Registry

| Where | URL | |---|---| | Source (GitLab, canonical public mirror) | gitlab.com/omnirise00/linkbreeze | | Source (GitHub) | github.com/Manak-hash/LinkBreeze | | Container image | docker.io/omnirise/linkbreeze (Docker Hub) |

All mirrors sync automatically — open issues/PRs on either forge.

⚙️ Configuration

All configuration is via environment variables (.env). .env.example is the canonical reference — copy it (cp .env.example .env) and it documents every variable, including the wallet-credential blocks with their caveats inline:

| Variable | Default | Description | |----------|---------|-------------| | PORT | 3000 | Server port | | DATABASE_PATH | ./data/linkbreeze.db | SQLite database file path | | SECRET_KEY | Auto-generated | HMAC signing key for sessions | | EXTRA_SCRIPT_SRC | _(empty)_ | Space-separated analytics domains for CSP (e.g. plausible.io umami.is) | | GOOGLE_WALLET_ISSUER_ID | _(empty)_ | Enables "Add to Google Wallet" buttons on public pages. Numeric issuer ID from the Google Pay & Wallet Console. | | GOOGLE_WALLET_SERVICE_ACCOUNT_JSON | _(empty)_ | Full service-account JSON (client_email + private_key) authorized for the Wallet API. | | APPLE_WALLET_CERT_PEM | _(empty)_ | Enables "Add to Apple Wallet" buttons. Pass Type ID signing certificate (PEM). | | APPLE_WALLET_KEY_PEM | _(empty)_ | Private key matching the signing certificate (PEM). | | APPLE_WALLET_KEY_PASSPHRASE | _(empty)_ | Passphrase for the signing key, if encrypted. | | APPLE_WALLET_WWDR_PEM | _(empty)_ | Apple WWDR intermediate certificate (PEM). | | APPLE_WALLET_TEAM_ID | _(empty)_ | Your 10-character Apple Team ID. | | APPLE_WALLET_PASS_TYPE_ID | _(empty)_ | Your Pass Type ID (must start with pass.). |

Wallet passes & contact export: every public page renders a share block with a "Save contact" button (universal vCard, always on). When the matching credentials above are configured, "Add to Google Wallet" (free issuer account; passes only save for whitelisted test users until Google grants production access) and "Add to Apple Wallet" (requires a paid Apple Developer account; passes install from Safari only) light up automatically. Passes are static snapshots — the QR on the pass always opens the live page. The Settings → Integration tab shows per-wallet credential status and warns when the Apple signing certificate is about to expire.

Using external analytics (Plausible, Umami, Matomo, Google Analytics):

The built-in analytics covers views, clicks, referrers, and device type with no setup needed. If you want to add a third-party analytics provider, paste your Chat with me