Your personal, self-hosted, AI-powered notes & tasks app — mobile-first, beautifully simple.
Snipsel is an open-source PWA for capturing ideas, notes, tasks, bookmarks, and media — all in one place. Enhanced with a user-configurable AI assistant, it helps you manage your knowledge without cloud lock-in. Runs on your own server in minutes.
Most note apps are either too simple (just plain text) or too heavy (Notion, Obsidian). Snipsel hits the sweet spot: structured collections, multiple content types, sharing, and reminders — all powered by a local-first architecture and real-time synchronization. It feels as lightweight and instant as a sticky note, but scales with your knowledge.
Organize everything in collections — from grocery lists to project notes. Each item inside is a snipsel, which can be one of six types:
- 📝 Text — plain notes with Markdown support
- ✅ Task — checkable to-dos with done tracking
- 🔗 External link — save URLs with labels
- 📎 Internal link — reference another snipsel
- 🖼️ Image — attach and view photos
- 📁 File attachment — store any file
Snipsel is built for speed and reliability:
- Real-time Engine — Powered by Server-Sent Events (SSE), changes sync instantly across all your devices and browser tabs.
- Local-first Architecture — Uses optimistic mutations and stale-while-revalidate patterns to ensure the UI is always responsive.
- Full Offline Mode — Optionally sync your entire library to local storage (IndexedDB) for seamless access without an internet connection.
Smart Selection Features:
- Multi-Select — Click the selection bar on the right to select multiple snipsels
- Range Selection — Hold Shift (desktop) or long-press (mobile) to select all snipsels between two items
- Auto-Select Children — Selecting a parent snipsel with collapsed children automatically selects all nested items
- Bulk Sharing — Quickly copy the content of all selected snipsels to your clipboard with one click
- Keyboard Shortcuts — Extensive keyboard shortcuts for navigation, editing, and bulk operations (see User Documentation)
Process your notes with a built-in AI assistant. Configure your own OpenAI-compatible endpoint (OpenAI, Groq, Ollama) and use it to summarize, translate, or transform snipsels with custom prompts.
- Cross-device Sync — Your prompt history and custom snippets are synchronized to your account.
- Vision Support — Use vision models for image analysis and text extraction from attachments.
A built-in daily collection auto-created for each day. Open tasks from the past 30 days are automatically carried over so nothing falls through the cracks.
- OIDC — Single Sign-On via your identity provider (Google, Microsoft, Authentik, etc.)
- Passkeys (WebAuthn / FIDO2) — log in with Face ID, Touch ID, or a hardware key
- TOTP 2FA — standard authenticator app support
- Passcode lock — protect individual collections with a PIN
- Password reset via email
- Registration toggle — disable new user registration via environment variable
- Admin User Management — admins can create, delete and manage users with role assignments
- Dynamic Accent Colors — System-wide accent colors that adapt to your preferences and per-collection settings.
- Theming — Light, dark, or system-adaptive theme with premium aesthetics.
- Visuals — Custom cover images for collections and sleek micro-animations.
- PWA — Installable on any device for a native-like experience.
Capture and view snipsels with geographic coordinates. See your notes on an interactive map, filter by location, and track where your ideas were born.
Snipsel is optimized for performance. With database indexing and smart result limiting, the UI remains snappy even when managing thousands of snipsels and collections.
Coming from Twos? Snipsel can import all your lists, tasks, photos, and reminders with a single click — including recurrence rules.
docker run -d \
--name snipsel \
-p 5000:5000 \
-v ./data:/app/data \
-v ./uploads:/app/uploads \
-e SNIPSEL_SECRET_KEY="your-secure-secret-key" \
-e SNIPSEL_DOMAIN="yourdomain.com" \
-e SNIPSEL_FRONTEND_URL="https://yourdomain.com" \
-e SNIPSEL_REGISTRATION_ENABLED=1 \
ghcr.io/mcfetz/snipsel:latestThat's it. Snipsel runs as a single container — no separate database server, no Redis, no complex setup.
Or with Docker Compose:
# Build the image
docker build -t snipsel .
# Run with compose
docker compose up -dNote:
SNIPSEL_DOMAINandSNIPSEL_FRONTEND_URLare required for Passkey authentication to work correctly.
- FFmpeg: Required for generating video thumbnails. Install it via your package manager (e.g.,
brew install ffmpegon macOS orsudo apt install ffmpegon Linux).
cd backend
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
pip install -e .
export SNIPSEL_SECRET_KEY="dev"
flask --app snipsel_api.app run --debug --port 5000
# Run database migrations
flask --app snipsel_api.app db upgradecd frontend
npm install
npm run devThe frontend proxies /api/* to the backend in dev mode.
| Variable | Default | Description |
|---|---|---|
SNIPSEL_SECRET_KEY |
dev |
Session secret — change in production! |
SNIPSEL_DATABASE_URL |
sqlite:///snipsel.db |
Database URL |
SNIPSEL_UPLOAD_DIR |
./uploads |
Directory for uploaded files |
SNIPSEL_MAX_UPLOAD_BYTES |
10485760 |
Max upload size (10 MB) |
SNIPSEL_DOMAIN |
localhost |
Domain for Passkey auth |
SNIPSEL_FRONTEND_URL |
http://localhost:5173 |
Frontend URL for CORS & Passkeys |
SNIPSEL_REGISTRATION_ENABLED |
1 |
Set to 0 to disable new user registration |
Optional SMTP (password reset):
| Variable | Description |
|---|---|
SNIPSEL_SMTP_HOST |
SMTP server host |
SNIPSEL_SMTP_PORT |
SMTP port (default: 587) |
SNIPSEL_SMTP_USERNAME |
SMTP username |
SNIPSEL_SMTP_PASSWORD |
SMTP password |
SNIPSEL_SMTP_USE_TLS |
Enable TLS (default: 1) |
SNIPSEL_MAIL_FROM |
Sender address |
SNIPSEL_PUBLIC_BASE_URL |
If set, emails include a reset link |
Optional VAPID (push notifications):
| Variable | Description |
|---|---|
VAPID_PUBLIC_KEY |
VAPID public key |
VAPID_PRIVATE_KEY |
VAPID private key |
VAPID_SUBJECT |
e.g. mailto:admin@yourdomain.com |
Optional OIDC (Single Sign-On):
| Variable | Default | Description |
|---|---|---|
SNIPSEL_OIDC_ENABLED |
0 |
Set to 1 to enable OIDC authentication |
SNIPSEL_OIDC_DISCOVERY_URL |
- | OIDC discovery URL (e.g., https://accounts.google.com/.well-known/openid-configuration) |
SNIPSEL_OIDC_CLIENT_ID |
- | OIDC client ID |
SNIPSEL_OIDC_CLIENT_SECRET |
- | OIDC client secret |
SNIPSEL_OIDC_SCOPE |
openid email profile |
OIDC scopes to request |
SNIPSEL_OIDC_PROVIDER_NAME |
OIDC |
Display name for the login button |
SNIPSEL_OIDC_DISABLE_PASSWORD_LOGIN |
0 |
Set to 1 to disable password login when OIDC is enabled |
- Backend: Python · Flask · SQLAlchemy · SQLite · Flask-Migrate
- Frontend: Svelte 5 · TypeScript · Vite · PWA (Service Worker)
- Auth: Session cookies · WebAuthn (Passkeys) · TOTP · OIDC · bcrypt
- Deployment: Docker (multi-stage build) · single container (includes FFmpeg)
MIT














