███████╗██╗ ██╗███████╗██████╗ ███████╗███████╗████████╗
██╔════╝╚██╗ ██╔╝██╔════╝██╔══██╗██╔════╝██╔════╝╚══██╔══╝
███████╗ ╚████╔╝ █████╗ ██████╔╝█████╗ ███████╗ ██║
╚════██║ ╚██╔╝ ██╔══╝ ██╔══██╗██╔══╝ ╚════██║ ██║
███████║ ██║ ███████╗██║ ██║███████╗███████║ ██║
╚══════╝ ╚═╝ ╚══════╝╚═╝ ╚═╝╚══════╝╚══════╝ ╚═╝
Presentation Generator
AI-Powered Presentation Generator — Turn any topic into a polished, editable, AI-themed slide deck in seconds. Pure HTML, CSS, and vanilla JavaScript. Zero frameworks. Zero build tools. Zero servers.
| Build | |
| Version | |
| License | |
| Dependencies | |
| Size | |
| Platform |
Live demo: vincenzo-afk.github.io/SlideForge · Source · Report a bug · Request a feature
- About the Project
- Tech Stack
- Getting Started
- Usage
- Configuration Reference
- Project Structure
- Features & Roadmap
- Testing
- Deployment
- Contributing
- Security
- License
- Acknowledgments
- Contact & Support
SlideForge is a fully client-side presentation generator. You type a topic — "The history of space exploration", "Startup pitch for an AI fitness coach" — and the app calls an AI model to produce a complete slide deck: titles, concise bullets, speaker notes, and a color theme matched to the subject. Every element is editable inline, decks are saved in your browser, and exports land as PDF or native PPTX files — all generated in the browser with hand-written code.
Most AI presentation tools require accounts, subscriptions, and closed ecosystems, and most open-source decks are built with heavy JavaScript frameworks and build pipelines that scare away non-developers. SlideForge sits at the opposite end of the spectrum: it is a single folder of plain files that anyone can open, read, modify, and host for free. There is nothing to install and nothing to compile — if you can open a web page, you can use SlideForge.
| Feature | Description |
|---|---|
| 🧠 AI content generation | Titles, bullets, and speaker notes generated from a single topic prompt |
| 🎨 AI theme selection | The model picks an accent palette and font pairing matched to the topic, with five built-in fallback themes |
| ✏️ Inline editing | Click ✎ Edit and change any text on any slide; changes persist automatically via localStorage |
| ➕ Slide management | Add, duplicate, delete, and reorder slides with one click |
| 📄 PDF export | Styled print layout at 1280×720, one click, speaker notes included |
| 📊 PPTX export | Native OOXML PowerPoint file generated by hand-written ZIP + XML code — no libraries |
| 💾 Offline-ready decks | Saved decks re-open instantly from browser storage |
| 🔍 SEO-optimized | Semantic HTML5, Open Graph, Twitter cards, JSON-LD structured data, sitemap, robots.txt |
| 📱 Responsive | Works on desktop, tablet, and mobile browsers |
| ⌨️ Keyboard navigation | Arrow keys and Page Up/Down move between slides |
The app follows a minimal module pattern. Five self-contained scripts (no bundler, no imports, no build step) cooperate through explicit global namespaces:
┌─────────────┐ ┌──────────┐ ┌───────────┐
│ app.js │────▶│ ai.js │────▶│ LLM API │
│ (routing, │ │ (prompts,│ │(Gemini / │
│ events) │ │ parsing)│ │ OpenAI) │
└──────┬──────┘ └──────────┘ └───────────┘
│
▼
┌─────────────┐ ┌───────────┐
│ slides.js │◀───▶│ editor.js │ ┌───────────┐
│ (render, │ │ (edit, │──▶│ localStorage
│ theme) │ │ persist) │ └───────────┘
└──────┬──────┘ └───────────┘
│
▼
┌─────────────┐
│ export.js │ ──▶ PDF (print) | PPTX (OOXML ZIP)
└─────────────┘
All data flows through one deck model: { id, topic, slides[], theme{} }. The render engine is stateless — it rebuilds the DOM from the model on every navigation, which keeps editing, persistence, and export trivially consistent.
SlideForge deliberately avoids frameworks and tooling. The entire application is hand-written and ships as static files.
| Layer | Technology | Notes |
|---|---|---|
| Markup | HTML5 | Semantic tags, ARIA roles, alt text on every image |
| Styling | CSS3 | Custom properties (design tokens), media queries, print stylesheet; no preprocessors |
| Logic | Vanilla JavaScript (ES5-compatible) | IIFE module pattern; no import/export, no transpilation |
| AI backend | Google Gemini REST API (default) or any OpenAI-compatible endpoint | Optional free tier; key stored in js/config.js |
| PPTX generation | Hand-written OOXML + store-compressed ZIP (CRC-32) | Zero libraries — JSZip and similar are not used |
| Persistence | localStorage |
Up to 10 recent decks |
| Hosting | GitHub Pages (or any static host) | No server required |
| Testing | Headless test harness (Node vm + shims) |
Functional tests for AI parsing, editing, and export |
Dependencies: 0. There is no package.json, no node_modules, no CDN script tag, no build script. The only runtime requirement is a modern browser with fetch support.
SlideForge has essentially no prerequisites. The table below lists everything you might need, and only the API key is mandatory for generation to work.
| Requirement | Minimum | Purpose |
|---|---|---|
| Web browser | Any modern browser (Chrome, Firefox, Safari, Edge) | Runs the app |
| Text editor | Any | Editing js/config.js |
| Gemini API key | Free, from Google AI Studio | AI slide generation (default provider) |
| (Optional) OpenAI-compatible key | Groq, OpenRouter, OpenAI, LocalAI, ... | Alternative provider |
No Node.js, no Python, no npm — those are only needed if you want to run the headless test suite (node test/run_headless.js).
1. Download or clone the repository
git clone https://github.com/vincenzo-afk/SlideForge.git
cd SlideForge2. Open it
# Option A — direct open (works in most browsers)
open index.html
# Option B — local static server (recommended, avoids CORS quirks)
python3 -m http.server 8000
# then visit http://localhost:8000That is the entire installation. There is no build step.
Open js/config.js and paste a key. A free Gemini key takes about 60 seconds to obtain:
- Visit Google AI Studio → API keys
- Sign in with a Google account
- Click Create API key
- Paste the key into
GEMINI_API_KEYinjs/config.js
var SlideForgeConfig = {
PROVIDER: "gemini", // "gemini" | "openai"
GEMINI_API_KEY: "AIza...", // ← paste here
GEMINI_MODEL: "gemini-2.5-flash",
// ...or for OpenAI-compatible endpoints:
OPENAI_API_KEY: "",
OPENAI_BASE_URL: "https://api.openai.com/v1",
OPENAI_MODEL: "gpt-4.1-mini"
};Deploy the whole folder to any static host — GitHub Pages, Netlify, Vercel, Cloudflare Pages, or an S3 bucket. The deployment section below covers each option.
- Open the site (locally or at the live demo URL)
- Type a topic, e.g. "How photosynthesis works"
- Optionally set slide count, audience, and tone
- Click Forge Slides ⚡
- Navigate with arrow keys or the toolbar buttons
- Click ✎ Edit to change any text — edits save automatically
- Export with ⤓ PDF or ⮳ PPTX
| Prompt | Result |
|---|---|
World War II timeline and key battles |
History deck with chronological content slides |
Startup pitch: AI-powered fitness coach |
Business pitch with title, problem, solution, market, close |
Introduction to quantum computing for beginners |
Educational deck matched to a general audience |
Quarterly sales review, 10 slides, professional tone |
Formal deck with elevated vocabulary |
The editor toolbar provides full deck management without leaving the presentation view.
| Action | How |
|---|---|
| Edit text | Click ✎ Edit, then click any title, bullet, or note and type |
| Add a slide | Click + Slide — inserted after the current slide |
| Duplicate | Use the duplicate button in the toolbar (reorders safely) |
| Reorder | ▲ / ▼ buttons move the current slide |
| Delete | 🗑 button (minimum 3 slides enforced) |
| Switch theme | ⚙ Theme cycles through the five built-in fallback palettes |
| Key | Action |
|---|---|
→ / PageDown |
Next slide |
← / PageUp |
Previous slide |
Escape |
Toggle edit mode |
Because every module is a plain <script> file, the AI engine can be reused outside the UI. Load the scripts in order and call the engine directly:
// After loading config.js, ai.js (order matters)
var deck = await SlideForgeAI.generateDeck("Photosynthesis", {
slideCount: 6,
audience: "middle school students",
tone: "educational"
});
console.log(deck.slides.length); // 6
console.log(deck.theme.accent); // e.g. "#16a34a"For server-side or non-browser use, the prompt format is documented in js/ai.js — the system prompt and JSON schema are plain strings and can be reused with any LLM SDK.
All configurable values live in js/config.js. There are no other config files and no .env files — the design goal is one file, one glance.
| Variable | Type | Default | Description |
|---|---|---|---|
PROVIDER |
"gemini" | "openai" |
"gemini" |
Which AI backend to call |
GEMINI_API_KEY |
string | "" |
Gemini API key (required when PROVIDER === "gemini") |
GEMINI_MODEL |
string | "gemini-2.5-flash" |
Gemini model ID |
OPENAI_API_KEY |
string | "" |
Key for any OpenAI-compatible endpoint |
OPENAI_BASE_URL |
string | "https://api.openai.com/v1" |
Base URL of the compatible API |
OPENAI_MODEL |
string | "gpt-4.1-mini" |
Model ID on the compatible endpoint |
REPO_URL |
string | "https://github.com/vincenzo-afk/SlideForge" |
Destination of the "View on GitHub" button |
APP_NAME |
string | "SlideForge" |
Application name used in exports |
STORAGE_KEY |
string | "slideforge.decks.v1" |
localStorage key for saved decks (bump to migrate) |
To use an OpenAI-compatible endpoint (Groq, OpenRouter, LocalAI, LM Studio, vLLM):
var SlideForgeConfig = {
PROVIDER: "openai",
OPENAI_API_KEY: "gsk_...",
OPENAI_BASE_URL: "https://api.groq.com/openai/v1",
OPENAI_MODEL: "llama-3.3-70b-versatile",
// Gemini settings can be left blank
GEMINI_API_KEY: "",
GEMINI_MODEL: ""
};Any endpoint that implements the OpenAI chat-completions schema works, including self-hosted models behind LocalAI or LM Studio — which makes SlideForge usable with no third-party API at all.
SlideForge/
├── index.html # Single-page app: landing + editor views, all SEO tags
├── README.md # This file
├── LICENSE # MIT
├── CONTRIBUTING.md # Contribution guidelines
├── SECURITY.md # Security policy and vulnerability reporting
├── robots.txt # Search-engine crawl rules
├── sitemap.xml # XML sitemap for indexing
├── test/
│ └── run_headless.js # Headless functional test suite (Node, zero deps)
├── css/
│ └── style.css # All styles: design tokens, themes, print, responsive
├── js/
│ ├── config.js # ⚙ The ONLY config file — API keys & app settings
│ ├── ai.js # LLM prompts, provider calls, JSON extraction, validation
│ ├── slides.js # Deck model, DOM render engine, theme application
│ ├── editor.js # Inline editing, slide CRUD, localStorage persistence
│ ├── export.js # PDF (print) + hand-rolled PPTX (OOXML ZIP) generator
│ └── app.js # Routing, form handling, keyboard nav, example chips
└── assets/
├── logo.png # Project logo (brand mark used across the site)
├── logo-512.png # 512px square variant for hero & app icons
├── og-image.png # 1200×630 Open Graph share card
├── favicon.ico # Multi-size favicon
└── favicon-*.png # PNG favicons (16/32/64/180px, incl. Apple touch icon)
Key files explained
| File | Role |
|---|---|
index.html |
The entire application shell. Contains the landing view, the editor view, all meta/OG/JSON-LD tags, and the script loading order |
js/config.js |
The single source of truth for API keys and app constants |
js/ai.js |
The intelligence layer: prompt engineering, response normalization, and robust JSON extraction that tolerates markdown fences and conversational filler |
js/slides.js |
The render engine. Pure function of (deck, index) → DOM; theming is applied through CSS custom properties |
js/export.js |
The most technically dense module — a from-scratch ZIP writer (CRC-32, local + central directory headers) emitting valid OOXML |
test/run_headless.js |
The test suite: shims fetch/localStorage/DOM, then exercises generation, parsing, editing, persistence, and PPTX output |
| Feature | Status |
|---|---|
| AI slide content generation (titles, bullets, notes) | ✅ Done |
| AI-chosen visual theme with fallback palette cycle | ✅ Done |
| Inline WYSIWYG editing with auto-save | ✅ Done |
| Add / duplicate / delete / reorder slides | ✅ Done |
| PDF export (1280×720 print layout) | ✅ Done |
| PPTX export (hand-written OOXML, no libraries) | ✅ Done |
Recent decks saved in localStorage |
✅ Done |
| Keyboard navigation (arrows, PageUp/Down, Escape) | ✅ Done |
| "View on GitHub" repository button | ✅ Done |
| Full SEO layer (OG, Twitter, JSON-LD, sitemap, robots.txt) | ✅ Done |
| Responsive layout (desktop, tablet, mobile) | ✅ Done |
| Gemini + OpenAI-compatible provider support | ✅ Done |
| Feature | Priority |
|---|---|
| Image slides (AI-generated illustrations via Pollinations.ai) | High |
| Theme gallery with one-click template selection | High |
| Deck sharing via URL-encoded state | Medium |
| Speaker-notes presenter view with timer | Medium |
| Markdown input mode (paste notes → slides) | Medium |
| Dark/light UI toggle for the app chrome | Low |
| Service worker for offline use | Low |
SlideForge's PPTX exporter covers standard title/content/closing layouts; complex shapes, embedded charts, and smart-art are out of scope for v1 and appear as plain text slides. Browser-generated PDFs depend on the client's print engine, so exact pagination varies slightly between browsers. Because the API key lives in js/config.js (a deliberate zero-backend design decision), keyless public deployments should use a scoped/free-tier key or route requests through a small proxy.
SlideForge ships a dependency-free functional test suite that runs in Node using the built-in vm module — no test framework, no install.
node test/run_headless.jsThe suite shims just enough browser API (fetch, localStorage, DOM, Blob) to exercise the real source files, then verifies:
| Test | What it checks |
|---|---|
T1 — generateDeck |
AI response is parsed into a valid deck with correct slide count, titles, and normalized theme |
T2 — extractJSON |
JSON extraction tolerates markdown fences, conversational filler, and rejects garbage |
| T3 — persistence | Decks round-trip through localStorage correctly |
| T4 — PPTX export | A .pptx file is produced and downloaded with a sane filename |
A second harness (test/validate_pptx.js pattern) generates a real PPTX and opens it with standard ZIP tools to confirm structural validity, including XML escaping of <, >, and & characters.
Before every release, verify in a real browser: deck generation with a live key, inline editing with refresh persistence, PDF export in the print dialog, PPTX opening in PowerPoint/Google Slides/Keynote, mobile layout below 640px, and keyboard navigation.
There is intentionally no CI configuration in v1 — the project's selling point is no tooling. The test file doubles as living documentation of how the modules compose. CI via GitHub Actions is on the roadmap (see above).
SlideForge is a static site, so every deployment option below simply serves the repository folder.
The repository is already published at vincenzo-afk.github.io/SlideForge. To reproduce:
- Push the code to the
mainbranch (this repo) - Go to Settings → Pages
- Set Source to Deploy from a branch, branch
main, folder/ (root) - Save — the site is live within a minute
netlify deploy --prod --dir=.Or connect the GitHub repository in the Netlify dashboard; the publish directory is the repo root and the build command is empty.
vercel --prodUse framework preset Other, output directory ., and no build command.
Connect the repository with build directory / and no build command. Cloudflare's CDN then serves the site globally with HTTPS automatically.
Copy the folder to your document root. Nginx/Apache/Caddy serve it as-is; no configuration is required beyond standard static-file hosting. For the PDF print feature to work cleanly, serve over HTTPS when sharing the site publicly.
For containerized hosting, one line suffices:
FROM nginx:alpine
COPY . /usr/share/nginx/htmldocker build -t slideforge . && docker run -p 8080:80 slideforgeContributions are welcome. Because the project has no build step, contributing is unusually frictionless: edit a file, open index.html, verify, commit.
- Fork the repository and clone your fork
- Create a branch:
git checkout -b feature/your-feature(usefix/,docs/, orfeature/prefixes) - Make your changes — remember the core constraint: no frameworks, no npm, no build tools, no CDN dependencies
- Run the tests:
node test/run_headless.js - Open the site in a browser and perform the manual QA checklist
- Commit and push, then open a pull request against
main
Follow Conventional Commits:
feat: add theme gallery
fix: escape XML entities in PPTX bullet text
docs: update deployment section
test: add PPTX structural validation
Describe what changed and why, link any related issue, and confirm the test suite passes. UI changes should include before/after screenshots. Keep PRs focused — one concern per pull request.
Plain ES5-compatible JavaScript with the existing IIFE module pattern; two-space indentation; descriptive var names (no let/const/arrow functions is a style preference, not a rule — consistency with the surrounding file matters most). CSS uses the design-token variables defined at the top of style.css.
Be respectful and constructive. Harassment, spam, or bad-faith contributions will not be tolerated. This project follows the spirit of the Contributor Covenant.
Do not open a public issue for security problems. Email itsmebk2007@gmail.com with details, or use GitHub's private vulnerability reporting if available. You will receive an acknowledgment within 48 hours.
SlideForge is a static site with no backend, no database, and no user accounts, which keeps the attack surface minimal. Three deliberate design decisions shape its security model:
| Decision | Rationale | Mitigation |
|---|---|---|
API key in js/config.js |
Zero-backend simplicity; no server to compromise | Use scoped/free-tier keys; rotate if exposed; production deployments should proxy |
localStorage persistence |
No server-side data storage at all | Deck data never leaves the user's browser |
| Hand-rolled export code | No third-party library supply-chain risk | Export code is fully auditable (one file, ~300 lines) |
Additionally, all user and AI-generated content is HTML-escaped before DOM insertion and XML-escaped before PPTX emission, preventing injection in both render and export paths. The site ships with a strict robots.txt allow policy and no external trackers or analytics scripts.
There are zero runtime dependencies to scan. The only external services contacted at runtime are the AI API endpoints configured in config.js (defaults: generativelanguage.googleapis.com for Gemini).
This project is licensed under the MIT License — see the LICENSE file for the full text.
MIT License
Copyright (c) 2026 Vincenzo AFK
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction...
In short: use it, modify it, redistribute it, commercially or otherwise — just keep the license notice.
Built & maintained by Vincenzo AFK.
SlideForge stands on the shoulders of open standards: the OOXML specification for PowerPoint generation, the ZIP application note for archive structure, and Schema.org for structured data.
The project logo is a custom mark created for SlideForge. Thanks to the early reviewers and friends whose feedback shaped the feature set, and to the open-source community that keeps zero-dependency development alive.
| Channel | Link |
|---|---|
| Source code | github.com/vincenzo-afk/SlideForge |
| Live demo | vincenzo-afk.github.io/SlideForge |
| Issues & bug reports | Issues tab |
| itsmebk2007@gmail.com | |
| GitHub profile | github.com/vincenzo-afk |
Built with ❤️ by Vincenzo AFK