You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A modern, self-hosted note-taking application with hierarchical organization, rich text editing, AI integration, and security-first design.
Screenshot
A Note on Quality
This isn't your typical "AI slop." While Claude Code assisted in development, every feature was thoughtfully designed with security reviews, proper error handling, and production-ready code. The codebase includes:
Comprehensive security audit with tiered rate limiting
Parameterized SQL queries throughout (no string concatenation)
Input validation on all API endpoints
Proper authentication flows with JWT + refresh tokens
No hardcoded secrets in production configurations
Features
Rich Text Editor
WYSIWYG Editing - Powered by TipTap with real-time formatting
Slash Commands - Type / to access quick formatting:
Languages - English, Chinese (Simplified), Hindi, Spanish, Arabic
Timezone - 30+ common timezones supported
Tech Stack
Component
Technology
Frontend
React 18, TypeScript, Vite
Editor
TipTap 2.11 (ProseMirror-based)
Backend
Node.js, Express, TypeScript
Database
SQLite (better-sqlite3)
Auth
JWT + bcrypt + TOTP (otplib)
Search
Local embeddings (Transformers.js + bge-small-en-v1.5)
Animations
Framer Motion
Math
KaTeX
Diagrams
Mermaid
Drag & Drop
@dnd-kit
Styling
CSS Modules + CSS Variables
Font
Inter
Deployment
Docker, Nginx
Quick Start
Prerequisites
Node.js 20+
npm or yarn
Development
# Clone the repository
git clone https://github.com/clucraft/note-app.git
cd note-app
# Start the backendcd backend
npm install
npm run dev
# Start the frontend (new terminal)cd frontend
npm install
npm run dev
The app will be available at http://localhost:5173
Production (Docker)
Deploy with a single command using pre-built images from GitHub Container Registry:
# Download docker-compose.yml
curl -O https://raw.githubusercontent.com/clucraft/note-app/main/docker-compose.yml
# Create environment file with secure secrets
cat > .env <<EOFACCESS_TOKEN_SECRET=$(openssl rand -hex 32)REFRESH_TOKEN_SECRET=$(openssl rand -hex 32)EOF# Start the application
docker-compose up -d
The app will be available at http://localhost:8088
Build from Source
If you prefer to build the images yourself:
git clone https://github.com/clucraft/note-app.git
cd note-app
docker-compose -f docker-compose.dev.yml up -d
Navigate to APIs & Services > Library, search for Google Drive API, and enable it
Go to APIs & Services > OAuth consent screen
Choose External user type
Fill in the app name and your email
Add the scope https://www.googleapis.com/auth/drive
Add your Google account as a test user
Go to APIs & Services > Credentials
Click Create Credentials > OAuth client ID
Application type: Web application
Under Authorized redirect URIs, add:
{BACKEND_PUBLIC_URL}/api/backups/oauth2/callback
For example: https://notes.example.com/api/backups/oauth2/callback
Save the Client ID and Client Secret
2. Set Environment Variable
Add BACKEND_PUBLIC_URL to your backend environment, set to the public URL where your backend is reachable (e.g. https://notes.example.com). This is used to construct the OAuth redirect URI.
3. Connect in the App
Go to Settings > Backups
Enter your Client ID and Client Secret, click Save Credentials
Click Connect Google Drive — you'll be redirected to Google's consent screen
Authorize with your Google account — you'll be redirected back with a success message
Enter a Google Drive Folder ID (the long string in the URL when you open a folder in Drive: https://drive.google.com/drive/folders/{FOLDER_ID})
Click Test Connection to verify — it should display your email
4. Configure Schedule
Enable automatic backups, set the interval (hours between backups), and the retention limit (max backups to keep). Older backups are automatically deleted when the limit is exceeded.
Note: While the OAuth consent screen is in "Testing" status, only users added as test users can authorize. This is fine for personal/self-hosted use — you don't need to go through Google's verification process.