A full-stack RAG (Retrieval-Augmented Generation) app that lets you search and ask questions about any EPUB book using AI.
- Place an EPUB file in
server/data/books/ - Send a request to process the book — it gets parsed, chunked, and vectorized
- Ask questions in natural language via the UI
- Get AI-generated answers with references to the source chapters
epub-rag/
├── server/ # Node.js + TypeScript REST API
├── client/ # Vanilla TypeScript + Vite PWA
└── README.md
- Node.js v20+
- An OpenAI API key
- An EPUB file
cd server
npm installCreate a .env file in the server/ directory:
OPENAI_API_KEY=sk-your-key-here
PORT=3000
Place your EPUB file in server/data/books/.
npm run dev # development with hot reload
npm run build # compile to dist/
npm start # run compiled buildcurl -X POST http://localhost:3000/api/books \
-H "Content-Type: application/json" \
-d '{"filename": "fileName.epub"}'Response:
{
"success": true,
"bookId": "bookId",
"chapters": 31,
"chunks": 219
}curl -X POST http://localhost:3000/api/search \
-H "Content-Type: application/json" \
-d '{"query": "your question?", "bookId": "bookId"}'Response:
{
"answer": "...",
"sources": [
{
"chapterTitle": "...",
"content": "..."
}
]
}cd client
npm installnpm run dev # development server at http://localhost:5173
npm run build # production build to dist/
npm run preview # preview production buildThe client proxies all /api requests to http://localhost:3000 automatically in development.
In client/index.html, add a new option to the select element:
<option value="YourBookId">Your Book Title</option>The value must match the bookId returned when processing the book (filename without .epub).
server/
├── src/
│ ├── index.ts # Express app entry point
│ ├── routes/
│ │ ├── books.ts # POST /api/books
│ │ └── search.ts # POST /api/search
│ └── services/
│ ├── epub.ts # EPUB parsing + chunking
│ ├── embeddings.ts # OpenAI vectorization
│ ├── vectorstore.ts # Vectra local vector DB
│ └── rag.ts # Search + AI answer generation
└── data/
├── books/ # place your .epub files here
└── indexes/ # vector indexes stored here automatically
client/
├── src/
│ ├── main.ts # Entry point, form handling
│ ├── api.ts # Fetch wrapper for backend
│ ├── ui.ts # DOM rendering
│ ├── types.ts # TypeScript interfaces
│ └── style.css # Styles
└── index.html