A minimalist, self-hosted bookmarking service designed to be your default new tab page. Built with SvelteKit 5, QuickMark provides a fast, privacy-focused way to save and organize your bookmarks.
- 🚀 Fast & Lightweight: Single-page application optimized for speed
- 🔒 Privacy-First: Self-hosted, no tracking, no external dependencies
- 📝 Auto Metadata: Automatically extracts titles, descriptions, and favicons
- 🏷️ Tag Support: Organize bookmarks with comma-separated tags
- 🔍 Instant Search: Real-time filtering across all bookmark metadata
- ⌨️ Keyboard Shortcuts: Navigate and manage bookmarks without touching your mouse
- 🎨 Multiple Views: Choose between compact list, card, or dense layouts
- 🌓 Dark Mode: Built-in theme support with system preference detection
- 📤 Export: Download your bookmarks as JSON or HTML (Netscape format)
- 💾 Data Persistence: SQLite database with local asset storage
- Create a
docker-compose.ymlfile:
services:
quickmark:
image: ghcr.io/drkpxl/quickmark:latest
container_name: quickmark
restart: unless-stopped
ports:
- "9022:9022"
volumes:
- ./data:/app/data
environment:
- NODE_ENV=production
- PORT=9022
- HOST=0.0.0.0- Start the service:
docker-compose up -d- Access QuickMark at
http://localhost:9022
docker run -d \
--name quickmark \
-p 9022:9022 \
-v ./data:/app/data \
-e NODE_ENV=production \
ghcr.io/drkpxl/quickmark:latestTo use a different port (e.g., 8080):
ports:
- "8080:9022"
environment:
- PORT=9022 # Keep internal port at 9022- Node.js 22 (LTS)
- npm or pnpm
- Clone the repository:
git clone https://github.com/drkpxl/quickmark.git
cd quickmark- Install dependencies:
npm install- Start the development server:
npm run dev- Open
http://localhost:9022
npm run build
npm run preview| Shortcut | Action |
|---|---|
Ctrl+Enter |
Save bookmark (when URL field is focused) |
/ or Ctrl+F |
Focus search input |
j or ↓ |
Navigate to next bookmark |
k or ↑ |
Navigate to previous bookmark |
Enter |
Open selected bookmark in new tab |
d |
Delete selected bookmark (with confirmation) |
Esc |
Clear search or close modal |
? |
Show keyboard shortcuts help |
- 📋 Compact List (default): Single line per bookmark with all metadata visible
- 🖼️ Card View: Responsive grid layout with Open Graph images
- 📝 Dense View: Minimal list showing only favicons and titles
Tags help organize your bookmarks:
- Add tags when saving a bookmark (comma-separated:
dev, javascript, tutorial) - Click any tag to filter bookmarks by that tag
- Multiple tags can be selected simultaneously (AND filtering)
- Click "Clear" to reset filters
Your bookmarks database and assets are stored in the ./data directory:
data/
├── bookmarks.db # SQLite database
└── assets/ # Favicons and images
Simply copy the entire data/ directory to create a backup:
# Stop the container first
docker-compose down
# Backup
cp -r data data-backup-$(date +%Y%m%d)
# Restart
docker-compose up -ddocker-compose down
rm -rf data
cp -r data-backup-20251017 data
docker-compose up -dUse the built-in export functionality:
- JSON Export: Complete bookmark data with all metadata
- HTML Export: Standard Netscape bookmarks format (compatible with all browsers)
- Frontend: SvelteKit 5 with Svelte 5 runes
- Styling: Bootstrap 5.3.3
- Database: SQLite via better-sqlite3
- Metadata Extraction: jsdom for HTML parsing
- Runtime: Node.js 22 (Alpine Linux in Docker)
src/
├── routes/
│ ├── +layout.svelte # App layout with theme toggle
│ ├── +page.svelte # Main bookmarks page
│ ├── +page.server.ts # SSR data loading
│ ├── api/
│ │ ├── bookmark/+server.ts # POST: Save bookmark
│ │ ├── bookmark/[id]/+server.ts # DELETE: Remove bookmark
│ │ └── export/+server.ts # GET: Export bookmarks
│ └── assets/[...path]/+server.ts # Serve local assets
└── lib/
└── server/
├── db.ts # SQLite operations
└── metadata.ts # Metadata extraction logic
| Variable | Default | Description |
|---|---|---|
NODE_ENV |
production |
Node environment |
PORT |
9022 |
Port to listen on |
HOST |
0.0.0.0 |
Host to bind to |
| Method | Endpoint | Description |
|---|---|---|
GET |
/ |
Main application page |
POST |
/api/bookmark |
Save new bookmark with metadata |
DELETE |
/api/bookmark/:id |
Delete specific bookmark |
GET |
/api/export?format=json|html |
Export bookmarks |
GET |
/assets/:path |
Serve locally stored assets |
- Uptime monitoring, see if a link is dead and update that its a deadlink
- Archive.org intergration.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Built with SvelteKit
- Styled with Bootstrap
- Icons from Bootstrap Icons
If you encounter any issues or have questions, please open an issue on GitHub.