Open-source Evernote alternative with powerful features for notes and todos management.
- π Notes Management - Create, edit, organize notes with Markdown support
- β Todo Management - Task tracking with priorities, due dates, reminders
- π Folder Organization - Hierarchical folder/subfolder structure
- π Full-text Search - Quick search across all notes and todos
- π Calendar View - Visual calendar for tasks with due dates
- π Analytics - Statistics and insights
- β Favorites - Mark important items
- π¦ Archive - Archive completed items
- ποΈ Trash - Soft delete with recovery
- π Encryption - Encrypt sensitive notes
- π Attachments - File attachments for notes and todos
- π Backup & Restore - Automatic backups with configurable retention
- π Reminders - Email/Telegram/DingTalk notifications
- π₯ Sharing - Share notes and todos with other users
- π Dark Mode - Theme switching
- β¨οΈ Keyboard Shortcuts - Customizable hotkeys
- π± Responsive Design - Works on desktop and mobile
- Java 25
- Spring Boot 4.1
- MyBatis
- SQLite (default) / PostgreSQL
- Maven
- React 18
- TypeScript
- Tailwind CSS
- Vite
- Java 25+
- Node.js 18+
- Maven 3.6+
Edit note-keeper-service/src/main/resources/application.yml:
app:
storage:
base-dir: ${user.dir}/../var
attachments-dir: ${app.storage.base-dir}/attachments
backups-dir: ${app.storage.base-dir}/backups
data-dir: ${app.storage.base-dir}/data
db-path: ${app.storage.data-dir}/notekeeper.dbDirectory structure:
var/
βββ data/ # SQLite database
βββ attachments/ # Uploaded files
βββ backups/ # Backup archives
SQLite (default):
spring:
datasource:
url: jdbc:sqlite:${app.storage.db-path}PostgreSQL:
spring:
profiles:
active: postgresql
datasource:
url: jdbc:postgresql://localhost:5432/notekeeper
username: your_username
password: your_passwordRun schema migration:
psql -U your_username -d notekeeper -f note-keeper-service/src/main/resources/schema-postgresql.sqlGenerate encryption key using Java:
cd note-keeper-service
mvn compile exec:java -Dexec.mainClass="xyz.crearts.note.keeper.service.EncryptionService" -Dexec.classpathScope=compileOr manually in code:
String key = EncryptionService.generateKey();
System.out.println(key); // Copy this keySet the key in application.yml:
app:
encryption:
key: "your-generated-base64-key-here"Or use environment variable:
export ENCRYPTION_KEY="your-generated-base64-key-here"Important:
- Without a fixed key, encrypted notes will be unreadable after restart
- Store key securely (password manager, secrets vault)
- Key is 256-bit AES (Base64 encoded = 44 characters)
- Once set, never change it or you'll lose access to encrypted notes
Default credentials (development only):
- Username:
admin - Password: Auto-generated on first start (check logs)
Production: Configure OAuth (Google) or LDAP.
Telegram Notifications:
app:
integrations:
telegram:
enabled: true
bot-token: YOUR_BOT_TOKEN
chat-id: YOUR_CHAT_IDDingTalk Notifications:
app:
integrations:
dingtalk:
enabled: true
webhook: YOUR_WEBHOOK_URL
secret: YOUR_SECRETConfigure in Settings UI or application.yml:
app:
backup:
auto-enabled: true
cron: "0 0 2 * * *" # Daily at 2 AM
retention-days: 30cd note-keeper-service
mvn clean install
mvn spring-boot:runServer starts on http://localhost:8080
cd note-keeper-web
npm install
npm run devOr build production:
mvn clean install -pl note-keeper-webFrontend served by backend at http://localhost:8080
Needs GraalVM 25+ with native-image. On Windows use x64 Native Tools Command Prompt.
One binary = React UI + Spring API. From repo root:
mvn -Pnative native:compile
./note-keeper-service/target/note-keeper -Djavax.xml.accessExternalDTD=allDocker image (Buildpacks, JDK 25+):
mvn -pl note-keeper-service -am -Pnative spring-boot:build-imageCI image (multi-stage GraalVM):
docker build -f Dockerfile.native -t note-keeper-native .
docker run -d -p 9082:8080 \
-e SPRING_PROFILES_ACTIVE=sqlite \
-v /volume1/docker/note-keeper/etc:/app/etc:ro \
-v /volume1/docker/note-keeper-native/var:/app/var:rw \
--name note-keeper-native note-keeper-nativeGitea: HTTP registry devops.local:5000 (REGISTRY_USER / REGISTRY_PASSWORD). JVM deploy.yml β minipc build+push β NAS 9081. Native deploy-native.yml β minipc build+push β NAS 9082.
Access OpenAPI docs at: http://localhost:8080/swagger-ui.html
Key endpoints:
GET /api/v1/notes- List notesPOST /api/v1/notes- Create noteGET /api/v1/todos- List todosPOST /api/v1/backup/export- Export backupPOST /api/v1/backup/import- Import backup
Customize in Settings > Shortcuts:
Ctrl+N- New noteCtrl+T- New todoCtrl+K- SearchCtrl+B- Toggle sidebarEsc- Exit fullscreen
note-keeper/
βββ note-keeper-service/ # Spring Boot backend
β βββ src/main/java/
β β βββ xyz/crearts/note/keeper/
β β βββ controller/ # REST controllers
β β βββ service/ # Business logic
β β βββ mapper/ # MyBatis mappers
β β βββ dto/ # Data transfer objects
β β βββ config/ # Configuration
β βββ src/main/resources/
β βββ application.yml # Configuration
β βββ schema.sql # Database schema
β βββ mapper/ # MyBatis XML
βββ note-keeper-web/ # React frontend
β βββ src/
β β βββ pages/ # Page components
β β βββ components/ # Reusable components
β β βββ utils/ # Utilities
β β βββ types/ # TypeScript types
β βββ package.json
βββ var/ # Runtime data (auto-created)
βββ data/
βββ attachments/
βββ backups/
- Backend: Add controller β service β mapper β DTO
- Frontend: Add page/component β update API calls
- Update schema if needed
- Test both modules
Database not created:
- Check
var/data/directory exists - Verify write permissions
- Check logs for SQLite errors
Attachments not uploading:
- Verify
var/attachments/exists - Check file size limits
- Review backend logs
Backup fails:
- Ensure
var/backups/is writable - Check disk space
- Review cron expression format
MIT License