Skip to main content

Self-Host Linkding: Open Source Bookmark Manager 2026

·OSSAlt Team
linkdingbookmarksself-hostingdockerproductivity2026

TL;DR

Linkding (MIT, ~6K GitHub stars, Python/Django) is a minimal self-hosted bookmark manager — fast, lightweight, and focused. Save URLs with tags, search instantly, import from browser exports or Pocket/Pinboard, and access a clean REST API. Pinboard charges $22/year; Raindrop.io charges $3/month for Pro. Linkding runs on a $5 VPS with under 50MB RAM and has no subscription.

Key Takeaways

  • Linkding: MIT, ~6K stars, Python/Django — bookmark manager with tags, search, and sharing
  • Browser extensions: Chrome and Firefox — save the current page with one click
  • REST API: Full CRUD API with token auth — automate bookmark collection
  • Import/export: Netscape HTML format (all browsers), Pocket, Pinboard CSV
  • Shared bookmarks: Optional public bookmark pages per user
  • Minimal footprint: ~50MB RAM, SQLite by default — runs on the smallest VPS

Linkding vs Raindrop.io vs Hoarder

FeatureLinkdingRaindrop.ioHoarder
PriceFree (self-host)$3/mo ProFree (self-host)
AI taggingNoYesYes (Ollama)
Full-page archiveNoYes (Pro)Yes
ScreenshotNoYes (Pro)Yes
Collections/foldersTags onlyYesLists
Mobile appPWANativeNative
REST APIYesYesYes
SpeedVery fastFastModerate

Part 1: Docker Setup

# docker-compose.yml
services:
  linkding:
    image: sissbruecker/linkding:latest
    container_name: linkding
    restart: unless-stopped
    ports:
      - "9090:9090"
    volumes:
      - linkding_data:/etc/linkding/data
    environment:
      # Create the first superuser automatically:
      LD_SUPERUSER_NAME: admin
      LD_SUPERUSER_PASSWORD: "${ADMIN_PASSWORD}"

      # Optional: disable public registration
      LD_DISABLE_BACKGROUND_TASKS: "False"

      # Optional: serve under a subpath (e.g. /bookmarks)
      # LD_CONTEXT_PATH: bookmarks/

      # Optional: enable CSRF trusted origins for reverse proxy:
      LD_CSRF_TRUSTED_ORIGINS: "https://links.yourdomain.com"

volumes:
  linkding_data:
docker compose up -d

Visit http://your-server:9090 → log in with your admin credentials.


Part 2: HTTPS with Caddy

links.yourdomain.com {
    reverse_proxy localhost:9090
}

Part 3: Browser Extensions

Chrome / Chromium

  1. Install Linkding Extension
  2. Extension → Options:
    • Base URL: https://links.yourdomain.com
    • API token: copy from Settings → Integrations → REST API
  3. Click extension icon on any page → opens bookmark dialog
  4. Add tags → Save

Firefox

  1. Install from Mozilla Add-ons: search "Linkding"
  2. Same configuration

Keyboard shortcut

Both extensions support a configurable keyboard shortcut for fast saving without taking your hands off the keyboard.


Part 4: REST API

Get your API token

Settings → Integrations → REST API → Generate token

API examples

TOKEN="your-api-token"
BASE="https://links.yourdomain.com"

# List bookmarks:
curl "$BASE/api/bookmarks/" \
  -H "Authorization: Token $TOKEN" | jq '.results[].url'

# Add a bookmark:
curl -X POST "$BASE/api/bookmarks/" \
  -H "Authorization: Token $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/article",
    "title": "Article Title",
    "description": "Notes about this link",
    "tag_names": ["tech", "read-later"],
    "is_archived": false
  }'

# Search bookmarks:
curl "$BASE/api/bookmarks/?q=kubernetes" \
  -H "Authorization: Token $TOKEN" | jq '.results[].title'

# Archive a bookmark (move to archive):
curl -X POST "$BASE/api/bookmarks/42/archive/" \
  -H "Authorization: Token $TOKEN"

# Delete a bookmark:
curl -X DELETE "$BASE/api/bookmarks/42/" \
  -H "Authorization: Token $TOKEN"

# List tags:
curl "$BASE/api/tags/" \
  -H "Authorization: Token $TOKEN" | jq '.results[].name'

Part 5: Import and Export

Import from browser

  1. Export bookmarks from Chrome/Firefox (Bookmarks Manager → Export) → bookmarks.html
  2. Linkding → Settings → Import
  3. Select file → Import

All bookmark folders become tags.

Import from Pocket

  1. Pocket → Exportril_export.html
  2. Linkding → Settings → Import → select Pocket file
  3. Pocket tags are preserved

Import from Pinboard

# Download Pinboard JSON export, convert to Netscape HTML format:
# Linkding accepts Netscape HTML format directly

# Or use the CLI tool:
pip install linkding-cli
linkding import --token $TOKEN --file pinboard_export.html

Export

# Export all bookmarks as Netscape HTML (importable to any browser):
curl "$BASE/api/bookmarks/?limit=9999&format=html" \
  -H "Authorization: Token $TOKEN" \
  -o bookmarks-export.html

Search syntax

Linkding supports full-text search across URL, title, description, and tags:

# Search by keyword:
kubernetes

# Search by tag:
#docker

# Search by URL domain:
github.com

# Combined:
kubernetes #docker github.com

# Untagged bookmarks:
!untagged

# Archived bookmarks:
Go to the Archive tab

Tag strategy

Good tagging makes bookmarks actually useful:

Content type:  #article #video #tool #paper #repo #doc
Topic:         #docker #kubernetes #rust #python #sre
Status:        #read-later #reading #reference #done
Project:       #ossalt #work #personal

Part 7: Sharing and Multiple Users

Public bookmarks

Users can mark individual bookmarks as public — visible at:

https://links.yourdomain.com/public?user=admin

Enable public sharing per user: Settings → General → Enable public bookmarks

Multiple users

Add additional users via the admin panel:

# Create a new user via Django CLI:
docker exec -it linkding python manage.py createsuperuser

# Or create a regular user:
docker exec -it linkding python manage.py shell -c "
from django.contrib.auth.models import User
User.objects.create_user('alice', 'alice@example.com', 'password123')
"

Part 8: Automation

Save bookmarks from command line

# Quick save function (add to ~/.bashrc or ~/.zshrc):
bm() {
  curl -s -X POST "https://links.yourdomain.com/api/bookmarks/" \
    -H "Authorization: Token $TOKEN" \
    -H "Content-Type: application/json" \
    -d "{\"url\": \"$1\", \"tag_names\": [\"cli\"]}"
  echo "Saved: $1"
}

# Usage:
bm "https://example.com/article"

Save from iOS Shortcuts

  1. Shortcuts → New Shortcut → Get contents of URL
  2. URL: https://links.yourdomain.com/api/bookmarks/
  3. Method: POST
  4. Headers: Authorization: Token $TOKEN
  5. Body: {"url": "Shortcut Input", "tag_names": ["ios"]}
  6. Add to Share Sheet → save any URL from Safari

ntfy notification on save

# Webhook approach: Linkding doesn't have webhooks natively,
# but you can poll the API and notify on new bookmarks:

# Run daily to check for unread bookmarks:
COUNT=$(curl -s "$BASE/api/bookmarks/?is_archived=false" \
  -H "Authorization: Token $TOKEN" | jq '.count')

curl -d "You have $COUNT unread bookmarks" \
  https://ntfy.yourdomain.com/bookmarks

Maintenance

# Update Linkding:
docker compose pull
docker compose up -d

# Backup (SQLite):
docker cp linkding:/etc/linkding/data/db.sqlite3 \
  ./linkding-backup-$(date +%Y%m%d).db

# Or backup the full data directory:
tar -czf linkding-data-$(date +%Y%m%d).tar.gz \
  $(docker volume inspect linkding_linkding_data --format '{{.Mountpoint}}')

# Check health:
curl https://links.yourdomain.com/health

# Logs:
docker compose logs -f linkding

See also: Hoarder — AI-powered alternative with automatic tagging and full-page archiving

See all open source productivity tools at OSSAlt.com/categories/productivity.

Comments