A self-hosted notes application inspired by Google Keep. Create, edit, organize, and collaborate on your notes with an intuitive, feature-rich user interface.
- β Create, edit, and delete notes with confirmation dialogs
- π¨ 12 different colors for your notes
- π Pin/unpin notes for quick access
- π·οΈ Tags/labels for better organization with drag-and-drop support
- π Full-text search in title and content
- π Todo lists/checklists within notes
- π Automatic link preview generation
- π¦ Archive notes (hide without deleting)
- π― Drag and drop to organize and reorder notes
- π₯ Multi-user support with JWT authentication
- π€ Friend system with friend requests
- π Share and collaborate on notes with friends
- ποΈ Visual indicators showing who has access to shared notes
- π Granular sharing permissions
- π Internationalization (English & German)
- π Dark mode with theme persistence
- π€ OLED mode for AMOLED displays
- π± Fully responsive design (works on desktop and mobile)
- π Fast and intuitive interface
- π― Toast notifications for instant feedback
- β¨οΈ Keyboard shortcuts for power users
- π Advanced security (XSS protection, CSRF tokens, CORS, Rate Limiting)
- π¨βπΌ Admin console for user management
- π User registration control (enable/disable)
- π Statistics and usage analytics
- πΎ MongoDB database integration
- π³ Docker & Docker Compose support
- π¦ Unraid ready with templates
- π Easy updates and maintenance
- React 18 with Hooks (useState, useEffect, useContext, etc.)
- React Context API for state management (Auth, Language)
- Axios for HTTP requests
- CSS3 with Grid Layout, Flexbox & CSS Variables for theming
- DOMPurify for XSS protection
- i18n with custom translation system
- Service Worker for offline capability
- Node.js & Express.js
- MongoDB & Mongoose ODM
- JWT (JSON Web Tokens) for authentication
- bcrypt for password hashing
- CSRF protection with csurf
- Helmet for security headers
- Express Rate Limit for DDoS protection
- XSS sanitization
- CORS with origin control
- Session management with express-session
The easiest way to run KeepLocal is using Docker Compose:
- Docker
- Docker Compose
-
Clone the repository
git clone https://github.com/zwaetschge/KeepLocal.git cd KeepLocal -
Start with Docker Compose
docker-compose up -d
-
Access the application
Open your browser and navigate to:
http://localhost:3000
That's it! The application will automatically:
- Set up MongoDB
- Configure the backend server
- Build and serve the frontend
- Handle all networking between services
# Start the application
docker-compose up -d
# Stop the application
docker-compose down
# View logs
docker-compose logs -f
# Restart services
docker-compose restart
# Stop and remove all data (including database)
docker-compose down -v- Install the Docker Compose Manager plugin from Community Applications
- Create a new stack in Docker Compose Manager
- Copy the contents of
docker-compose.ymlfrom this repository - Click "Compose Up"
- Access via
http://[UNRAID-IP]:3000
Choose between installing individual containers or using the compose stack:
Option A: Individual Containers
- Go to Docker tab in Unraid
- Click Add Container
- Under Template repositories, add:
https://github.com/zwaetschge/KeepLocal/tree/main/unraid - Install containers in this order:
- KeepLocal-MongoDB (database)
- KeepLocal-Server (backend API)
- KeepLocal-Client (web interface)
- Configure each container:
- Update IP addresses in environment variables
- Ensure ports don't conflict (27017, 5000, 3000)
- Set MongoDB data path:
/mnt/user/appdata/keeplocal/mongodb
- Click Apply for each container
Option B: Docker Compose Stack
Use the template file at unraid/keeplocal-compose.xml with the Docker Compose Manager plugin.
For detailed instructions, see the Unraid README.
After installation, you may need to update the CORS settings:
- Go to Docker tab
- Click on KeepLocal container
- Edit the ALLOWED_ORIGINS variable
- Add your Unraid server IP:
http://[UNRAID-IP]:3000 - Click Apply
- Node.js (Version 14 or higher)
- npm or yarn
- MongoDB (local or MongoDB Atlas)
-
Clone the repository
git clone https://github.com/zwaetschge/KeepLocal.git cd KeepLocal -
Configure MongoDB
Create a
.envfile in theserver/directory:cd server cp .env.example .envEdit the
.envfile and set your MongoDB URI:PORT=5000 NODE_ENV=development MONGODB_URI=mongodb://localhost:27017/keeplocal ALLOWED_ORIGINS=http://localhost:3000
-
Install and start the server
npm install npm start
The server runs on:
http://localhost:5000 -
Install and start the client (new terminal window)
cd ../client npm install npm startThe app opens automatically at:
http://localhost:3000
- Access the application at
http://localhost:3000 - Create your admin account on the setup page
- Log in with your credentials
- Click on the input field "Take a note..." or click anywhere in the note form
- Add a title (optional)
- Enter your note content or create a todo list
- Add tags (comma-separated) for organization
- Select a color from the palette
- Click "Save" or press
Ctrl+Enter
- Click on any note to open the edit modal
- Edit the title, content, tags, or color
- Switch between regular note and todo list mode
- Click "Save" or press
Ctrl+Enter
- Pin/Unpin: Click the pin icon to keep notes at the top
- Archive: Click the archive icon to hide notes without deleting
- Share: Click the share icon to collaborate with friends
- Delete: Click the trash icon and confirm deletion
- Click the checkbox icon when creating/editing a note
- Add items to your todo list
- Check items off as you complete them
- Press
Enterto add new items - Press
Backspaceon empty items to delete them
- Add Friends: Click "Freunde" (Friends) in the sidebar
- Send Requests: Search for users and send friend requests
- Share Notes: Click the share icon on any note
- Manage Access: Add or remove collaborators
- View Shared Notes: See avatar indicators on shared notes
- Use the search bar at the top for full-text search
- Click on tags in the sidebar to filter by category
- Drag tags onto notes to add them
- Click "Archiviert" to view archived notes
- Click the theme toggle icon
- Cycle through: Light β Dark β OLED β Light
- Your preference is automatically saved
- Click the language selector (π©πͺ/π¬π§)
- Choose between German and English
- All UI text updates instantly
Ctrl+N: Focus on new note inputCtrl+F: Focus on search barCtrl+K: Toggle themeCtrl+Shift+L: LogoutCtrl+Enter: Save note (in modal)Esc: Close modal
- Click on your username (admin only)
- View statistics and user management
- Create new users manually
- Delete users or change admin status
- Enable/disable user registration
POST /api/auth/setup- Initial admin account creationPOST /api/auth/register- Register new user (if enabled)POST /api/auth/login- User login (returns JWT)POST /api/auth/logout- User logoutGET /api/auth/me- Get current user infoGET /api/csrf-token- Get CSRF token
GET /api/notes- Get all notes (own + shared)- Query params:
search,tag,page,limit,archived
- Query params:
GET /api/notes/:id- Get single notePOST /api/notes- Create new notePUT /api/notes/:id- Update noteDELETE /api/notes/:id- Delete notePOST /api/notes/:id/pin- Toggle pin statusPOST /api/notes/:id/archive- Toggle archive statusPOST /api/notes/:id/share- Share note with userDELETE /api/notes/:id/share/:userId- Unshare note
GET /api/friends- Get friends listGET /api/friends/requests- Get pending friend requestsPOST /api/friends/request- Send friend requestPOST /api/friends/accept/:requestId- Accept friend requestPOST /api/friends/reject/:requestId- Reject friend requestDELETE /api/friends/:friendId- Remove friendGET /api/friends/search- Search users
GET /api/admin/stats- Get system statisticsGET /api/admin/users- Get all usersPOST /api/admin/users- Create new userDELETE /api/admin/users/:id- Delete userPOST /api/admin/users/:id/toggle-admin- Toggle admin statusGET /api/admin/settings- Get system settingsPUT /api/admin/settings- Update system settings
GET /api/link-preview- Fetch link preview data- Query param:
url
- Query param:
All endpoints (except auth and setup) require authentication via JWT token.
KeepLocal/
βββ client/ # React Frontend
β βββ public/
β β βββ service-worker.js # PWA Service Worker
β β βββ manifest.json
β βββ src/
β β βββ components/ # React Components
β β β βββ AdminConsole.js # Admin panel
β β β βββ CollaborateModal.js # Note sharing UI
β β β βββ ColorPicker.js # Color selection
β β β βββ ConfirmDialog.js # Confirmation dialogs
β β β βββ FriendsModal.js # Friend management
β β β βββ LanguageSelector.js # i18n switcher
β β β βββ LinkPreview.js # URL preview cards
β β β βββ Login.js # Login form
β β β βββ Logo.js # App logo
β β β βββ Note.js # Individual note card
β β β βββ NoteForm.js # New note input
β β β βββ NoteList.js # Notes grid
β β β βββ NoteModal.js # Note editor modal
β β β βββ Register.js # Registration form
β β β βββ SearchBar.js # Search input
β β β βββ Setup.js # Initial setup
β β β βββ Sidebar.js # Navigation sidebar
β β β βββ ThemeToggle.js # Theme switcher
β β β βββ Toast.js # Notifications
β β βββ contexts/ # React Context
β β β βββ AuthContext.js # Authentication state
β β β βββ LanguageContext.js # i18n state
β β βββ translations/ # i18n files
β β β βββ de.js # German translations
β β β βββ en.js # English translations
β β β βββ index.js
β β βββ utils/ # Utility functions
β β β βββ colorMapper.js # Color theme mapping
β β β βββ sanitize.js # XSS protection
β β βββ services/
β β β βββ api.js # API client
β β βββ App.js
β β βββ App.css
β β βββ index.js
β βββ Dockerfile
β βββ nginx.conf
β βββ package.json
β
βββ server/ # Express Backend
β βββ config/
β β βββ database.js # MongoDB connection
β βββ middleware/
β β βββ auth.js # JWT authentication
β β βββ errorHandler.js # Error handling
β β βββ sanitizeInput.js # Input sanitization
β βββ models/
β β βββ Note.js # Note schema
β β βββ Settings.js # System settings schema
β β βββ User.js # User schema
β βββ routes/
β β βββ admin.js # Admin endpoints
β β βββ auth.js # Authentication
β β βββ friends.js # Friend management
β β βββ linkPreview.js # Link previews
β β βββ notes.js # Note CRUD
β βββ utils/
β β βββ sanitize.js
β βββ Dockerfile
β βββ server.js
β βββ package.json
β
βββ unraid/ # Unraid templates
β βββ keeplocal-compose.xml
β βββ README.md
βββ docker-compose.yml # Docker Compose config
βββ .env.example # Environment template
βββ .gitignore
βββ README.md
cd server
npm run devUses nodemon for automatic reloading on changes.
cd client
npm run buildCreates an optimized production build in the client/build/ directory.
KeepLocal implements multiple security layers:
- Authentication: JWT-based authentication with secure token storage
- Password Security: bcrypt hashing with salt rounds
- CSRF Protection: csurf middleware with token validation
- XSS Protection: Input sanitization on server and client (DOMPurify)
- CORS Control: Configurable allowed origins
- Rate Limiting: Protection against brute-force attacks (100 requests/15min)
- Security Headers: Helmet.js for additional HTTP header security
- Input Validation: Mongoose schema validation on all inputs
- Payload Limits: Request size restrictions
- Session Security: Secure session management with express-session
- SQL Injection: Protected via Mongoose ODM parameterized queries
| Variable | Description | Default |
|---|---|---|
PORT |
Server port | 5000 |
NODE_ENV |
Environment mode | development |
MONGODB_URI |
MongoDB connection string | mongodb://localhost:27017/keeplocal |
ALLOWED_ORIGINS |
Comma-separated CORS origins | http://localhost:3000 |
SESSION_SECRET |
Session encryption key | Random string |
JWT_SECRET |
JWT token signing key | Auto-generated |
CSRF_SECRET |
CSRF token secret | Auto-generated |
- Notes are stored persistently in MongoDB
- Ensure MongoDB is running before starting the server
- The
.envfile contains sensitive configuration and should not be committed - For Docker deployments, MongoDB is automatically configured
- All data is stored in Docker volumes for persistence
Port already in use:
# Change the port in docker-compose.yml
ports:
- "8080:80" # Use port 8080 instead of 3000Cannot connect to MongoDB:
# Check if MongoDB container is running
docker-compose ps
# View MongoDB logs
docker-compose logs mongodbReset everything:
# Stop and remove all containers and volumes
docker-compose down -v
# Start fresh
docker-compose up -dCannot access WebUI:
- Check if the container is running
- Verify port mapping in container settings
- Update ALLOWED_ORIGINS with your Unraid IP
- Check firewall settings
Database not persisting:
- Ensure the appdata path is correctly configured
- Check permissions on
/mnt/user/appdata/keeplocal/
- πΌοΈ Image and file attachments in notes
- π Real-time synchronization with WebSockets
- π€ Export/Import functionality (JSON, Markdown, PDF)
- π± Progressive Web App (PWA) improvements
- π Reminders & notifications
- π§ Email notifications for shared notes
- π Advanced search filters (by date, color, collaborator)
- π·οΈ Nested tags/folders
- π Note statistics and analytics
- π¨ Custom color themes
- π Additional languages
- π Browser extensions (Chrome, Firefox)
- π± Native mobile apps (iOS/Android)
- π Two-factor authentication (2FA)
- π¬ Comments on shared notes
- π Rich text editor with formatting
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
MIT License
Created with β€οΈ and Claude Code
- Inspired by Google Keep
- Built with React and Express
- MongoDB for data persistence
- Docker for easy deployment