Upload a PDF and chat with it. This repo contains a Rust backend API that ingests PDFs into an in-memory vector store (per session) and a React + Vite + Tailwind frontend that lets users upload a PDF, preview it, and ask questions against the uploaded content.
Primary use cases
- Personal “chat with a PDF” for reports, specs, ebooks, and papers
- Lightweight prototype for RAG-style PDF Q&A (session-scoped, single process)
Key features
- PDF ingestion (text extraction → chunking → embeddings)
- Semantic retrieval using cosine similarity + LLM answer generation (DeepSeek API)
- Session isolation (
session_id) so users don’t see each other’s documents - Dev-friendly CORS configuration for local frontends
be/— Rust (Axum) backend APIfe/— React (Vite) frontendscreenshots/— UI screenshots used in this README
- Rust: 1.85+ (required for
edition = "2024") - Network access:
- DeepSeek API calls (requires
DEEPSEEK_API_KEY) - FastEmbed model download/cache on first run
- DeepSeek API calls (requires
- Hardware (recommended): 8GB+ RAM (PDF extraction + embedding can be memory heavy)
- Bun (recommended): 1.0+
- Alternatively, Node.js: 18+ (if you prefer npm; project scripts are compatible)
- Modern browser: Chrome / Firefox / Safari / Edge
- Network access: PDF.js is loaded from a CDN at runtime
macOS / Linux
git clone <YOUR_REPO_URL>
cd pdf-chatWindows (PowerShell)
git clone <YOUR_REPO_URL>
cd pdf-chatCopy the backend environment template and set your API key.
macOS / Linux
cp be/.env.sample be/.envWindows (PowerShell)
Copy-Item be\.env.sample be\.envEdit be/.env and set:
DEEPSEEK_API_KEY=...
Optional:
PORT=8080BIND_ADDR=0.0.0.0:8080CORS_ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000CORS_ALLOW_CREDENTIALS=false
Run the backend:
macOS / Linux
cd be
cargo runWindows (PowerShell)
cd be
cargo runBackend default URL: http://localhost:8080
Copy the frontend environment template and point it to your backend URL:
macOS / Linux
cp fe/.env.sample fe/.envWindows (PowerShell)
Copy-Item fe\.env.sample fe\.envEdit fe/.env:
VITE_BASE_URL_API=http://localhost:8080Install dependencies and run:
Bun (recommended)
cd fe
bun install
bun run devFrontend default URL (Vite): http://localhost:5173
- Open the frontend in the browser.
- Click Upload PDF and select a PDF file (max size is enforced by the UI).
- After upload finishes, use the chat panel to ask questions about the PDF.
All user data isolation is session-based. Use the same session_id for upload and subsequent queries.
Ingest a PDF
curl -X POST "http://localhost:8080/ingest?session_id=my-session" \
-F "file=@/path/to/document.pdf"Ask a question
curl -X POST "http://localhost:8080/query?session_id=my-session" \
-H "Content-Type: application/json" \
-d '{"question":"Summarize the main points."}'For full backend endpoint details, see:
be/README.md
Located in be/.env:
DEEPSEEK_API_KEY(required): DeepSeek API keyPORT(optional): port number (default8080)BIND_ADDR(optional): bind address (default0.0.0.0:{PORT})CORS_ALLOWED_ORIGINS(optional): comma-separated list of allowed origins (or*)CORS_ALLOW_CREDENTIALS(optional):true/false(only works with explicit origins, not*)
Located in fe/.env:
VITE_BASE_URL_API(required): backend base URL (e.g.http://localhost:8080)
- Rust: format with
cargo fmt, lint withcargo clippy - Frontend:
bun run lint, and format withbun run format - Don’t commit secrets (
.envfiles should stay local)
- Create a branch:
feat/<name>orfix/<name> - Keep changes scoped and well-described
- Ensure builds pass:
cd be && cargo checkcd fe && bun run build
- Open a PR with:
- What changed
- Why it changed
- How to test it
When filing a bug, include:
- Steps to reproduce
- Expected vs actual behavior
- Screenshots / screen recordings (if UI-related)
- Environment: OS, browser, Node/Bun version, Rust version
- Relevant logs (browser console + backend logs)
Be respectful, assume good intent, and keep feedback constructive. Harassment and discrimination are not tolerated.
No license file is included in this repository yet. Until a license is added, assume “all rights reserved” by the author(s).
If you want this to be open source, add a LICENSE file (e.g. MIT/Apache-2.0) and update this section accordingly.
- Ensure the frontend origin (e.g.
http://localhost:5173) is included inCORS_ALLOWED_ORIGINSinbe/.env - Restart the backend after updating env vars
- Another process is already using the port.
- Stop the running process or change the port:
PORT=8081 cargo run
Common causes:
- Backend CORS mismatch (see above)
- Request timeout (PDF ingestion and LLM calls can take time)
- Set
DEEPSEEK_API_KEYinbe/.envand restart the backend.
- FastEmbed may download a model on first use and cache it locally.
- Maintainer: (Hamam)
- Contact: (zero.saturnus@gmail.com)
