# ✏️ InkNote
A cross-platform note-taking application with rich text editing, freehand drawing, PDF annotation, and encrypted sync — inspired by Samsung Notes.
---
## Features
### Core
- **Rich Text Notes** — Bold, italic, underline, headings, bullet/numbered lists, checkboxes
- **Freehand Drawing** — Pen, highlighter, eraser with adjustable thickness and color palette (20 colors, 7 pen sizes)
- **Undo/Redo** — Full history stack for drawing operations
- **PDF Import & Annotation** — Import PDFs, overlay drawing/highlighting, persistent annotations
- **Notebooks & Folders** — Create notebooks with custom gradient covers, organize notes by folder
- **Star/Favorite** — Quick access to important notes
- **Dark & Light Mode** — Full theme support with refined color schemes
### Sync & Storage
- **Offline-First** — Works fully offline, syncs when connection returns
- **Conflict-Aware Sync** — Vector clock–based conflict detection; notifies user of merge conflicts
- **WebSocket Real-Time Push** — Changes appear on other devices instantly
- **Encrypted at Rest** — AES-256-CBC encryption for all note content on the server
- **JWT Authentication** — Secure user accounts with bcrypt password hashing
### Architecture
- **Self-Hosted Backend** — Node.js + Express + SQLite (or PostgreSQL)
- **Docker Ready** — docker-compose up and you're running
- **Client Sync Engine** — Portable JS library for any frontend (React Native, Flutter JS bridge, Electron, web)
---
## Project Structure
```
inknote/
├── note-app.jsx # Full React UI (artifact / web)
├── docker-compose.yml # Container orchestration
├── backend/
│ ├── server.js # Express API + WebSocket server
│ ├── sync-client.js # Client-side sync engine library
│ ├── package.json # Node dependencies
│ ├── Dockerfile # Server container
│ └── .env.example # Environment variable template
└── README.md # This file
```
---
## Quick Start
### 1. Run the UI (Web / Artifact)
The `note-app.jsx` file is a self-contained React component. It runs directly as a Claude artifact, or you can embed it in any React project:
```jsx
import NoteApp from './note-app';
function App() {
return
World
' }); await sync.updateNote('note-id', { title: 'Updated' }); await sync.deleteNote('note-id'); await sync.uploadPDF(fileBlob); await sync.saveDrawing('note-id', canvasDataUrl); ``` --- ## Conflict Resolution InkNote uses **vector clocks** to detect conflicts: 1. Each device maintains a logical clock counter 2. On save, the device increments its counter and includes the full vector clock 3. The server compares clocks — if the client clock is strictly newer, the update applies 4. If clocks are concurrent (both have changes the other doesn't), a **409 Conflict** is returned 5. The client receives both versions and can present a merge UI to the user --- ## Extending to Native Platforms ### React Native Use `note-app.jsx` components with React Native adaptations (replace HTML canvas with `react-native-canvas` or `@shopify/react-native-skia` for drawing). The sync engine works as-is. ### Flutter Use the sync engine via a JavaScript bridge, or port the API calls to Dart. For drawing, use Flutter's `CustomPainter`. For PDF, use `flutter_pdfview`. ### Electron Wrap the React app directly in Electron for desktop. Add native file system access for PDF import/export. --- ## Security Notes - All note content is encrypted with AES-256-CBC before database storage - Passwords are hashed with bcrypt (12 rounds) - JWT tokens expire after 30 days - HTTPS should be enforced in production (use a reverse proxy like Nginx or Pangolin) - The encryption key should be stored securely (e.g., environment variable, secrets manager) --- ## Tech Stack | Layer | Technology | |-----------|-------------------------------------| | Frontend | React (web), adaptable to RN/Flutter | | Backend | Node.js, Express | | Database | SQLite (dev), PostgreSQL (prod) | | Real-time | WebSocket (ws library) | | Auth | JWT + bcrypt | | Encryption| AES-256-CBC | | Container | Docker + docker-compose |