Claude Code can create presentation slides in two formats: PowerPoint (.pptx) files generated via the python-pptx library, and HTML files with arrow-key navigation and contenteditable text. PPTX works for sending to others who need an editable file. HTML works for presenting from a browser and iterating quickly. Merging new slides into an existing PPTX deck takes multiple attempts due to OOXML theme-handling quirks. HTML slides typically need 8-12 rounds of visual feedback to get right.
There are two ways to make slides with Claude Code. The first produces a .pptx file, the kind you’d open in PowerPoint or Keynote and send to a client. The second produces an HTML file, the kind you’d open in a browser and navigate with arrow keys. Both work. They’re right for different situations.
This post covers both approaches, including what goes wrong with each, how to choose between them, and the specific failure modes that will waste your afternoon if you don’t know about them going in.
What a .pptx file actually is
Before getting into the workflow, here’s the thing that made all of this click: a .pptx file is not a binary file. It’s a zip archive full of XML.
If you rename any .pptx file to .zip and open it, you’ll find a folder structure with XML files describing every slide, shape, relationship, and style. The PowerPoint format is called OOXML (Office Open XML), and it’s an ISO standard for representing documents as XML. Understanding this matters because it explains both why Claude can generate PowerPoint files from scratch and why those files sometimes come out subtly broken.
python-pptx is the Python library that most scripts use to create or edit .pptx files. It’s the standard tool. It handles the common cases well and breaks in interesting ways on the edge cases.
Approach 1: Generating a PPTX from scratch
The easier of the two PPTX tasks is generating a new deck from a rough outline or notes.
This came up in practice when there was a course to teach in three hours and nothing prepared except a messy outline with random thoughts, screenshots with Obsidian filenames like Pasted image 20260128052639.png, and a bullet point that just said “fuck that shit.”
The prompt that worked was explicit about what Claude needed to actually do:
I need slides for my course session today. Here's my outline: [paste outline].
Don't help me make slides. Actually make them.
Vibe: playful, a little weird, 90s PowerPoint energy, not corporate.
Output: a .pptx file, 15-20 slides, consistent color palette.
The key phrase was “don’t help me make slides - actually make them.” Without that, Claude offers structure and suggestions. With it, Claude writes the python-pptx code and runs it.
Twenty minutes later: 18 slides, consistent colors, all the content from the outline organized into a logical flow. The presentation debugged itself between the first and second version while the prompt-writer was reading the first draft.
The python-pptx gotchas
When generating from scratch, the common failure modes are visual rather than functional. The file opens. The content is there. But:
- Backgrounds specified in the design theme often vanish. The slides come out white even when you asked for dark.
- Rounded rectangles in shapes revert to hard corners. python-pptx has limited support for the
rPr(run properties) and shape geometry attributes that control this in OOXML. - Font weights and sizes are often off. The library doesn’t always translate “bold 24pt” into the exact XML attributes PowerPoint expects.
None of these are dealbreakers. They’re fixable with a few rounds of feedback. The process is the same as with HTML slides: open the file, notice what’s wrong, describe it, iterate.
Approach 2: Merging slides into an existing deck
This is the harder problem, and where the real learning happened.
The situation: a working PowerPoint deck for a course. Five new slides needed to be added before teaching in two hours. The existing deck had a specific design system: backgrounds, custom color schemes, rounded rectangles, a consistent visual style that took a while to build.
Attempt 1: python-pptx append
The obvious approach: use python-pptx to open the existing deck, create the new slides programmatically, and save.
It worked in the sense that the file opened. But the new slides looked like someone had photocopied the originals while slightly drunk. Backgrounds vanished. Rounded rectangles became regular rectangles. The visual style was gone.
The problem is that python-pptx reads and writes the OOXML XML directly, but it doesn’t fully understand the relationship between theme files and slide content. When you create a new slide in python-pptx, it creates the XML but doesn’t carry over the theme references that control how shapes and colors render. The result looks right in the file structure but wrong on screen.
Attempt 2: Manual OOXML editing
Since the file is just a zip of XML, the next attempt was to unzip the deck, hand-edit the XML files to insert new slide XML, then rezip.
This produced a corrupt file. PowerPoint refused to open it.
OOXML has a relationship system: every slide has a corresponding .rels file that registers it with the presentation. If you add a slide XML without updating the relationship files and the [Content_Types].xml manifest, the file structure is invalid. PowerPoint catches it immediately.
Attempt 3: Append plus force-pack
The approach that worked: generate the new slides as a separate deck using python-pptx, then use the python-pptx API to copy slide objects from the new deck into the existing one, skipping the library’s validation step during the copy.
The key was rearranging slide order after the merge (moving the new slides to their target positions), then saving. The --force-pack flag in the script skipped the validation that was rejecting the merged slide objects.
Three attempts to insert five slides. That’s roughly how it goes with OOXML work.
Here’s a YouTube walkthrough of the whole process:
Approach 3: HTML slides with contenteditable
The discovery of this HTML workflow is described in All You Gotta Do Is Ask.
The HTML approach sidesteps all of the OOXML complexity. Instead of generating a file format with a complex specification, Claude generates a self-contained HTML file that works as a presentation.
What contenteditable means: it’s an HTML attribute you can add to any element. <p contenteditable="true">Your text here</p> makes that paragraph editable in the browser. You click it, you type, the text changes. For slides, this means you can make last-minute edits during a presentation without reopening a code editor. The changes don’t persist after you reload the page, but for live presenting that’s usually fine.
The workflow:
- Describe what you need. Mention the visual style, number of slides, content focus.
- Claude writes the full HTML file with CSS for layout, JavaScript for arrow key navigation, and
contenteditableon all the text elements. - Open the file in your browser.
- Look at every slide. Notice what’s off.
- Describe what needs to change. Claude updates the file.
- Repeat 8 to 12 times. That sounds like a lot. Each round takes about two minutes.
The feedback format matters. “Change the h2 font-size to 2.2rem” is the wrong kind of feedback. “The title on slide 3 is getting cut off” is the right kind. Claude can infer the code fix from the visual problem. You don’t need to know CSS.
If you make edits directly in the browser (via contenteditable) and want to preserve them, you can export the current HTML from the browser console: document.documentElement.outerHTML. Copy that, paste it back to Claude, and continue iterating from the edited version.
For deploying HTML slides to a real URL, see the companion post: How to Build and Deploy Presentation Slides with Claude Code and Cloudflare Pages.
When to use which approach
Use PPTX when:
- You need to send the file to someone else
- The recipient needs to edit slides in PowerPoint or Keynote
- You’re working with an existing branded deck you can’t abandon
- The presentation needs to be printed or handed off as a document
Use HTML when:
- You’re presenting directly from your own laptop
- You want to iterate fast and see changes instantly
- You want to deploy slides to a URL so attendees can follow along
- You don’t need the file to be editable by non-technical people
The practical heuristic: if the person receiving the slides needs to open them in an app, use PPTX. If you control the presentation environment, HTML is faster to build and easier to iterate on.
What “starting from chaos” actually looks like
Both of the real examples described in this post started with almost nothing. In one case: an outline with incomplete sentences and a profanity-laden bullet point. In the other: an existing deck with no time to carefully craft the new slides.
The common thread in both was the prompt framing. The successful versions of these prompts had a few things in common:
- Explicit about the output format (PPTX or HTML, not “slides”)
- Gave the visual direction a name or reference (“90s PowerPoint energy,” “match the existing deck’s style”)
- Said “make them” rather than “help me make them”
- Didn’t try to specify exact dimensions or styles in the prompt
The visual direction is worth thinking about before you start. “Make them look good” produces generic. “Warm and playful, like an Airbnb deck from 2015” or “dark background, technical, code-heavy” gives Claude something to match.
Summary
Two approaches. One produces a file you can email. The other produces a file you can present from a browser URL.
PPTX generation from scratch works well. PPTX merging with an existing deck is doable but takes a few attempts, usually in the progression: python-pptx append (visual breakage), manual XML edit (corrupt file), append-plus-rearrange (works). Understanding that a .pptx is a zip of XML makes the failure modes predictable rather than mysterious.
HTML slides are faster to build, easier to iterate on, and deployable to a URL in one session. They don’t work for sending to someone who needs a file they can edit in PowerPoint.
Neither approach requires knowing how to code. The job is describing what you need and describing what’s wrong when it’s wrong.
Further reading
- How to Build and Deploy Presentation Slides with Claude Code and Cloudflare Pages for the full HTML slides to Cloudflare workflow
- python-pptx documentation for understanding what the library can and can’t do
- OOXML specification overview if you want to understand the file format at the XML level
- MDN: contenteditable for how browser-editable HTML works
- Claude Code documentation for getting started with Claude Code
Common Questions
Can Claude Code make PowerPoint slides?
Yes. Claude Code uses the python-pptx library to generate .pptx files from scratch. Provide a rough outline and visual direction, and Claude produces a complete slide deck. Common issues include background colors not rendering and rounded corners reverting to hard edges, both fixable with iteration.
Should I use PPTX or HTML slides from Claude Code?
Use PPTX when recipients need to edit in PowerPoint/Keynote or when the file needs to be emailed. Use HTML when presenting from your own laptop, when you want fast iteration, or when you want to deploy slides to a URL. HTML is faster to build; PPTX is more portable.
Why do merged PowerPoint slides lose their formatting?
python-pptx doesn’t fully carry over theme references between slide XML and theme files. When new slides are created programmatically, they get the XML structure but not the visual styles from the original deck. The fix involves generating slides separately and merging with forced packing.
What is OOXML?
OOXML (Office Open XML) is the file format behind .pptx, .docx, and .xlsx files. A .pptx file is actually a zip archive containing XML files that describe slides, shapes, and styles. Understanding this explains both why Claude can generate PowerPoint files and why they sometimes render incorrectly.
A note from Alex: hi i’m alex - i run code for creatives. i’m a writer so i feel that it is important to say - i had claude write this piece based on my ideas and ramblings, voice notes, and teachings. the concepts were mine but the words themselves aren’t. i want to say that because its important for me to distinguish, as a writer, what is written ‘by me’ and what’s not. maybe that idea will seem insane and antiquated in a year, i’m not sure, but for now it helps me feel okay about putting stuff out there like this that a) i know is helpful and b) is not MY voice but exists within the umbrella of my business and work. If you have any thoughts or musings on this, i’d genuinely love to hear them - its an open question, all of this stuff, and my guess is as good as yours.