Fork of Glass Keep, with a strong focus on local-first usage, offline support, Trash / restore, mobile usability, simpler self-hosting, and a native Android companion app.
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Compared to the original project, this fork puts more emphasis on:
- 🔄 local-first usage and offline support
- 🗑️ safer note deletion with Trash / restore
- 📱 better mobile usability
- ✏️ a real WYSIWYG / live-formatting editor for text notes
- 🪟 side-by-side note reading and comparison
- 🤖 a native Android companion app
- 📺 an Android TV layout designed for couch use and remote control
- 🌍 a cleaner and more extensible i18n foundation
- 🛠️ simpler self-hosting
- ✨ a broad polish / stability pass
- 🎨 a deeper overhaul of the drawing mode
- 💬 configurable AI assistant with local or remote endpoints
- 🔐 Server-side encryption & passkeys
- 🔔 In-app update notifications
- 🚀 one-click in-app update from the admin panel — live progress, cancel/rollback, AI-translatable changelog after install
- 🎙️ audio notes
- 🖼️ refreshed logo and icons across the web app, PWA, favicon, and Android launcher / TV banner
For a more complete and structured overview of the changes made since the fork, see:
This fork also keeps the main capabilities that already made the original project attractive:
- 🔐 authentication and multi-user support
- 👑 admin panel
- 🗝️ secret recovery key login
- 📝 Markdown notes, checklists, drawings, and images
- 👥 real-time collaboration on notes
- 📦 import / export with cross-device duplicate detection
- 📥 Google Keep import (Takeout
.zip— full colour, images, line breaks) - 🤖 optional AI assistant via any OpenAI-compatible endpoint (Ollama, Open WebUI, LiteLLM, OpenAI, …)
- 📲 PWA support
A native Android companion app is available for GlassKeep, making self-hosted mobile usage more convenient.
The Android app is a WebView wrapper for GlassKeep Enhanced and does not necessarily change with every project release.
The same APK also runs on Android TV — the app detects leanback hardware (or the ?tv=1 URL override) and switches the React frontend to a dedicated TV layout designed for the couch and the D-pad. No separate build, no separate install: phone, tablet and TV all share one codebase. See section 4 of IMPROVEMENTS.md for the full TV layout details.
The launcher icon, the Android TV banner, the PWA install icon, and the favicon have all been redrawn from a single master so the app looks coherent across every surface.
Current APK version: 1.3.0
The Android source code is available in the
android/directory.
From APK 1.3.0 onward, the Android app supports passkeys natively (fingerprint, face unlock, hardware security keys, password managers — the same authenticators you'd use from your browser). It works out-of-the-box with the official APK on a regular HTTPS install.
📖 Full setup guide, prerequisites, custom-build instructions and troubleshooting: see
PASSKEYS.md. Worth a read even for the smooth path — the non-standard-port and reverse-proxy edge cases trip a lot of self-hosted setups.
Run as root on a clean Debian-based system:
curl -fsSL https://raw.githubusercontent.com/Victor-root/glasskeep-enhanced/main/install.sh | sudo bashThe script is designed to make installation as simple as possible:
- it directly offers install / update / uninstall
- it asks for the important information up front
- it creates the admin account
- it generates the configuration automatically
- it sets up the systemd service
- it can handle HTTPS depending on your setup:
- reverse proxy
- self-signed certificate
- custom SSL certificate
- it optionally sets up at-rest encryption to protect notes in the database (you can enable it later from the admin panel if you prefer)
This is the main installation method recommended for this fork.
Docker is also available, especially for NAS and similar environments. The same docker-compose.yml works whether you deploy from a terminal or from a graphical interface — pick the one that matches your setup.
services:
glasskeep:
image: ghcr.io/victor-root/glasskeep-enhanced:latest
container_name: glasskeep
restart: unless-stopped
ports:
- "8080:8080"
environment:
ADMIN_EMAIL: "your-admin-username"
ADMIN_PASSWORD: "choose-a-strong-password"
volumes:
- ./data:/data
# Lets the admin panel update the container in one click.
- /var/run/docker.sock:/var/run/docker.sockOnce the container is up, open http://<your-host>:8080 and sign in with the admin username and password you chose.
🖥️ Command line (Linux / macOS / WSL)
Edit the ADMIN_EMAIL and ADMIN_PASSWORD values below, then paste the whole block into your terminal — it creates the folder, writes the compose file and starts the container in one go.
mkdir -p ~/glasskeep && cd ~/glasskeep && cat > docker-compose.yml <<'EOF'
services:
glasskeep:
image: ghcr.io/victor-root/glasskeep-enhanced:latest
container_name: glasskeep
restart: unless-stopped
ports:
- "8080:8080"
environment:
ADMIN_EMAIL: "your-admin-username"
ADMIN_PASSWORD: "choose-a-strong-password"
volumes:
- ./data:/data
# Lets the admin panel update the container in one click.
- /var/run/docker.sock:/var/run/docker.sock
EOF
docker compose up -d🐳 Don't have Docker yet?
- Linux — one-liner that works on Debian / Ubuntu / Fedora / Arch / …:
curl -fsSL https://get.docker.com | sudo sh- macOS / Windows — install Docker Desktop and make sure it's running before continuing.
🐙 Portainer
- Open Portainer → select your environment → Stacks → Add stack
- Give it a name (e.g.
glasskeep) - Choose Web editor and paste the compose file above
- Edit the
ADMIN_EMAIL/ADMIN_PASSWORDvalues - Click Deploy the stack
The container appears in the Containers tab once it's pulled and started.
📦 Synology (Container Manager / DSM 7.2+)
- Open Container Manager → Project → Create
- Set Project name to
glasskeepand Path to a folder of your choice (e.g./docker/glasskeep) - Source → Create docker-compose.yml and paste the compose file above
- Edit the
ADMIN_EMAIL/ADMIN_PASSWORDvalues - Click Next → Done
The Docker socket volume works out of the box on DSM, so the in-app "Update now" button will work without extra setup.
🟧 Unraid
The simplest route is the Compose Manager plugin (Community Apps):
- Install Compose Manager from Community Apps if you don't have it
- Go to the Docker tab → Add New Stack → name it
glasskeep - Click the gear → Edit Stack → Compose and paste the compose file above
- Adjust the
ADMIN_*values, click Save - Click Compose Up
You can also use the native Add Container form, but the compose route preserves the Docker-socket mount for one-click updates.
🏠 CasaOS
- Click the ➕ icon on the dashboard → Install a customized app → Import
- Paste the compose file above
- Edit the
ADMIN_EMAIL/ADMIN_PASSWORDvalues - Click Install
The app shows up on the dashboard with a launcher tile pointing to port 8080.
🛟 TrueNAS SCALE
TrueNAS SCALE doesn't ship a generic compose UI, so the simplest route is the built-in shell:
- Open System Settings → Shell
- Create a folder for the stack:
mkdir -p /mnt/<your-pool>/glasskeep && cd $_ - Paste the compose file above into
docker-compose.yml - Run
docker compose up -d
The easiest way is to open the admin panel and click "Update now" — the new image is pulled and the container is replaced automatically. Your data is preserved.
If you prefer the command line:
cd ~/glasskeep && docker compose pull && docker compose up -d💡 Existing install without one-click updates? You have two options:
- Patch the existing compose — add
- /var/run/docker.sock:/var/run/docker.sockunder thevolumes:block of your currentdocker-compose.yml, then re-deploy the stack once.- Redeploy from the current example — replace your
docker-compose.ymlwith the one at the top of this section (keep yourADMIN_*values and your./datavolume), then re-deploy. The current example already ships the right configuration, so you'll never have to touch the file again.Either way, the in-app Update now button takes over from there.
GlassKeep no longer ships an embedded local model — it was too small to be genuinely useful. Instead, it connects to any OpenAI-compatible chat endpoint, so each instance picks what fits its hardware, privacy needs and budget — fully local with Ollama / Open WebUI, or remote via OpenAI, OpenRouter, …
Two AI features are available once configured:
- 🔎 Global AI search — ask questions across your notes from the search bar. The backend pre-selects relevant notes before calling the model, and only cites notes it actually received (no fabricated sources).
- 🗒️ Per-note assistant — discuss the currently opened note with the AI. Conversations are temporary by default; a save button can keep them per note.
Admins control AI at the instance level: disable it entirely, configure a server-side provider (optionally shared with users so the API key stays hidden), or let each user bring their own endpoint in their settings.
⚠️ Notes sent to a remote provider leave your GlassKeep instance. For sensitive data, prefer a local setup such as Ollama + Open WebUI on your LAN/LXC.
Recommended starter model (light enough to run even on CPU-only setups):
ollama pull qwen3:4b-instruct-2507-q4_K_M📘 Full setup guide — base-URL gotchas, model recommendations, privacy notes, admin/user config flows →
AI_CHANGES.md
- Copy
src/i18n/locales/en.jsto a new file, e.g.src/i18n/locales/it.js, and translate all values - In
src/i18n/index.js:- import the new locale:
import { it } from "./locales/it"; - add the language code to
SUPPORTED_LANGUAGES:export const SUPPORTED_LANGUAGES = ["fr", "en", "it"]; - add the native display name to
LANGUAGE_NATIVE_LABELS:it: "Italiano" - extend the dict selector:
const dict = locale === "fr" ? fr : locale === "it" ? it : en;
- import the new locale:
- In
server/index.js, add the new code to the validation allowlist inPATCH /api/user/profile(the line that checkslang !== "fr" && lang !== "en") - Rebuild the app:
npm run build
The language selector in the settings panel will automatically show the new option. Missing keys fall back to English automatically.
- More translations with better RTL language support
- Make the Android app available on F-Droid
- (open — suggestions welcome)
JWT_SECRETis automatically generated by the native install script- if you run the server outside the script, you must provide your own valid secret
- serving the app behind HTTPS is still recommended
- the recovery secret key should be treated like a password
This repository is first and foremost a fork built on a foundation I genuinely liked.
I originally started looking for a self-hosted and open-source alternative to Google Keep. I found Glass Keep, liked its direction, its interface, and especially the potential of its foundation. This fork started very modestly, with the idea of adding a French translation, and gradually evolved into a broader set of improvements.
The goal here is not to replace the original project, nor to move “against” it.
On the contrary, the reason this fork grew so much is precisely because the foundation of Glass Keep made me want to spend a lot of time improving it.
Thanks to nikunjsingh93 for the original project and its foundation.
Thanks to @Rikhtar for active testing, bug reports, UX feedback.
MIT — based on Glass Keep by nikunjsingh93
















