This guide covers everything you need to know to develop KoInsight locally.
- Prerequisites
- Getting Started
- Development Workflow
- Key Technologies
- Project Structure
- Database Management
- Code Quality
- Testing
- Contributing
Before you begin, ensure you have the following installed:
-
Node.js (v22 or higher)
- Download from nodejs.org
- Or use a version manager like nvm
-
npm (v10.2.4 or higher)
- The project uses npm workspaces for monorepo management
-
nvm (Node Version Manager) - Makes it easy to switch between Node versions
# Install nvm (macOS/Linux) curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash # Use the required Node version nvm install 22 nvm use 22
-
Docker (optional) - For running the production build locally
git clone https://github.com/GeorgeSG/koinsight.git
cd koinsightKoInsight uses a monorepo structure with npm workspaces. Install all dependencies from the root:
npm installThis will install dependencies for:
- Root workspace (build tools, Prettier, Turbo)
apps/server(Express backend)apps/web(React frontend)packages/common(shared types)
The development database uses SQLite and is stored in the data/ directory.
Run database migrations:
npm run -w server knex migrate:latestPopulate your database with realistic fake data for development:
# From the root directory
npm run seedThis creates:
- 5 e-reader devices
- 10 books (popular fantasy/sci-fi titles)
- Realistic reading statistics and page data
- 200+ annotations (highlights, notes, bookmarks)
- 14 genres with book associations
- 3 test users with KoSync progress data
Test User Credentials:
- Username:
reader1,reader2,bookworm - Password:
password123(all users)
See Database Seeding for more details.
KoInsight consists of two apps that run concurrently:
From the root directory:
npm run devThis uses Turbo to run both apps in parallel:
- Backend server: http://localhost:3000 (Express API)
- Frontend web app: http://localhost:5173 (Vite dev server)
Backend only:
cd apps/server
npm run dev- Runs on http://localhost:3001
- Watches for TypeScript changes and auto-restarts
Frontend only:
cd apps/web
npm run dev- Runs on http://localhost:3000
- Hot module replacement enabled
- Frontend proxy: The Vite dev server (port 3000) proxies API requests to the backend (port 3001)
- Hot reload: Both apps support hot reloading during development
- TypeScript: Changes to TypeScript files trigger automatic recompilation
- Shared types: The
@koinsight/commonpackage contains types shared between frontend and backend
Backend:
- Express 5.x - Web framework
- Knex.js - SQL query builder
- better-sqlite3 - SQLite driver
- bcryptjs - Password hashing
- Multer - File upload handling
- Zod - Schema validation
Frontend:
- React 18.x - UI library
- Vite - Build tool and dev server
- Mantine UI - Component library
- React Router 7.x - Client-side routing
- SWR - Data fetching and caching
- Recharts - Data visualization
Development:
- TypeScript - Type safety
- Turbo - Monorepo build system
- Prettier - Code formatting
- Vitest - Unit testing
koinsight/
├── apps/
│ ├── server/ # Express backend (TypeScript)
│ │ ├── src/
│ │ │ ├── annotations/ # Annotation management
│ │ │ ├── books/ # Book management
│ │ │ ├── db/ # Database migrations, seeds, factories
│ │ │ ├── devices/ # Device management
│ │ │ ├── genres/ # Genre management
│ │ │ ├── kosync/ # KoSync protocol implementation
│ │ │ ├── stats/ # Statistics and analytics
│ │ │ └── app.ts # Express app entry point
│ │ └── package.json
│ └── web/ # React frontend (Vite + TypeScript)
│ ├── src/
│ │ ├── components/ # React components
│ │ ├── pages/ # Page components
│ │ ├── api/ # API client functions
│ │ └── main.tsx # App entry point
│ └── package.json
├── packages/
│ └── common/ # Shared types and utilities
│ └── types/ # TypeScript type definitions
├── data/ # SQLite database files (gitignored)
├── package.json # Root workspace config
├── turbo.json # Turbo build configuration
└── .prettierrc # Prettier configuration
- Engine: SQLite (via better-sqlite3)
- Query Builder: Knex.js
- Location:
data/dev.db(development),data/prod.db(production) - Migrations: Located in
apps/server/src/db/migrations/ - Seeds: Located in
apps/server/src/db/seeds/
# Run all pending migrations
npm run -w server knex migrate:latest
# Rollback last migration
npm run -w serverknex migrate:rollback
# Create a new migration
npm run -w server knex migrate:make migration_nameSeed the database with realistic fake data:
# From root directory
npm run seedWhat gets seeded:
| Data Type | Count | Description |
|---|---|---|
| Devices | 5 | Kindle, Kobo, Nook, iPad, Android Tablet |
| Books | 10 | Popular fantasy/sci-fi titles |
| Book-Device Associations | 50 | Each book on each device |
| Page Statistics | ~1,800 | Reading progress over last 100 days |
| Annotations | ~200 | Highlights, notes, and bookmarks |
| Genres | 14 | Fantasy, Sci-Fi, etc. with book associations |
| Users | 3 | Test accounts (password: password123) |
| Progress Records | ~13 | KoSync reading progress |
# Run a specific seed file
npm run -w server knex seed:run -- --specific=01_devices.ts
# Create a new seed file
npm run -w server knex seed:make new_seed_name
# View migration status
npm run -w server knex migrate:statusIf you need a fresh start:
# Delete the database
rm data/dev.db
# Run migrations
npm run -w server knex migrate:latest
# Seed with fake data
npm run seedKoInsight uses Prettier for consistent code formatting.
Prettier Configuration (.prettierrc):
Format your code:
# Format all files (from root)
npx prettier --write .
# Format specific files
npx prettier --write "apps/server/**/*.ts"
npx prettier --write "apps/web/**/*.{ts,tsx}"
# Check formatting without changing files
npx prettier --check .Editor Integration:
- VS Code Extension
- Enable "Format on Save" for automatic formatting
# Run all tests
npm run test:coverage
# Run server tests only
cd apps/server
npm test
# Run tests in watch mode
npm run test:watch
# Run with coverage report
npm run test:coverageWhen contributing code:
- Format your code with Prettier before committing
- Run tests to ensure nothing breaks
- Write tests for new features
- Update documentation if needed
- Follow existing patterns in the codebase