Self-Host Linkding: Open Source Bookmark Manager 2026
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
| Feature | Linkding | Raindrop.io | Hoarder |
|---|---|---|---|
| Price | Free (self-host) | $3/mo Pro | Free (self-host) |
| AI tagging | No | Yes | Yes (Ollama) |
| Full-page archive | No | Yes (Pro) | Yes |
| Screenshot | No | Yes (Pro) | Yes |
| Collections/folders | Tags only | Yes | Lists |
| Mobile app | PWA | Native | Native |
| REST API | Yes | Yes | Yes |
| Speed | Very fast | Fast | Moderate |
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
- Install Linkding Extension
- Extension → Options:
- Base URL:
https://links.yourdomain.com - API token: copy from Settings → Integrations → REST API
- Base URL:
- Click extension icon on any page → opens bookmark dialog
- Add tags → Save
Firefox
- Install from Mozilla Add-ons: search "Linkding"
- 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
- Export bookmarks from Chrome/Firefox (Bookmarks Manager → Export) →
bookmarks.html - Linkding → Settings → Import
- Select file → Import
All bookmark folders become tags.
Import from Pocket
- Pocket → Export →
ril_export.html - Linkding → Settings → Import → select Pocket file
- 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
Part 6: Tagging and Search
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
- Shortcuts → New Shortcut → Get contents of URL
- URL:
https://links.yourdomain.com/api/bookmarks/ - Method: POST
- Headers:
Authorization: Token $TOKEN - Body:
{"url": "Shortcut Input", "tag_names": ["ios"]} - 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.