A full-stack note-taking application built with Go/Gin backend and React/Vite frontend.
- π Create, edit, delete notes with rich text editor (Quill)
- π Pin/unpin important notes
- π·οΈ Organize with tags (multiple per note)
- π Group into folders
- π Full-text search
- π Markdown support
- Create, edit, delete folders with custom icons & colors
- Create, edit, delete tags with color picker
- View all notes inside a folder
- π Toast notifications for all actions
- β Confirmation modals for destructive actions
- π Notification bell with history
- π Dark mode support
- π± Responsive design
- JWT-based authentication
- User registration & login
- Profile management with avatar
| Technology | Purpose |
|---|---|
| Go 1.21+ | Language |
| Gin | HTTP framework |
| GORM | ORM |
| PostgreSQL | Database |
| JWT | Authentication |
| MinIO | Object storage (avatars, images) |
| Zap | Structured logging |
| Technology | Purpose |
|---|---|
| React 19 | UI library |
| Vite | Build tool |
| TypeScript | Type safety |
| TailwindCSS v4 | Styling |
| ReactQuill | Rich text editor |
| react-markdown | Markdown rendering |
| react-hot-toast | Notifications |
| Axios | HTTP client |
simple-note-app/
βββ apps/
β βββ backend/ # Go API server
β β βββ cmd/api/ # Entry point
β β βββ config/ # Configuration
β β βββ internal/
β β β βββ dto/ # Data transfer objects
β β β βββ handlers/ # HTTP handlers
β β β βββ middleware/ # Auth, CORS, rate limit
β β β βββ models/ # GORM models
β β β βββ repository/ # Database layer
β β β βββ services/ # Business logic
β β βββ migrations/ # SQL migrations
β β βββ pkg/ # Utilities (jwt, password, logger)
β β
β βββ frontend/ # React application
β βββ src/
β β βββ components/ # React components
β β βββ context/ # Auth & Notification context
β β βββ hooks/ # Custom hooks
β β βββ lib/ # Axios config
β β βββ services/ # API services
β β βββ types/ # TypeScript types
β βββ index.html
β
βββ package.json # Monorepo config
βββ README.md
- Go 1.21+
- Node.js 18+
- PostgreSQL 15+
- (Optional) MinIO for image uploads
git clone <repository-url>
cd simple-note-app
# Install frontend dependencies
npm install# Create database
createdb gonote
# Run migrations
psql -d gonote -f apps/backend/migrations/001_create_users.sql
psql -d gonote -f apps/backend/migrations/002_create_folders.sql
psql -d gonote -f apps/backend/migrations/003_create_tags.sql
psql -d gonote -f apps/backend/migrations/004_create_notes.sql
psql -d gonote -f apps/backend/migrations/005_create_note_tags.sql
psql -d gonote -f apps/backend/migrations/006_create_note_images.sqlconnection to server on socket "/var/run/postgresql/.s.PGSQL.5432" failedpsql -h localhost -U postgres -d gonote -f 001_create_users.sql
psql -h localhost -U postgres -d gonote -f 002_create_folders.sql
psql -h localhost -U postgres -d gonote -f 003_create_tags.sql
psql -h localhost -U postgres -d gonote -f 004_create_notes.sql
psql -h localhost -U postgres -d gonote -f 005_create_note_tags.sql
psql -h localhost -U postgres -d gonote -f 006_create_note_images.sqlcd apps/backend
cp .env.example .env
# Edit .env with your settings.env configuration:
# Server
PORT=8080
GIN_MODE=debug
# Database
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=yourpassword
DB_NAME=gonote
DB_SSLMODE=disable
# JWT
JWT_SECRET=your-super-secret-key-here
JWT_EXPIRY_HOURS=72
# MinIO (optional)
MINIO_ENDPOINT=localhost:9000
MINIO_ACCESS_KEY=minioadmin
MINIO_SECRET_KEY=minioadmin
MINIO_BUCKET=gonote
MINIO_USE_SSL=false
# CORS
CORS_ALLOWED_ORIGINS=http://localhost:5173Populate the database with sample data for testing:
cd apps/backend
go run cmd/seed/seed.goThis creates:
- Demo user:
demo@gonote.app/demo123 - 6 folders with various categories
- 8 tags with different colors
- 15+ sample notes (meeting notes, code snippets, recipes, etc.)
Terminal 1 - Backend:
cd apps/backend
go run ./cmd/api/main.go
# Server runs at http://localhost:8080Terminal 2 - Frontend:
cd apps/frontend
npm run dev
# UI runs at http://localhost:5173| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/auth/register |
Register new user |
| POST | /api/v1/auth/login |
Login |
| GET | /api/v1/auth/profile |
Get profile (auth required) |
| PUT | /api/v1/auth/profile |
Update profile (auth required) |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/notes |
List notes (with pagination, search, filter) |
| POST | /api/v1/notes |
Create note |
| GET | /api/v1/notes/:id |
Get note by ID |
| PUT | /api/v1/notes/:id |
Update note |
| DELETE | /api/v1/notes/:id |
Delete note |
Query Parameters for GET /notes:
page- Page number (default: 1)page_size- Items per page (default: 10)search- Search in title/contentfolder_id- Filter by foldertag_id- Filter by tagis_pinned- Filter pinned notes
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/folders |
List folders |
| POST | /api/v1/folders |
Create folder |
| GET | /api/v1/folders/:id |
Get folder |
| PUT | /api/v1/folders/:id |
Update folder |
| DELETE | /api/v1/folders/:id |
Delete folder |
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/tags |
List tags |
| POST | /api/v1/tags |
Create tag |
| DELETE | /api/v1/tags/:id |
Delete tag |
| Method | Endpoint | Description |
|---|---|---|
| POST | /api/v1/upload/note-image |
Upload note image |
| POST | /api/v1/upload/avatar |
Upload user avatar |
The API uses JWT tokens. Include the token in requests:
Authorization: Bearer <your-jwt-token>
Example login:
curl -X POST http://localhost:8080/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "password": "password123"}'Build and run with Docker:
cd apps/backend
docker build -t gonote-api .
docker run -p 8080:8080 --env-file .env gonote-apicd apps/backend
go mod tidy # Install dependencies
go run ./cmd/api/main.go # Run server
go build -o gonote ./cmd/api # Build binarycd apps/frontend
npm run dev # Dev server with HMR
npm run build # Production build
npm run preview # Preview production buildMIT License - see LICENSE for details.