AI-powered collaborative study & knowledge management platform
Noted transforms note-taking into an all-in-one study platform combining real-time collaboration , AI-assisted content generation , spaced repetition flashcards , quizzes , and a Pomodoro timer - all in one unified experience.
Rich Text Editor - TipTap-based editor with formatting, code blocks, tables, images, and embeds
Real-time Collaboration - Simultaneous editing with cursor tracking and presence awareness
Block-based Content - Modular content blocks for flexible document structure
Markdown Support - Write in markdown with live preview
Smart Summarization - Auto-generate concise summaries
Content Expansion - Elaborate on topics with AI assistance
Flowchart Generation - Auto-create Mermaid diagrams
Translation - Multi-language support
Quiz Generation - Create quizzes from your notes
Flashcard Creation - Generate study cards automatically
Flashcards - Spaced repetition with SM-2 algorithm
Quizzes - Multiple question types with instant feedback
Pomodoro Timer - Floating, draggable productivity timer
Hierarchical Folders - Organize notes with nested folders
Tags - Flexible tagging system
Sharing - Public/private links with password protection
File Library - Upload and manage PDFs, images, and documents
High-Level System Architecture
flowchart TB
subgraph Client["Client Layer"]
Browser["Browser"]
Editor["TipTap Editor"]
YJS["Y.js Client"]
end
subgraph Frontend["Next.js Application :3000"]
Pages["App Router Pages"]
API["API Routes"]
Context["React Context"]
Components["152 Components"]
end
subgraph Realtime["WebSocket Server :3001"]
Socket["Socket.io"]
YServer["Y.js Server"]
end
subgraph Backend["Backend Services"]
Auth["Better-Auth"]
AI["AI Provider Layer"]
Stripe["Stripe Payments"]
end
subgraph Data["Data Layer"]
PG[(PostgreSQL)]
Redis[(Redis)]
S3[(S3/R2 Storage)]
end
subgraph External["External Services"]
Groq["Groq API"]
OpenAI["OpenAI API"]
Ollama["Ollama (Local)"]
end
Browser --> Pages
Editor --> YJS
YJS <--> Socket
Pages --> API
API --> Auth
API --> AI
API --> Stripe
Auth --> PG
API --> PG
Socket --> Redis
Socket --> YServer
YServer --> PG
AI --> Groq
AI --> OpenAI
AI --> Ollama
API --> S3
Loading
flowchart TD
Start([User Visits App]) --> Check{Has Session?}
Check -->|Yes| Validate[Validate Session Token]
Check -->|No| Login[Show Login Page]
Validate -->|Valid| Dashboard[Load Dashboard]
Validate -->|Invalid/Expired| Login
Login --> AuthMethod{Auth Method}
AuthMethod -->|Email/Password| EmailAuth[Email Authentication]
AuthMethod -->|OAuth| OAuthFlow[OAuth2 Flow]
EmailAuth --> Verify[Verify Credentials]
Verify -->|Success| CreateSession[Create Session]
Verify -->|Fail| Error[Show Error]
OAuthFlow --> Provider{Provider}
Provider -->|Google| Google[Google OAuth]
Provider -->|GitHub| GitHub[GitHub OAuth]
Google --> Callback[OAuth Callback]
GitHub --> Callback
Callback --> CreateSession
CreateSession --> SetCookie[Set Session Cookie]
SetCookie --> Dashboard
Error --> Login
Loading
Real-Time Collaboration Flow
sequenceDiagram
participant U1 as User 1
participant U2 as User 2
participant WS as WebSocket Server
participant YJS as Y.js CRDT
participant DB as PostgreSQL
U1->>WS: Connect to document room
WS->>DB: Load Y.js state
DB-->>WS: Return saved state
WS-->>U1: Sync initial state
U2->>WS: Connect to same room
WS-->>U2: Sync current state
WS-->>U1: User 2 presence update
U1->>WS: Edit operation (delta)
WS->>YJS: Merge CRDT changes
YJS-->>WS: Resolved state
WS-->>U2: Broadcast changes
WS->>DB: Persist Y.js state
U2->>WS: Edit operation (delta)
WS->>YJS: Merge CRDT changes
YJS-->>WS: Resolved state
WS-->>U1: Broadcast changes
Loading
flowchart LR
subgraph Input
User[User Request]
Context[Note Context]
Mode[AI Mode]
end
subgraph Processing
Validate[Validate Quota]
Truncate[Truncate Context]
Prompt[Build System Prompt]
Select[Select Model]
end
subgraph Generation
Stream[Stream Response]
Parse[Parse Markdown]
end
subgraph Output
Display[Display to User]
Track[Track Usage]
Save[Save to Block]
end
User --> Validate
Context --> Truncate
Mode --> Prompt
Validate -->|OK| Truncate
Validate -->|Over Quota| Error[Show Upgrade]
Truncate --> Prompt
Prompt --> Select
Select --> Stream
Stream --> Parse
Parse --> Display
Stream --> Track
Display --> Save
Loading
Flashcard Spaced Repetition (SM-2 Algorithm)
flowchart TD
Start([Review Card]) --> Show[Show Question]
Show --> Reveal[User Reveals Answer]
Reveal --> Grade{User Self-Grade}
Grade -->|Again| G0[Quality = 0]
Grade -->|Hard| G1[Quality = 1]
Grade -->|Good| G2[Quality = 3]
Grade -->|Easy| G3[Quality = 5]
G0 --> Calculate[Calculate New Interval]
G1 --> Calculate
G2 --> Calculate
G3 --> Calculate
Calculate --> Update[Update Ease Factor]
Update --> Schedule[Schedule Next Review]
Schedule --> Next{More Cards?}
Next -->|Yes| Start
Next -->|No| Complete([Session Complete])
subgraph SM2["SM-2 Formula"]
EF["EF' = EF + (0.1 - (5-q) * (0.08 + (5-q) * 0.02))"]
Int["Interval = Previous * EF"]
end
Loading
flowchart TD
Request([HTTP Request]) --> Middleware{Middleware}
Middleware --> RateLimit[Rate Limiting]
RateLimit -->|Exceeded| R429[429 Too Many Requests]
RateLimit -->|OK| Auth[Authentication Check]
Auth -->|Public Route| Handler[Route Handler]
Auth -->|Protected Route| Session{Valid Session?}
Session -->|No| R401[401 Unauthorized]
Session -->|Yes| Subscription[Check Subscription]
Subscription --> Limits{Within Limits?}
Limits -->|No| R403[403 Forbidden]
Limits -->|Yes| Handler
Handler --> DB[(Database)]
DB --> Response[Build Response]
Response --> Client([Return to Client])
Loading
Technology
Version
Purpose
Next.js
16.1.4
React framework with App Router
React
19.2.3
UI library
TypeScript
5.x
Type safety
Tailwind CSS
4.x
Styling
TipTap
3.15.3
Rich text editor
Y.js
13.6.29
CRDT for collaboration
Technology
Version
Purpose
Node.js
22.18+
Runtime
Socket.io
4.8.3
WebSocket server
Better-Auth
1.4.16
Authentication
Drizzle ORM
0.45.1
Database ORM
Stripe
20.2.0
Payments
Provider
Models
Purpose
Groq
Llama 3.3 70B, Mixtral 8x7B
Primary AI inference
OpenAI
GPT-4o-mini
Alternative provider
Ollama
Llama 3.1, Mistral
Local inference
Technology
Purpose
PostgreSQL 16
Primary database
Redis 7
Caching & pub/sub
S3/R2
File storage
Docker
Containerization
Node.js 22.18 or higher
PostgreSQL 16
Redis 7 (optional for development)
npm, yarn, or pnpm
Clone the repository
git clone https://github.com/yourusername/noted.git
cd noted
Install dependencies
Set up environment variables
cp .env.example .env
# Edit .env with your configuration
Set up the database
npm run db:generate
npm run db:push
Start the development servers
# Terminal 1: Next.js app
npm run dev
# Terminal 2: Backend API + WebSocket server
npm run dev:backend
Open the app
Navigate to http://localhost:3000
# Development
docker-compose up
# Production
docker-compose -f docker-compose.prod.yml up -d
Create a .env file in the root directory:
# Database
DATABASE_URL = " postgresql://user:password@localhost:5432/noted"
# Authentication
BETTER_AUTH_SECRET = " your-secret-key"
BETTER_AUTH_URL = " http://localhost:3000"
# OAuth Providers
GOOGLE_CLIENT_ID = " your-google-client-id"
GOOGLE_CLIENT_SECRET = " your-google-client-secret"
GITHUB_CLIENT_ID = " your-github-client-id"
GITHUB_CLIENT_SECRET = " your-github-client-secret"
# AI Configuration
AI_PROVIDER = " groq" # groq | openai | ollama
GROQ_API_KEY = " your-groq-api-key"
OPENAI_API_KEY = " your-openai-api-key"
ENABLE_AI_FEATURES = " true"
# Redis (optional)
REDIS_URL = " redis://localhost:6379"
# Stripe
STRIPE_SECRET_KEY = " sk_test_..."
STRIPE_PUBLISHABLE_KEY = " pk_test_..."
STRIPE_WEBHOOK_SECRET = " whsec_..."
# File Storage
S3_BUCKET = " your-bucket"
S3_REGION = " us-east-1"
S3_ACCESS_KEY = " your-access-key"
S3_SECRET_KEY = " your-secret-key"
Entity Relationship Diagram
erDiagram
users ||--o{ pages : creates
users ||--o{ folders : owns
users ||--o{ sessions : has
users ||--o{ accounts : links
users ||--o{ subscriptions : subscribes
users ||--o{ ai_usage : tracks
folders ||--o{ pages : contains
folders ||--o{ folders : nests
pages ||--o{ page_collaborators : shares
pages ||--o{ page_tags : tagged
pages ||--o{ share_links : publishes
tags ||--o{ page_tags : applies
users {
uuid id PK
string email UK
string name
string password_hash
boolean email_verified
timestamp created_at
}
folders {
uuid id PK
uuid user_id FK
uuid parent_id FK
string name
string color
int sort_order
}
pages {
uuid id PK
uuid folder_id FK
uuid user_id FK
string title
jsonb blocks
binary ydoc_state
boolean is_public
timestamp updated_at
}
subscriptions {
uuid id PK
uuid user_id FK
string tier
string stripe_id
timestamp current_period_end
}
ai_usage {
uuid id PK
uuid user_id FK
int month
int year
int request_count
}
Loading
Category
Tables
Auth
users, accounts, sessions, verifications
Content
pages, folders, blocks
Collaboration
page_collaborators, folder_collaborators, collaboration_sessions, presence
Sharing
share_links
Files
files, file_folders
Learning
tags, page_tags, folder_tags, todos
Billing
subscriptions, ai_usage, rate_limits
Endpoint
Method
Description
/api/auth/[...all]
ALL
Better-Auth handler
Endpoint
Method
Description
/api/pages
GET
List user's pages
/api/pages
POST
Create new page
/api/pages/[id]
GET
Get page by ID
/api/pages/[id]
PUT
Update page
/api/pages/[id]
DELETE
Delete page
/api/pages/[id]/save
POST
Save page content
/api/pages/[id]/share
POST
Generate share link
/api/pages/[id]/collaborators
POST
Add collaborator
Endpoint
Method
Description
/api/folders
GET
List folders
/api/folders
POST
Create folder
/api/folders/[id]
PUT
Update folder
/api/folders/[id]
DELETE
Delete folder
Endpoint
Method
Description
/api/ai/generate
POST
Generate AI response (streaming)
/api/ai/actions
POST
Execute AI-requested actions
/api/ai/models
GET
List available models
Endpoint
Method
Description
/api/files
GET
List files
/api/files
POST
Upload file
/api/files/[id]
DELETE
Delete file
/api/files/extract-text
POST
Extract text from PDF
Mode
Description
Use Case
answer
Q&A about content
Ask questions about notes
expand
Elaborate with details
Add more information
summarize
Create TL;DR
Quick overviews
translate
Multi-language
Translate content
explain
Simplify topics
Learn complex concepts
improve
Writing enhancement
Polish your writing
flowchart
Generate diagrams
Visualize processes
quiz
Create questions
Test your knowledge
flashcard
Study cards
Spaced repetition
AI Provider Configuration
flowchart LR
Config[AI_PROVIDER env] --> Check{Provider}
Check -->|groq| Groq[Groq API]
Check -->|openai| OpenAI[OpenAI API]
Check -->|ollama| Ollama[Local Ollama]
Groq --> Models1[Llama 3.3 70B<br/>Mixtral 8x7B<br/>Compound-Beta]
OpenAI --> Models2[GPT-4o-mini]
Ollama --> Models3[Llama 3.1 8B<br/>Mistral 7B]
Loading
Tier
AI Requests/Month
Price
Free
10
$0
Pro
500
$9/mo
Team
Unlimited
$29/mo
Docker Production Deployment
# docker-compose.prod.yml
services :
web :
build : .
ports :
- " 3000:3000"
environment :
- NODE_ENV=production
depends_on :
- postgres
- redis
websocket :
build :
context : .
dockerfile : Dockerfile.ws
ports :
- " 3001:3001"
depends_on :
- redis
postgres :
image : postgres:16
volumes :
- pgdata:/var/lib/postgresql/data
environment :
POSTGRES_DB : noted
POSTGRES_USER : noted
POSTGRES_PASSWORD : ${DB_PASSWORD}
redis :
image : redis:7-alpine
volumes :
- redisdata:/data
volumes :
pgdata :
redisdata :
Build the application
Run database migrations
Start production services
docker-compose -f docker-compose.prod.yml up -d
Set up SSL (optional)
./init-ssl.sh your-domain.com
noted/
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── (auth)/ # Auth pages (login, register)
│ │ ├── api/ # 34 API routes
│ │ ├── note/[id]/ # Note editor page
│ │ ├── folder/[id]/ # Folder view
│ │ └── pricing/ # Subscription pricing
│ ├── components/ # 152 React components
│ │ ├── dashboard/ # Main dashboard UI
│ │ ├── editor/ # TipTap editor components
│ │ ├── ai/ # AI integration UI
│ │ ├── flashcards/ # Spaced repetition UI
│ │ ├── pomodoro/ # Timer widget
│ │ └── collaboration/ # Real-time features
│ ├── context/ # 10 React Context providers
│ ├── lib/ # Business logic
│ │ ├── ai/ # AI provider configuration
│ │ ├── auth.ts # Authentication setup
│ │ └── subscription.ts # Tier management
│ ├── db/ # Database layer
│ │ └── schema.ts # Drizzle ORM schema
│ └── types/ # TypeScript definitions
├── backend/ # Backend API + WebSocket server
│ └── src/index.ts # Hono + Socket.io + Y.js handler
├── drizzle/ # Database migrations
├── public/ # Static assets
└── docker-compose.yml # Docker configuration
Command
Description
npm run dev
Start development server
npm run dev:backend
Start backend API + WebSocket server
npm run build
Build for production
npm run start
Start production server
npm run lint
Run ESLint
npm run db:generate
Generate migrations
npm run db:push
Push schema to database
npm run db:studio
Open Drizzle Studio
Fork the repository
Create your feature branch (git checkout -b feature/amazing-feature)
Commit your changes (git commit -m 'Add amazing feature')
Push to the branch (git push origin feature/amazing-feature)
Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
Made with dedication for learners everywhere