From ff3f99e613c97e093177ee3ee0801ae7d0cd8a4d Mon Sep 17 00:00:00 2001 From: Neon <18559658+neonsolstice@users.noreply.github.com> Date: Tue, 12 May 2026 00:54:43 -0600 Subject: [PATCH] docs: overhaul README and update repo to bookorbit org (#9) --- CONTRIBUTING.md | 2 +- README.md | 392 ++++++---------------------------------- docs/release-process.md | 6 +- 3 files changed, 57 insertions(+), 343 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2376d0af0..907b703f8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,7 +65,7 @@ This step prevents wasted effort on changes that conflict with the project direc ```bash git clone https://github.com//bookorbit.git cd bookorbit -git remote add upstream https://github.com/neonsolstice/bookorbit.git +git remote add upstream https://github.com/bookorbit/bookorbit.git ``` > **Trusted contributors** with direct push access can skip the fork and work on branches in the main repository. The rest of this guide assumes the fork workflow. diff --git a/README.md b/README.md index 392b6b5eb..0bfdde55e 100644 --- a/README.md +++ b/README.md @@ -1,381 +1,95 @@ +
+ + +BookOrbit + # BookOrbit -[![CI](https://github.com/neonsolstice/bookorbit/actions/workflows/ci.yml/badge.svg)](https://github.com/neonsolstice/bookorbit/actions/workflows/ci.yml) -[![Release](https://github.com/neonsolstice/bookorbit/actions/workflows/release.yml/badge.svg)](https://github.com/neonsolstice/bookorbit/actions/workflows/release.yml) +A self-hosted library management and reading platform for epub, pdf, audiobooks, and comics. -A self-hostable book and library management app with Kobo device support. Organize your epub, pdf, and cbz collections, track reading progress, and sync with your Kobo. +[![CI](https://github.com/bookorbit/bookorbit/actions/workflows/ci.yml/badge.svg)](https://github.com/bookorbit/bookorbit/actions/workflows/ci.yml) +[![Release](https://github.com/bookorbit/bookorbit/actions/workflows/release.yml/badge.svg)](https://github.com/bookorbit/bookorbit/actions/workflows/release.yml) +[![Latest release](https://img.shields.io/github/v/release/bookorbit/bookorbit?label=latest)](https://github.com/bookorbit/bookorbit/releases) +[![Commits/month](https://img.shields.io/github/commit-activity/m/bookorbit/bookorbit?label=commits%2Fmonth)](https://github.com/bookorbit/bookorbit/commits/main) +[![Stars](https://img.shields.io/github/stars/bookorbit/bookorbit?style=flat)](https://github.com/bookorbit/bookorbit/stargazers) +[![License: AGPL v3](https://img.shields.io/badge/License-AGPL_v3-blue.svg)](LICENSE) +[![Container image](https://img.shields.io/badge/ghcr.io-bookorbit%2Fbookorbit-informational?logo=docker&logoColor=white)](https://github.com/bookorbit/bookorbit/pkgs/container/bookorbit) + +**[Documentation](https://bookorbit.app) · [Live Demo](https://demo.bookorbit.app) · [Report a Bug](https://github.com/bookorbit/bookorbit/issues/new?template=bug_report.yml) · [Request a Feature](https://github.com/bookorbit/bookorbit/issues/new?template=feature_request.yml)** + +
--- -## Quick Start - -### Prerequisites - -| Tool | Version | Install | -| ------- | ------- | ------------------------------------------------------------ | -| Node.js | >= 24 | [nodejs.org](https://nodejs.org) | -| pnpm | >= 9 | `corepack enable && corepack prepare pnpm@latest --activate` | -| Docker | latest | [docker.com](https://www.docker.com/products/docker-desktop) | - -### Setup - -```bash -git clone bookorbit -cd bookorbit -pnpm setup -``` - -Docker is only used for PostgreSQL. The server and client run directly on your machine. - -### Start developing - -```bash -pnpm dev -``` - -This starts the NestJS server and Vue client concurrently: - -- **Client:** http://localhost:5173 -- **API:** http://localhost:3000/api - -If you prefer separate terminals (cleaner logs): - -```bash -# Terminal 1 -cd server && pnpm start:dev - -# Terminal 2 -cd client && pnpm dev -``` - -Both must be running. The client proxies all `/api` and `/socket.io` requests to the server, so API calls will fail if only the client is running. - -### First steps after setup - -1. **Complete initial setup** - you'll be redirected to `/setup` to create the first administrator account (username, password, name, and email). -2. **Create a library** - open Settings (gear icon) > Libraries > Create Library. Add a folder path pointing to some books on your machine, e.g. any directory containing `.epub`, `.pdf`, or `.cbz` files. -3. **Scan** - the library scans automatically after creation. You should see books appear on the home page once the scan completes. - -> **Where does data go?** `APP_DATA_PATH` in `server/.env` defaults to `../local/data` (resolves to `/local/data`). This is the app's data directory where extracted cover images and thumbnails are stored (`local/data/covers/`). It is **not** where your book files live - those paths are configured per-library in the UI. The `local/` folder is gitignored. +![BookOrbit dashboard showing reading stats, widgets, and book shelves](https://bookorbit.app/images/home/dashboard-overview.webp) --- -## Project Structure +## About -``` -bookorbit/ -├── client/ Vue 3 frontend (Vite + Tailwind CSS v4) -├── server/ NestJS 11 backend (Fastify + Drizzle ORM) -├── packages/ -│ └── types/ Shared TypeScript types (@bookorbit/types) -├── docker/ -│ └── postgres/ Postgres init scripts (extensions) -├── local/ Local dev data (covers, docs) - gitignored -├── docker-compose.dev.yml Dev: runs Postgres only (app runs natively) -├── docker-compose.yml Prod: app + Postgres -├── .env.example Template env file for production compose -└── Dockerfile Production multi-stage build -``` +BookOrbit is a self-hosted book and library manager. Deploy it once on your own server and get a full reading platform: built-in readers, rich metadata, reading statistics, device sync, and multi-user support - all running on your hardware. -### Monorepo layout - -This is a **pnpm workspace**. The three packages are: - -- **`server/`** - NestJS API. Modules live in `src/modules/`, one folder per feature. Database schema is in `src/db/schema/`. -- **`client/`** - Vue 3 SPA. Feature code lives in `src/features/`, shared components in `src/components/ui/`. -- **`packages/types/`** - Shared types imported as `@bookorbit/types` by both server and client. Add any type that crosses the API boundary here. +No subscription. No third-party account. No data leaving your server. --- -## Common Commands +## Live Demo -All commands run from the **repo root** unless noted otherwise. +Try BookOrbit without installing anything. The demo is pre-loaded with a sample library and resets automatically. -### Everyday workflow - -| Command | Description | -| -------------------- | --------------------------------------------------- | -| `pnpm setup` | One-time bootstrap | -| `pnpm dev` | Daily development | -| `pnpm verify` | Default local checks before push | -| `pnpm verify:fast` | Faster local checks while coding (lint + typecheck) | -| `pnpm verify:strict` | Aspirational strict gate (format + full typecheck) | - -### Development - -| Command | Description | -| ----------------------------- | ------------------------------------ | -| `pnpm dev` | Start server + client (concurrently) | -| `cd server && pnpm start:dev` | Server only (watch mode) | -| `cd client && pnpm dev` | Client only (Vite dev server) | - -### Testing - -| Command | Description | -| ------------------------------------- | ---------------------------- | -| `pnpm test` | Server + client unit tests | -| `pnpm test:server` | Server unit tests | -| `pnpm test:client` | Client unit tests | -| `pnpm run e2e:run -- guard-mechanics` | Server smoke e2e | -| `pnpm coverage` | Coverage for server + client | -| `pnpm --filter server test:e2e` | Server e2e only | - -### Database - -| Command | Description | -| ----------------------------------------- | ---------------------------------------- | -| `pnpm db:up` | Start local Postgres | -| `pnpm db:migrate` | Apply pending migrations | -| `pnpm db:seed` | Seed baseline app data | -| `pnpm db:reset` | Reset schema, migrate, and seed | -| `pnpm --filter server db:generate ` | Generate a migration from schema changes | -| `pnpm --filter server db:studio` | Open Drizzle Studio (DB browser) | - -### Production operations - -| Command | Description | -| ---------------- | ------------------------------------- | -| `pnpm prod:up` | Start/update production compose stack | -| `pnpm prod:down` | Stop production compose stack | - -### Linting & formatting - -| Command | Description | -| --------------------- | ---------------------------------- | -| `pnpm format:check` | Check formatting | -| `pnpm format` | Auto-format source files | -| `pnpm lint:check` | Non-mutating lint checks | -| `pnpm lint:fix` | Auto-fix lint issues | -| `pnpm typecheck` | Typecheck server + client | -| `pnpm typecheck:full` | Typecheck server + client (strict) | +**[Open demo](https://demo.bookorbit.app/magic?token=2d92cb900e184cf0eb8b11f72cffc6011673d1016e1b300d750eb3d76abc1572)** - no account needed, click the link to log in automatically. --- -## Development Workflow +## Features -Once `pnpm dev` is running, here's how the feedback loop works for each type of change: - -### Frontend (`client/`) - -Save a file → Vite HMR hot-swaps the module → browser updates instantly. No restart needed. - -### Backend (`server/`) - -Save a file → NestJS watch mode (SWC) recompiles and restarts the server automatically. Takes about a second. - -### Shared types (`packages/types/`) - -The types package points directly at `.ts` source files. Edit a type → both client and server pick it up on their next rebuild cycle. No build step needed. - -### Database schema - -Schema changes are the one thing that isn't automatic. See [Database Workflow](#database-workflow) for the generate + migrate steps. - -### Environment variables - -The `start:dev` script reads `server/.env` once at startup. If you change a value in `.env`, you must restart `pnpm dev` for it to take effect. - -### After `git pull` - -If other people have pushed changes, you may need to sync dependencies and migrations: - -```bash -pnpm install # pick up lockfile changes -pnpm db:migrate # apply any new migrations -``` - -### Adding a dependency - -Always install into the correct workspace, not the root: - -```bash -cd server && pnpm add # backend dependency -cd client && pnpm add # frontend dependency -``` - -### Adding a new feature - -The fastest way to learn the patterns is to follow an existing module: - -- **Backend:** Look at `server/src/modules/bookmark/` for a minimal example (controller, service, repository, DTO, module). Copy it, rename, and adapt. -- **Frontend:** Look at `client/src/features/collection/` for a full feature (composables for state/API, components for UI). -- **Shared types:** If the feature adds API request/response shapes, add them in `packages/types/src/` and import via `@bookorbit/types`. +- **4 built-in readers** - eBook (EPUB, KEPUB, MOBI, AZW3, FB2), PDF, Comics (CBZ, CBR, CB7), Audiobook (M4B, MP3, FLAC, and more) +- **Multiple libraries** with independent scan rules, format priorities, and metadata configuration +- **Collections and Smart Scopes** - curated lists and saved filters that live in your sidebar +- **Metadata from 9 providers** - Google Books, Goodreads, Hardcover, Amazon, Audible, ComicVine, and more; with field-level rules and confidence scoring +- **Reading statistics** - daily time, heatmap, streaks, pace, goal tracking, and library health +- **Kobo sync** - sideload books and sync reading position over the local network +- **OPDS, email delivery, and Book Dock** for getting books in from anywhere +- **Multi-user** with per-user permissions, isolated reading data, and OIDC/SSO support --- -## Environment Variables +## Setup -Server environment is configured in `server/.env` for local development. Production compose uses the repo-root `.env` created from `.env.example`. - -| Variable | Default | Description | -| ------------------------------- | --------------------------------------------------------- | ----------------------------------------------------------------- | -| `DATABASE_URL` | `postgres://bookorbit:bookorbit@localhost:5432/bookorbit` | PostgreSQL connection string | -| `PORT` | `3000` | Server port | -| `NODE_ENV` | `development` | Environment mode | -| `JWT_SECRET` | `change-me-in-production` | JWT signing secret | -| `SETUP_BOOTSTRAP_TOKEN` | (empty) | Required in production for initial `/api/v1/auth/setup` | -| `APP_DATA_PATH` | `../local/data` | App data directory for cover images (not where books live) | -| `APP_URL` | `http://localhost:5173` | Client URL (used in emails) | -| `CSP_ALLOW_CLOUDFLARE_INSIGHTS` | `false` | Allow Cloudflare Web Analytics beacon script/connect hosts in CSP | -| `NODE_MAX_OLD_SPACE_SIZE` | `2048` | Docker Node.js heap limit in MB | - -## Production Deploy - -Production uses the root compose file and env file: - -- Compose: `docker-compose.yml` -- Env file: `.env` (from `.env.example`) -- Image source: CI-published images (`latest`, sha tags, or digests) - -Quick start: - -```bash -cp .env.example .env -# edit .env and set secrets, APP_URL, BOOKS_HOST_PATH, and optionally APP_IMAGE -pnpm prod:up -``` - -For production compose, `BOOKS_HOST_PATH` is the only host folder most users need to choose. It is mounted as `/books` in the container, and library paths created in the UI should point under `/books`. - -Generated app data and PostgreSQL live in explicit folders beside the compose file: - -```text -./data/app generated covers, author images, staging files, and Book Dock uploads -./data/postgres PostgreSQL data -``` - -The container starts as root only long enough to create/chown app-managed data paths, then runs the Node process as `PUID:PGID`. - -On NAS installs, set `PUID` and `PGID` to the user/group that should own app-generated files: - -```bash -id your-media-user -``` - -Do not add a compose `user:` override unless your platform requires it; that bypasses the startup permission repair. - -The app container defaults Node's JavaScript heap limit to 2048 MB. Set `NODE_MAX_OLD_SPACE_SIZE` in `.env` if the host needs a lower or higher limit. +See the **[Installation guide](https://bookorbit.app/installation.html)** for Docker setup, NAS installs, environment variables, and upgrade instructions. --- -## Database Workflow +## Documentation -The database schema is defined in `server/src/db/schema/` using Drizzle ORM. Each domain has its own schema file (e.g. `books.ts`, `libraries.ts`, `auth.ts`). +Full documentation is at **[bookorbit.app](https://bookorbit.app)**. -**Making schema changes:** - -1. Edit the relevant file in `server/src/db/schema/` -2. Generate a migration: `pnpm --filter server db:generate describe_your_change` -3. Apply it: `pnpm db:migrate` - -Never hand-write migration SQL. Always generate from schema diffs. - -### Resetting the database from scratch - -```bash -pnpm db:reset -``` +> [What is BookOrbit?](https://bookorbit.app/what-is-bookorbit.html)  ·  [Installation](https://bookorbit.app/installation.html)  ·  [Creating a Library](https://bookorbit.app/creating-a-library.html)  ·  [Metadata](https://bookorbit.app/metadata.html)  ·  [Kobo Sync](https://bookorbit.app/kobo.html)  ·  [Users & Permissions](https://bookorbit.app/users.html) --- -## Architecture Overview +## Developing -``` -┌──────────────┐ ┌──────────────────────┐ ┌────────────┐ -│ Vue 3 SPA │──────>│ NestJS API (/api) │──────>│ PostgreSQL │ -│ port 5173 │<──────│ port 3000 │<──────│ port 5432 │ -└──────────────┘ └──────────────────────┘ └────────────┘ - │ │ - │ WebSocket │ Drizzle ORM - │ (socket.io) │ (schema in src/db/schema/) - └────────────────────────┘ -``` - -- **Backend:** NestJS 11 on Fastify. Global prefix `/api`. Auth via JWT (access + refresh tokens in httpOnly cookies). RBAC with permissions system. -- **Frontend:** Vue 3 Composition API (`