Skip to content

Repository files navigation

▌▌ PresentPDF

A local-first PDF presentation tool.

Upload a PDF → get a dual-window presenter with a fullscreen view and a controller — all running 100% in your browser.

Next.jsReactDockerLicense


⚡ What is PresentPDF?

PresentPDF turns any PDF into a full-screen, keyboard-navigable presentation — with a separate control panel for the presenter and a present view for the audience. No file uploads to a server; everything stays in the browser using IndexedDB.


✦ Features

FeatureDescription
Drag & Drop UploadLand on the homepage, drop a PDF, and you're in
Dual-Window ModeOpen /present on the projector and /control on your laptop — they stay in sync
Smart BackgroundThe present view samples the PDF's edge colors and adapts the page background to match
Keyboard NavigationArrow keys navigate slides from either window
Local-Only StoragePDFs are stored in the browser via localforage / IndexedDB — nothing leaves your machine
High-Fidelity Rendering2× supersampled canvas rendering via react-pdf for crisp text and vectors
Pre-RenderingPages around the current slide are rendered ahead of time for instant transitions

🏗 Architecture

┌────────────────────────────────────────────────────┐
│ Browser (Same Origin) │
│ │
│ ┌──────────┐ BroadcastChannel ┌────────────┐ │
│ │ /control │ ◄──────────────────► │ /present │ │
│ │ (laptop) │ slide sync │ (projector)│ │
│ └────┬─────┘ └─────┬──────┘ │
│ │ │ │
│ └──────────┐ ┌──────────────────┘ │
│ ▼ ▼ │
│ ┌──────────────┐ │
│ │ IndexedDB │ │
│ │ (localforage)│ │
│ └──────────────┘ │
└────────────────────────────────────────────────────┘

Routes

RoutePurpose
/Landing page — drag-and-drop PDF upload
/control?id=<uuid>Presenter control panel with live preview, slide counter, and navigation
/present?id=<uuid>Fullscreen audience view with adaptive background

🚀 Getting Started

Prerequisites

  • Node.js ≥ 20
  • npm ≥ 9

Install & Run (Development)

# Clone the repo
git clone https://github.com/iamcoder18/PresentPDF
cd PresentPDF
# Install dependencies
npm install
# Start the dev server
npm run dev

Open http://localhost:3000 and drop a PDF.

Production Build

npm run build
npm start

🐳 Docker

Quick Start

# Build and run with Docker Compose
docker compose up --build
# Or build the image directly
docker build -t presentpdf .
docker run -p 3000:3000 presentpdf

The app will be available at http://localhost:3000.

Docker Compose

The included docker-compose.yml provides:

  • Port mapping (3000:3000)
  • Health check (auto-restarts if unhealthy)
  • restart: unless-stopped policy
# Start in background
docker compose up -d
# View logs
docker compose logs -f
# Stop
docker compose down

📁 Project Structure

PresentPDF/
├── src/
│ ├── app/
│ │ ├── page.tsx # Landing page (upload)
│ │ ├── layout.tsx # Root layout (Space Mono font)
│ │ ├── globals.css # Tailwind + brutalist theme tokens
│ │ ├── control/page.tsx # Presenter control panel
│ │ └── present/page.tsx # Fullscreen presentation view
│ ├── components/
│ │ ├── pdf/PDFViewer.tsx # Core PDF renderer (react-pdf)
│ │ └── ui/button.tsx # Shadcn button component
│ ├── hooks/
│ │ └── useSyncState.ts # BroadcastChannel sync hook
│ └── lib/
│ ├── storage.ts # localforage PDF persistence
│ └── utils.ts # Utility helpers
├── Dockerfile # Multi-stage production build
├── docker-compose.yml # Compose orchestration
├── .dockerignore # Build context exclusions
├── next.config.ts # Next.js config (standalone output)
├── package.json
└── tsconfig.json

🛠 Tech Stack

LayerTechnology
FrameworkNext.js 16 (App Router)
UIReact 19
PDF Enginereact-pdf + pdf.js
StylingTailwind CSS 4 + Shadcn UI
Storagelocalforage (IndexedDB)
Cross-Tab SyncBroadcastChannel API
FontSpace Mono (Google Fonts)

📄 License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages