Markdown note-taking application with folders, tags, and full-text search. Express backend + React frontend.
+-----------+
| Browser |
+-----+-----+
|
+-----------+-----------+
| |
+--------v--------+ +---------v--------+
| Vite Dev (5173) | | Express API (3001)|
| React Frontend | | REST Endpoints |
+---------+--------+ +---------+--------+
| |
| CORS (direct) |
+-----------+-----------+
|
+-----------v-----------+
| Service Layer |
| (noteService.js) |
+-----------+-----------+
|
+-----------v-----------+
| Repositories |
| folder / note repos |
+-----------+-----------+
|
+-----------v-----------+
| In-Memory Storage |
+-----------------------+
# Backend
npm install
npm start # http://localhost:3001
# Frontend (separate terminal)
cd frontend
npm install
npm run dev # http://localhost:5173
# Tests
npm test # 24 backend tests (Jest)
cd frontend && npx playwright test # 17 E2E tests (Playwright)
Method
Endpoint
Description
GET
/api/folders
List all folders
GET
/api/folders/:id
Get folder by ID
POST
/api/folders
Create folder ({ name })
PUT
/api/folders/:id
Update folder ({ name })
DELETE
/api/folders/:id
Delete folder
Method
Endpoint
Description
GET
/api/notes
List notes (supports filters)
GET
/api/notes/:id
Get note by ID
POST
/api/notes
Create note
PUT
/api/notes/:id
Update note
DELETE
/api/notes/:id
Delete note
Query Parameters (GET /api/notes)
Param
Description
Example
q
Search title + content
?q=meeting
folder
Filter by folder ID
?folder=1
tag
Filter by tag
?tag=work
// POST /api/notes
{
"title" : " Meeting Notes" ,
"content" : " Discussed roadmap..." ,
"folderId" : 1 ,
"tags" : [" work" , " meeting" ]
}
// Response
{
"success" : true ,
"data" : {
"id" : 1 ,
"title" : " Meeting Notes" ,
"content" : " Discussed roadmap..." ,
"folderId" : 1 ,
"tags" : [" work" , " meeting" ],
"createdAt" : " 2026-02-12T..." ,
"updatedAt" : " 2026-02-12T..."
}
}
Field
Rules
title
Required, 1-255 chars
content
Optional, defaults to ""
folderId
Optional, positive integer
tags
Optional, max 10 tags, each max 50 chars
folder.name
Required, 1-100 chars
Backend : Express 4, Zod 4, CORS, in-memory storage
Frontend : React 19, Vite 7
Testing : Jest + Supertest (backend), Playwright (E2E)
note-taking-api/
src/
app.js Express routes
server.js Server startup (port 3001)
errors.js ApiError, NotFoundError, ValidationError
validators.js Zod schemas
folderRepository.js In-memory folder data access
noteRepository.js In-memory note data access
noteService.js Business logic
middleware.js validate(), parseId(), errorHandler()
__tests__/
folders.test.js 7 folder CRUD tests
notes.test.js 17 note CRUD + search tests
frontend/
src/
App.jsx Main app with state management
FolderSidebar.jsx Folder navigation sidebar
NoteList.jsx Note card list display
NoteForm.jsx Create/edit note form
api.js API client (foldersApi, notesApi)
tests/e2e/
note-app.spec.js 17 Playwright E2E tests