Note This guide is based on the
mainbranch of the GitHub repository (v0.13.3 per the CHANGELOG, 2026-10-02). There is no official release (tags or installers) yet; you get it withgit clone. For an overview of the app, see /apps/nexa-slide.
Overview
Nexa Slide is a local web service for building PowerPoint decks together with an AI (LLM) session. When you start a small web server on your PC, a slide editor (Studio) opens in your browser, and a Claude Code session opened in the same folder writes drafts or edits slides based on the requests you leave in the editor.
- A single deck JSON is the source of truth. The browser view (
render.js) and the PPTX converter (export_pptx.py) each draw it using the same rules. - It produces editable PPTX files. Slides are not baked into images; they are exported as native PowerPoint shapes such as text boxes, shapes, tables, connectors, and groups, so you can keep editing them in PowerPoint.
- Differences between the screen and PowerPoint are verified numerically (pixel comparison with
compare.py, JS↔Python result comparison withcheck_parity.py). - The server uses only the Python standard library (no external web framework, CDN, or npm). Only PPTX generation requires
python-pptx. - It includes 15 design templates, 21 purpose-specific starter contents (15 template types + 6 hand-written examples), and 54 slide types.
How the AI Connection Works
Nexa Slide itself does not call any LLM API and does not take an API key. Instead, a session of the AI coding tool you use (recommended: Claude Code) reads and edits the files in the workspace.
Editor ──(leave request notes · send)──▶ decks/<deck>.requests.json
│
watch_requests (request watcher started by the AI session)
│ ├─ heartbeat → editor header "Session connected"
│ └─ request batch → notifies the AI session
▼
AI session ──▶ working → edit deck JSON → done + reply
│
editor reloads the changed deck within 2 seconds
- In the editor, select an element or area, leave a request note such as “Split this table into two slides,” and send it.
- The request watcher (
watch_requests) started by the AI session passes the request to the session. - When the AI edits the deck file, marks the request “done,” and leaves a reply, the editor automatically shows the new content.
The CLAUDE.md (for Claude Code) and AGENTS.md (for Codex CLI, Gemini CLI, Cursor, etc.) files created with the workspace describe this handling protocol and the commands, so the AI follows them as written.
Requirements
| Component | Required? | Used for |
|---|---|---|
| Python 3.10 or later | Required | Server, build, and export — everything |
python-pptx (1.0 or later) | Required | PPTX export |
Pillow (10.0 or later) | Recommended | Precise text width measurement, compare.py image comparison |
| git | Required | Getting the engine (git clone) |
| AI coding tool | Required (for the AI connection) | Recommended: Claude Code (terminal, VS Code extension, Claude Desktop). Codex CLI, Gemini CLI, Cursor, and others can also be connected |
| Chrome or Edge | Recommended | Editor view, compare.py headless capture |
| Node.js 18 or later | Optional | check_parity.py, Mermaid diagram rendering (render_mermaid.py) |
| PowerPoint + PowerShell (Windows) | Optional | Editor “PowerPoint render preview”, PPTX with embedded fonts |
- Operating systems: the server, editor, build, and PPTX export all work on Windows, macOS, and Linux. Only the PowerPoint render preview, PPTX with embedded fonts, and the PowerPoint side of
compare.pyare Windows-only. - To use Claude Code, you need an account that can use Claude Code (separate from Nexa Slide).
Caution On Windows, depending on how Python was installed, the
python3command may not exist or may redirect to the Microsoft Store. Replacepython3in this guide withpy -3orpython. In Git Bash,pythonmay be a different wrapper, so use the Python that haspython-pptxinstalled.
Installation
Keep a single copy of the engine on your PC, and keep slide content separately in workspace folders outside the engine.
macOS / Linux
mkdir -p ~/Projects && cd ~/Projects
git clone https://github.com/SosomLab/nexa-slide.git
python3 -m pip install --user -r nexa-slide/requirements.txt
python3 -c "import pptx, PIL; print('ok')" # you're ready once it prints ok
Windows (PowerShell)
New-Item -ItemType Directory -Force D:\Projects | Out-Null; Set-Location D:\Projects
git clone https://github.com/SosomLab/nexa-slide.git
python3 -m pip install -r nexa-slide\requirements.txt # if python3 is missing: py -3 -m pip …
python3 -c "import pptx, PIL; print('ok')"
Note To use a virtual environment, run
python3 -m venv ~/.venvs/nexa && source ~/.venvs/nexa/bin/activateon macOS orpy -3 -m venv $HOME\.venvs\nexa; & $HOME\.venvs\nexa\Scripts\Activate.ps1on Windows, then run the samepip install. In that case, also tell the AI session “use the python in~/.venvs/nexa.”
Fonts (Optional)
The default font set default uses operating system fonts (Malgun Gothic, Consolas), so there is nothing extra to install. To use the recommended set modern (Pretendard, JetBrains Mono, D2Coding — all SIL OFL), install the fonts and then select it in the workspace.
| OS | Installation |
|---|---|
| macOS | brew install --cask font-pretendard font-jetbrains-mono font-d2coding |
| Windows | pwsh -NoProfile -File <engine>\studio\install_fonts.ps1 (installs for the current user; no admin rights needed) |
To change the font set: editor ⋯ → Font set, or python3 <workspace>/nexa.py set_fonts modern. PowerPoint and the browser must be reopened after installing fonts to show them.
Starting and Stopping the Service
The server listens only on 127.0.0.1 (this PC). It has no authentication, so do not expose it to other PCs.
Start Page (Hub)
python3 studio/service.py start # from the engine folder → http://127.0.0.1:5599/
python3 studio/service.py stop # stop
python3 studio/server.py # or run in the foreground (stop with Ctrl+C)
When started without a workspace, it opens the start page (hub). The hub port is 5599; run information and logs are kept in the user settings folder, and nothing is written to the engine folder.
Workspace Server
Each workspace has a launcher, nexa.py, so you don’t have to type the engine path every time.
python3 <workspace>/nexa.py start # runs in the background on that workspace's port (opens Studio directly if a deck exists)
python3 <workspace>/nexa.py url # access address
python3 <workspace>/nexa.py status # workspace, decks, server, session connection, pending/in-progress requests
python3 <workspace>/nexa.py restart # after changing settings
python3 <workspace>/nexa.py stop # stops only that workspace's server
- One workspace = one server = one request watcher = one AI session. If each workspace uses a different port, you can run several at the same time.
- Starting a second time in the same workspace is refused, and the existing address is shown.
- If another program is using the port, it stops with a “port unavailable” message. Change
portinnexa-slide.jsonor useserver.py --port auto(finds a free port).
Start Page
This is the first screen you see when you open http://127.0.0.1:5599/. Because Nexa Slide physically separates the authoring tool (engine) from the slides you make, the start page first decides “where to create” and then hands off to Studio (the editor).
| Tab | Contents |
|---|---|
| Start | Create new slides, Open folder/repository, Recent work |
| Tutorial | A 5-step guide: choose a workspace → template and direction → edit in Studio → request in a Claude session → present and export |
| Demo | Copies the engine example into nexa-slide-demo/ in the base folder the first time and opens it. Feel free to edit it; to reset it, delete the folder and open it again |
| Templates | The design template list (color swatches, descriptions) and starter contents. Each card has a Preview |
| Browse samples | Add or remove reference sites and open them in a new tab |
| Template review | A screen (/review) for previewing, reviewing, and approving template and layout candidates and reference materials |
Creating New Slides
- Choose a title, template, and starter content.
- Fill in the purpose, audience, writing direction, and reference materials. These are saved to
BRIEF.mdin the workspace and serve as the basis when the AI writes the draft. - Choose a save location. If you don’t, it is created under
NexaSlide/<title>in your operating system’s Documents folder. If you choose a git repository, the subfolder is filled in asslides. - If needed, turn on “Leave a draft request for the Claude session”. A pending request is left on the first slide and delivered as soon as an AI session connects.
- Click “Create and open Studio” to create the workspace, start its server, and go to the editor.
Under the form, “Or create with a command” shows the equivalent init_workspace.py command, pre-filled for PowerShell and bash, with a copy button. The button and the command produce the same result.
- Port: if left blank, it suggests a free port starting from 5600 that no other workspace uses.
- Preview: shows slides actually built from the chosen template × starter content in a window. If no content is selected, it shows layout samples. “Create with this combination” carries the selection straight into the form.
Caution On Windows, if a path contains
&(e.g.S&OP), pyenv-win’spython3may cut off the command. The start page shows a warning and rewrites the command with the real Python path, but if possible, remove&from the folder name.
Main Menu and Base Folder
The ☰ menu at the top left of the start page and Studio takes you to Home, New, Open, Studio, Tutorial, Demo, Templates, Samples, Recent work (search), and Base folder settings.
The base folder is NexaSlide/ under your operating system’s Documents folder (on Windows, including a location moved to OneDrive; ~/Documents on macOS; the XDG documents folder on Linux). You can change it with Base folder settings in the menu or the environment variable NEXA_SLIDE_PROJECTS. User settings are stored in %APPDATA%\nexa-slide\settings.json on Windows, ~/Library/Application Support/nexa-slide/settings.json on macOS, and ~/.config/nexa-slide/settings.json on Linux.
Creating a Workspace
A workspace is the folder on the side where decks are made (e.g. slides/ in a presentation repository). Instead of the start page, you can also create one with a command.
cd ~/Projects/my-talk
python3 ~/Projects/nexa-slide/studio/init_workspace.py slides --title "New Product Launch" --build
python3 slides/nexa.py start # → http://127.0.0.1:<port>/
Set-Location D:\Projects\my-talk
python3 D:\Projects\nexa-slide\studio\init_workspace.py slides --title "New Product Launch" --build
python3 slides\nexa.py start
What gets created (existing files are left untouched):
slides/
├─ nexa-slide.json choices only: port · title · engine location · template · font set · logo file
├─ nexa.py launcher (start · stop · status · build_deck · …)
├─ CLAUDE.md instructions for the Claude Code session (request watcher · handling protocol · commands)
├─ AGENTS.md instructions for other AI tools (same rules)
├─ .claude/settings.json Claude Code hooks — show session activity in the editor
├─ content/ content source <deck>.json ← the AI writes drafts here
├─ decks/ deck <deck>.json (what the editor edits) · request notes <deck>.requests.json
├─ assets/brand/ logo (a placeholder image at first — replace it with your own logo PNG)
└─ out/ PPTX · renders · session state (excluded from git)
Main options:
| Option | Meaning |
|---|---|
--title "title" | Workspace title |
--template <name> | Design template (default: the one set by the starter content, otherwise lecture) |
--starter <name> | Copy starter content (table below) |
--deck <name> | First deck name (default intro) |
--port N or auto | Port (a free port is chosen automatically if omitted) |
--build | Build the content source into a deck after creating |
--purpose --audience --direction … --material … | Writing brief BRIEF.md (direction and material can be given multiple times) |
--ask-draft | Leave a pending request to write a draft from the brief (implies --build) |
--force | Rewrite only nexa-slide.json and nexa.py |
Running it again on an existing workspace creates only the missing files (such as AGENTS.md). In a git repository, out/ and decks/.history/ are excluded via .gitignore, and you can commit the rest.
Starter Content
Start with a slide structure and example content suited to your purpose. The content is fictional, so replace the numbers, names, and dates.
| Group | Starter content |
|---|---|
| 15 template types (purpose-specific default structures, 11–17 slides) | research-report research report · strategy-plan strategy/annual plan · board-decision executive decision request · periodic-report periodic status report · investor-pitch investor pitch · ir-finance IR/finance · sales-proposal B2B proposal · case-story case study/retrospective · marketing-campaign marketing campaign · consulting consulting · lecture-theory theory lecture · training-course job training · classroom class/student presentation · public-policy public sector/policy · talk-story talk/portfolio |
| 6 hand-written examples | lecture-course 3-day course materials · schedule schedule/roadmap · story-retro project retrospective · notice-onboarding internal notice/onboarding · rfp-owner RFP summary · rfp-response proposal |
python3 <engine>/studio/init_workspace.py <folder> --title "Monthly Report" --starter periodic-report --template graphite
Course Materials Starter (lecture-course)
A starter for writing multi-day course materials on the same skeleton. It includes a shared cover, overall table of contents, and EoD (content/_common.json), a course introduction chapter ch00 (24 body slides), and a theory chapter ch01 (12 body slides, including Mermaid diagrams).
python3 <engine>/studio/init_workspace.py <workspace> --title "Course Name" --starter lecture-course
python3 <workspace>/nexa.py build_deck ch00 --force
python3 <workspace>/nexa.py build_deck ch01 --force
python3 <workspace>/nexa.py start
Design Templates
Colors, fonts, font sizes, and check criteria live in the engine’s templates; a workspace only picks a name via template in nexa-slide.json.
| Template | Characteristics |
|---|---|
lecture (default) · lecture-large | Lectures and course materials, 16:9 / uniformly larger text |
brief · notice · schedule · proposal | Purpose-specific (decision, notice, schedule, RFP) colors and corners |
keynote · archive · blueprint · swiss | Dark stage, gold / off-white paper, terracotta, serif / blueprint teal and orange / white background with a single red |
editorial · ledger · signal · forest | Off-white, serif, crimson / cream, navy, gold / yellow, black, red / forest green, cream, terracotta |
graphite | White background, black text, gray tones only with no accent color, no rounded corners |
Using the Editor
Open the workspace server address (nexa.py url) in a browser to bring up Studio.
Screen Layout
| Area | Contents |
|---|---|
| Header | Deck tabs · save status · session chip · ▶ Present · History · Export ▾ · ⋯ More (font set, template, shortcuts, reset layout) |
| Left rail | Thumbnails (drag to reorder, duplicate, delete) · note/request/in-progress/check badges · + New slide |
| Mode bar | ✎ Edit (E) · ◎ Select (M) · ✐ Draw (D) · undo · ✨ Fix layout · ✨ Polish |
| Format bar | Appears when you select an element in Edit mode — font, size, text color, bold, alignment, line spacing, fill, border, duplicate, delete, lock, ✥ Position |
| Bottom | Notes · Outline · Check tabs · page navigation · zoom (10–300%) |
| Right panel | Properties · Requests (list, status, replies) · History (automatic backups) · Changes (changes made outside the editor) |
Colors are chosen from the template color palette, not arbitrary HEX values.
Three Modes
| Mode | What it does |
|---|---|
| ✎ Edit (E) | Click to select, drag to move (8px grid, Shift = free), resize with handles, double-click or Enter to edit text directly (Esc or Ctrl+Enter to finish) |
| ◎ Select (M) | Click an element to open a note popover right there. Quick chips by element type (polish, make longer, make shorter, split table into two slides, etc.). Enter = add, Shift+Enter = new line |
| ✐ Draw (D) | Mark an area with ▭ box · 〰 pen · 📍 pin and add a note. Elements overlapping that area become the target of the request |
Adding Slides and Changing Types
Click + New slide to open the Add Slide dialog.
- By type: choose a slide type from preview cards in 8 purpose groups (opening and introduction, message, evidence and data, comparison and judgment, process and plan, people and cases, learning and review, closing and appendix). The chosen type is inserted pre-filled with example content.
- By layout: choose by layout name.
- Change type: right-click a thumbnail → “Change type…”. The title and notes are kept and the body is converted to the new type (Ctrl+Z to undo).
Saving, History, and Presenting
- Autosave: saves 0.7 seconds after an edit. Nothing is saved if nothing changed. Ctrl+S saves immediately.
- History: automatic backups are kept on every save (the latest 50) and before a build overwrites the deck. “Restore” takes you back to the deck at that point.
- Changes: when the AI or anything else changes the deck from outside, the editor reloads it within 2 seconds and shows the changed slides and elements in the Changes tab, with thumbnail badges, and with blue dashed outlines on the canvas.
- Present: F5 from the beginning · Shift+F5 from the current slide · →/Space next · ← previous · N notes and elapsed time · Esc to end.
Keyboard Shortcuts
| Category | Keys |
|---|---|
| Modes | E Edit · M Select · D Draw |
| Slides | PageUp/PageDown · Home/End |
| Zoom | Ctrl+wheel · Ctrl+= / Ctrl+- · Ctrl+0 fit · Ctrl+1 100% · Space+drag to pan |
| Editing | Ctrl+Z/Y · Ctrl+C/X/V/D · Ctrl+B bold · Delete · Enter/F2 edit text · Ctrl+S save |
| Order | Ctrl+] / Ctrl+[ (forward/backward) · Alt+Ctrl+] / Alt+Ctrl+[ (to front/to back) |
| Other | F5 / Shift+F5 present · Ctrl+\ right panel · Esc close · ? help |
Making Slides with an LLM (Claude Code)
Overall Flow
| Step | What happens |
|---|---|
| ① Create | Create a workspace from the start page or with init_workspace.py and start the server. The AI is not connected yet |
| ② Connect the AI session | Open the AI in the workspace folder and say “start the request watcher” → the editor chip shows Session connected |
| ③ Iterate | Leave requests in the editor → send → AI handles them → done + reply → editor refreshes automatically |
| ④ Finish | Check shows 0 ERRORs → export PPTX → commit (if using git) |
Requests left before connecting are not lost. They stay pending in requests.json and are delivered all at once as soon as the watcher starts.
Step 1 — Open a Claude Code Session and Start the Watcher
Terminal
cd '<workspace>'
claude
Type one line in the chat.
Start the nexa-slide request watcher for this workspace.
Claude reads CLAUDE.md and starts the following watcher with the Monitor tool (you can also type it yourself).
python3 <workspace>/nexa.py watch_requests --stream --takeover --label "<session name>" (timeout 1800000)
- VS Code: open the workspace (or its repository) with File → Open Folder and type the same line in the Claude Code chat. You can also view the editor inside VS Code with the command palette’s
Simple Browser: Show. - Claude Desktop: create a Code (local folder) session, choose the workspace as the folder, and type the same line. If you open the editor in the built-in browser panel, Claude can also look at the screen directly to check its work.
- A session opened in a folder other than the workspace (such as a parent repository) does not read the workspace’s
CLAUDE.mdautomatically. Include the path in your request, for example: “<workspace>is a nexa-slide workspace. Read the CLAUDE.md in that folder first, then start the request watcher.” It helps to add a line to the repository rootCLAUDE.mdsuch as “Slide work is inslides/— readslides/CLAUDE.mdfirst.”
Note The watcher (
--stream) ends on its own after about 30 minutes (1780 seconds) and emits{"event":"ttl"}. Following theCLAUDE.mdprotocol, Claude restarts it with the same command.--takeovercleans up any leftover previous watcher and takes over from it.
Step 2 — Check the Connection
| Editor header chip | Meaning |
|---|---|
| Green Session connected | The watcher is running — sent requests are delivered right away |
| Blue Session working n | The AI is handling n requests |
| Gray No session connected | No watcher — requests are saved and delivered once the watcher starts |
With Claude Code, the chip also shows session activity — “Working in chat for N min · n requests pending”, “Handling request”, “Idle — will handle requests right away”, “N other sessions”. The hooks in the workspace’s .claude/settings.json record this information, and Claude Code may ask you to confirm trust the first time you open it.
Step 3 — The First Draft
If you turned on the draft request when creating the workspace, the request “Please write a draft of this deck based on the purpose, audience, writing direction, and reference materials in BRIEF.md” is delivered as soon as the session connects. If you didn’t, saying “Write a draft from BRIEF.md” in the chat does the same. The AI works in this order:
- Reads
BRIEF.mdand checks the layouts and fields withnexa.py layout_samples. - Writes
content/<deck>.json(the content source). When choosing slides, it uses the slide type that fits the nature of the content. - Builds the deck with
build_deck <deck> --forceand clears overlap, overflow, and minimum-font-size ERRORs withcheck_layout <deck>. - Marks the request done and leaves a summary and follow-up questions (about anything left blank because it wasn’t in the materials) as a reply.
If you want to hand it off directly with a command, you can ask like this:
Write a draft of content/intro.json with the content below. Check the layouts with python3 nexa.py layout_samples,
reduce ERRORs with build_deck intro --force → check_layout intro, and make it viewable in the editor.
- Topic: <presentation topic>
- Audience and length: <for whom, how many minutes>
- Number of slides: <e.g. 10–12>
- Materials: <paths, documents, URLs to reference> (do not make up figures or quotes without a source)
Step 4 — Leaving Request Notes in the Editor
| What | How |
|---|---|
| A single element | Click the element in ◎ Select (M) and write a note (Enter) — e.g. “Split this table into two slides” |
| An area | Draw a box, pen stroke, or pin with ✐ Draw (D) and write a note |
| The whole slide | Write a note in the slide request field of the Requests tab on the right (Enter = add, Shift+Enter = new line) |
| Sending | ”Send N requests” in the bottom bar. When connected, they are delivered after 8 seconds of inactivity; “Send now” delivers them immediately |
| Fixing check results | ✨ Fix layout — immediately sends a request containing this slide’s check results |
| Polishing content | ✨ Polish — requests cleanup of logic and alignment while keeping the style |
Notes first accumulate as drafts (number badges on the canvas, ✎ badges in the rail), and once sent they move through pending → working → done. Input you haven’t added yet is also kept in the browser, so it isn’t lost when you move to another slide or refresh.
When the AI needs clarification, it leaves the request pending and asks a question in its reply. Add your answer in the Requests tab and it is delivered again. When the AI creates a new deck, a new deck tab appears right away along with a “New deck — [Open]” notice.
Editing Directly from the Chat
You can also just tell the AI in the chat without request notes — “Change the title on slide 3 to a conclusion-style headline and keep tables to 6 rows or fewer,” “Cut the deck down to 10 slides.” The AI edits content/ and rebuilds, and the editor automatically loads the changed deck.
Caution If there are slides you edited directly in the editor,
build_deck --forcestops and tells you, because rebuilding from the content source would discard those edits. Ask the AI to “move the edits made in the editor into content and rebuild.” The state before overwriting can be restored from History.
Other AI Tools (Codex CLI, Gemini CLI, Cursor, etc.)
These tools read the workspace’s AGENTS.md (Gemini CLI reads GEMINI.md by default, so copy AGENTS.md to GEMINI.md or add it to the contextFileName setting). Because they cannot receive notifications from long-running commands, they connect using a wait-once loop.
This folder is a nexa-slide slide workspace. Read CLAUDE.md first (the same rules apply to you).
1) Run python3 nexa.py watch_requests --label "<tool name>". It waits until a request arrives, prints the list, and exits.
2) For each request: set status to working → edit the deck → reflect it in content as well → set status to done, with one or two sentences in reply.
3) When finished, run 1) again. Repeat until I tell you to stop.
For tools that cannot use a shell, skip the watcher: after sending requests, say “Handle the requests with status open in the requests.json files in decks/.” These tools have no session activity display (only the connected and working chips).
Finishing and Resuming
- Closing the AI session stops the watcher, and the chip changes to “No session connected.” Stop the server with
python3 <workspace>/nexa.py stop. - To resume next time:
nexa.py start→ open the AI session → “Start the request watcher.”
Deck JSON Structure Summary
There are two sources.
| File | Contents | Who edits it |
|---|---|---|
content/<deck>.json | Content source — a layout name + fields for each slide | Mainly the AI (drafts, large edits) |
decks/<deck>.json | Deck — the content source built out with element coordinates | The editor (direct edits), the AI (handling requests) |
Content source example:
{
"id": "intro", "title": "New Product Launch", "part": "day1", "version": "0.1",
"slides": [
{"layout": "cover", "title": "New Product Launch", "subtitle": "Subtitle"},
{"layout": "bullets", "title": "Why change", "items": ["Point 1", {"text": "Point 2", "sub": ["Supporting detail"]}], "notes": "Speaker notes"},
{"layout": "table", "title": "Comparison", "header": ["Item", "Current", "New"], "rows": [["Speed", "1x", "**3x**"]]},
{"layout": "summary", "title": "Summary", "items": ["Key takeaway"]},
{"layout": "end", "title": "End of Document", "sub": "New Product Launch"}
]
}
- Slides are based on 1280×720 px, converted to PPTX as pt = px × 0.75.
- Deck element types: rectangle, ellipse, pill (
pill), text box, image, line, arrow, curve, table, bullets, code, action plan, and more. - Inline emphasis:
**bold**·==highlight==·[[token|colored text]]·{page}(page number). - There are 56 layouts, including cover, table of contents, section cover, bullets, table, comparison, flow, cards, KPI, Gantt, roadmap, donut, and heatmap. See the list and field examples with
python3 <workspace>/nexa.py layout_samples. - For long Korean sentences, breaking lines yourself with
\nis the safest way to keep the screen and PowerPoint in sync.
PPTX Export
| Method | Result |
|---|---|
| Editor Export ▾ → PPTX | out/<deck>.pptx |
python3 <workspace>/nexa.py export_pptx <deck> | Same |
Export menu “PPTX — embed fonts” or nexa.py embed_fonts <deck> | out/<deck>-fonts.pptx — embeds fonts for only the characters used (Windows, requires PowerPoint) |
| Export menu PowerPoint render preview | View an image actually rendered by PowerPoint in the editor (Windows, requires PowerPoint) |
- The exported PPTX consists of native PowerPoint shapes, so you can open it and edit it right away. Speaker notes are also included as PPTX slide notes.
- Each export records the fonts used (free / system / custom) in
out/<deck>.fonts.json.
Caution Edits made in PowerPoint do not flow back into the deck JSON (one-way). For content you will keep refining, edit it in the editor or through AI requests and export again.
Before exporting, make sure the Check tab at the bottom shows 0 ERRORs. Checks run automatically on every save and report text overlap, overflow, out-of-slide elements, minimum font size, and monospace column alignment. Click an item to jump to the element.
Verifying Screen–PowerPoint Consistency
Both renderers use the same rules so that the screen (browser) and the PPTX look the same, and you can check the result numerically. For most users, checking visually with the PowerPoint render preview is enough.
python3 studio/compare.py -W <workspace> <deck>: pixel comparison of the browser view and the PowerPoint render (Windows + PowerPoint + Chrome/Edge). For the 15-slide example deck, the difference is 0.3–2.7% (at the level of text edges).python3 studio/check_parity.py -W <workspace>: checks that the screen (JS) and PPTX (Python) calculations produce the same results (requires Node.js).- Line layout correction values were measured with Malgun Gothic and Consolas. If you use other fonts, it’s a good idea to re-measure with
compare.py.
Troubleshooting
| Symptom | Check / fix |
|---|---|
python3 not found (Windows) | Run with py -3 or python instead. Also tell the AI “use py -3 instead of python3" |
| "Port unavailable” | Another workspace or program is using that port — change port in nexa-slide.json or use --port auto |
| ”Already running” | That workspace’s server is already running — check the address with nexa.py url |
| ”No deck” in the editor | Check whether there is a deck in decks/ — if not, run nexa.py build_deck <deck> |
| Chip stays “No session connected” | Check that the AI actually ran the watcher command. If the session was opened in another folder, include the workspace path in your request |
| ”Connected” but requests aren’t delivered | An expired watcher may be left over — restart it with the same command plus --takeover |
{"event":"refused"} | Another session is watching this workspace — use that session or take over with --takeover |
| Request stuck in “working” | The AI session dropped mid-task — in the Requests tab, “Mark as done” → “Reopen” to return it to pending, then reconnect |
build_deck stops | There are slides edited directly in the editor — move them into content, then build (see “Editing Directly from the Chat” above) |
| Logo not showing / image 404 | Check that brand.logo in nexa-slide.json and the image paths in the deck are relative to assetRoot |
| PowerPoint render fails | Check that PowerPoint is installed and the pwsh path. If a previous render is still running, try again shortly |
| Repeated save conflicts | Check whether the same deck is open in another browser tab (no automatic merging) |
Finding the process using a port:
# Windows
Get-NetTCPConnection -LocalPort 5600 -State Listen | % { Get-CimInstance Win32_Process -Filter "ProcessId=$($_.OwningProcess)" } | select ProcessId, CommandLine
# macOS / Linux
lsof -iTCP:5600 -sTCP:LISTEN
pgrep -fl watch_requests
Note On Windows,
killin Git Bash may end only the wrapper and leave python running. UseStop-Process -Id <PID> -Forceortaskkill /F.
Version History
Note Nexa Slide has not created any git tags or GitHub releases yet. The versions below are the engine versions recorded in the repository’s
CHANGELOG.md, merged into themainbranch in sequence.
Version Flow Summary
| Version | Date | Highlights |
|---|---|---|
| v0.13.0 – v0.13.3 | 2026-10-02 | Template parts, change type, per-deck/per-slide fonts, session activity display, 15 starters, 5 visual templates added |
| v0.11.0 – v0.12.0 | 2026-10-02 | 54 slide types, 19 new layouts, 4 approved templates |
| v0.10.0 – v0.10.2 | 2026-10-02 | Changes tab, workspace fonts, PPTX with embedded fonts, template review |
| v0.7.0 – v0.9.0 | 2026-10-02 | Start page and main menu, purpose-specific starters and designs, preview and create-with-command |
| v0.5.0 – v0.6.0 | 2026-10-01 – 10-02 | Editor UI overhaul (3 modes, in-place notes), new workspace tool, course materials starter |
| v0.2.0 – v0.4.1 | 2026-10-01 | Split into a standalone repository, layout checks, design templates, more stable session connection |
v0.13.3 — 2026-10-02
- Added Visual template
graphite— white background, black text, only gray tones and weights with no accent color, no rounded corners, page numbers only.
v0.13.2 — 2026-10-02
- Added 4 recommended visual templates —
editorial(off-white, serif, crimson) ·ledger(cream, navy, gold) ·signal(yellow, black, red) ·forest(forest green, cream, terracotta).
v0.13.1 — 2026-10-02
- Added All 15 template types as starter content — purpose-specific default structures mixing 11–14 slide types (11–17 slides). 10 new ones (
research-report,investor-pitch,sales-proposal,case-story,marketing-campaign,consulting,training-course,classroom,public-policy,talk-story). - Improved The existing 5 starters were expanded the same way. All 15 have 0 layout check ERRORs.
v0.13.0 — 2026-10-02
- Added Template parts — within the same layout, the template chooses only the look of common parts such as labels, footer bands, and large page numbers.
- Added Editor Change type — switch to a different slide type while keeping the title and notes.
- Added Per-deck and per-slide font sets (slide > deck > workspace precedence).
- Added Session activity display — Claude Code hooks show “Working in chat for N min · n requests pending” and similar in the editor chip.
- Added
AGENTS.mdin new workspaces (instructions for Codex, Gemini CLI, Cursor). - Improved The start page warns when a path contains
&and shows the command with the real Python path.
v0.12.0 — 2026-10-02
- Added 4 approved visual templates —
keynote·archive·blueprint·swiss. - Added 5 approved template types as starter content (
periodic-report,board-decision,ir-finance,strategy-plan,lecture-theory). - Added Layouts
donut(arcs editable in PPTX) ·heatmap. - Changed Overlapping templates (
story,report) and starters (weekly-report,monthly-report,decision-brief) are hidden from the lists — existing workspaces and--starterstill work. - Improved Added “selection signals” to the 54 slide types so the AI picks a type that fits the content when drafting or handling requests (
nexa.py slide_types).
v0.11.0 — 2026-10-02
- Added 17 new layouts — conclusion panel, line chart, range bars, funnel, option comparison, quadrant, tree, person cards, photo plates, step-by-step solution, quiz, references, anticipated questions, and more.
- Added 52 slide types (8 groups by purpose and structure) and the editor’s Add Slide dialog (by type / by layout).
- Added Slide type review screen.
v0.10.2 — 2026-10-02
- Changed Template review moved to a tab on the start page (
/review).
v0.10.1 — 2026-10-02
- Added A review registry for registering, previewing, reviewing, and approving template and layout candidates and reference materials.
v0.10.0 — 2026-10-02
- Added Editor Changes tab — records and shows before/after per slide and element when a deck changed from outside (e.g. by the AI) is reloaded.
- Added Workspace fonts (
fonts/+ a custom font set), editor font dialog, record of fonts used (out/<deck>.fonts.json). - Added PPTX with embedded fonts (
PPTX — embed fonts, requires PowerPoint on Windows) and a free fonts guide page.
v0.9.0 — 2026-10-02
- Added Start page Preview — view slides actually built from template × starter content in a window.
- Added Create with a command — shows the
init_workspace.pyand server start commands, filled in with the form values, for PowerShell and bash. - Added
init_workspace.pyoptions--port,--build, brief options (--purpose, etc.), and--ask-draft. - Improved The editor detects new decks, settings, and engine changes, refreshing deck tabs and showing a “New deck — [Open]” notice.
- Added AI connection docs — how to connect Claude Code and other AI tools.
- Fixed Build errors caused by empty samples in some layouts (
column_chart,stack_bars).
v0.8.0 — 2026-10-02
- Added 8 purpose-specific starter materials (weekly and monthly reports, decision request, schedule, retrospective, notice/onboarding, RFP issuing and response) and 6 design templates.
- Added 16 layouts — status table, KPI tiles, Gantt, roadmap, weekly table, bar chart, and more.
v0.7.0 — 2026-10-02
- Added Start page (hub) and the main menu at the top left — New, Open, Recent work, Tutorial, Demo, Templates, Samples.
- Changed Slide content is no longer kept in the engine folder — the default workspace location is Documents/
NexaSlide/<title>.
v0.6.0 — 2026-10-02
- Added Course materials starter
lecture-courseandinit_workspace.py --starter. - Fixed The launcher
nexa.pyraised a syntax error when the workspace was on a different drive from the engine (Windows).
v0.5.3 — 2026-10-02
- Improved In the slide request field of the Requests tab, Enter = add note, Shift+Enter = new line.
v0.5.2 — 2026-10-02
- Improved Footer footnotes are laid out horizontally with more visible numbers.
- Improved Request input not yet added is kept in the browser (survives moving between slides and refreshing).
v0.5.1 — 2026-10-01
- Added New workspace creation with
init_workspace.py(automatic free port selection), layout sampleslayout_samples.py, and a detailed new project guide (macOS, Windows).
v0.5.0 — 2026-10-01
- Changed Editor UI overhaul — Edit, Select, and Draw modes, in-place note popover, “Send N requests,” a docked format bar, and a position menu.
- Added Zoom 10–300%, presentation mode (notes, elapsed time), History (restore from automatic backups), ✨ Fix layout · ✨ Polish.
- Improved Nothing is saved if nothing changed. Slide designs are unchanged.
v0.4.1 — 2026-10-01
- Fixed After the request watcher expired, it still showed “Connected” but requests were not delivered — the watcher now ends on its own after a set time (
ttl), and--takeovertakes over a leftover watcher.
v0.4.0 — 2026-10-01
- Added Design templates — colors, fonts, font sizes, and check criteria are bundled into engine templates, and a workspace only picks a name.
lecture(default) ·lecture-large(larger text).
v0.3.0 — 2026-10-01
- Added Layout checks — text overlap, overflow, out-of-slide elements, minimum font size, monospace alignment. Editor “Check” tab (runs automatically on every save; clicking an item jumps to the element).
v0.2.0 — 2026-10-01
- Added Split into a standalone repository — engine and workspaces separated, multiple workspaces running at once on per-workspace ports, background service (
start,stop,status). - Added Claude session connection — request watcher stream, editor session chip, “Send now.”
- Added MIT license, example workspace, documentation.
Earlier versions (0.1, 2026-09) were developed as an internal tool (Slide Studio v0) inside another repository.
Known Limitations
- Pre-release: there are no tags or installers; you get it with
git clone. Development is moving quickly, so screens and commands may change. - Requires a separate AI tool: Nexa Slide does not call an LLM directly. Drafting and request handling are done by a session you open, such as Claude Code. Tools other than Claude Code connect via the wait-once loop or manually, and have no session activity display.
- One-way conversion: edits made in PowerPoint do not flow back into the deck JSON.
- Windows-only features: PowerPoint render preview, PPTX with embedded fonts, and the PowerPoint comparison in
compare.py. - Editor: auto-fit text (shrink on overflow), rotation, shadows, transparency, and gradients are not supported. There are no multi-select or alignment tools.
- Tables: rounded corners on header rows are square because PowerPoint tables don’t support them. In PowerPoint tables, rows grow automatically when text is larger than the cell (on screen it appears to overflow).
- Concurrent editing: if the same deck is open in two browsers, whichever saves later gets a conflict notice (no automatic merging).
- Local only: the server listens only on
127.0.0.1and has no authentication. It is not meant for access from other PCs. - Screen–PowerPoint line layout correction is calibrated for Malgun Gothic and Consolas. Line positions may differ slightly with other fonts.
License
Nexa Slide is distributed under the MIT License and is free to use, including for commercial purposes. For third-party component notices, see THIRD_PARTY_NOTICES.md in the repository.
- The engine repository does not include trademark files such as company logos or font files. The logo in the examples is a placeholder image; put your own logo in the workspace’s
assets/brand/and custom fonts in the workspace’sfonts/. - The recommended fonts (Pretendard, JetBrains Mono, D2Coding) are SIL OFL fonts; get them from their official distribution sites.