Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create, edit, read, and design PowerPoint presentations (.pptx). Use whenever a .pptx file is involved — creating slide decks, pitch decks, or stakeholder presentations; reading or extracting content from an existing .pptx; editing or updating slides; building from a template. Trigger on "deck", "slides", "presentation", "pitch deck", "PowerPoint", or any .pptx filename.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 47% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 93% | 0% |
| case-13 | ✗→✓ | ▲ Improved | 68% | 0% |
| case-16 | ✗→✓ | ▲ Improved | 156% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 147% | 0% |
A .pptx file is a ZIP archive of XML files. You can create, edit, and read them programmatically. Choose the right approach for the task:
| Task | Approach | |---|---| | Create a new deck | pptxgenjs (Node) or python-pptx (Python) | | Edit an existing deck | Unzip → edit slide XML → rezip | | Read content from a deck | markitdown deck.pptx or unzip and parse XML | | Convert to PDF | LibreOffice headless |
Ask the user:
bash# pptxgenjs is often pre-installed — try require first node -e "require('pptxgenjs')" 2>/dev/null && echo "installed" || npm install pptxgenjs
javascriptconst pptx = require("pptxgenjs"); const pres = new pptx(); // ALWAYS set layout before adding slides pres.layout = "LAYOUT_16x9"; // 10" × 5.625" — standard widescreen // Define theme colors (never use # prefix, never 8-digit hex) const COLORS = { primary: "1E3A5F", // Deep navy accent: "2E86AB", // Electric blue light: "F8F9FA", // Near white dark: "212529", // Near black muted: "6C757D", // Gray }; // Title slide const titleSlide = pres.addSlide(); titleSlide.background = { color: COLORS.primary }; titleSlide.addText("Your Presentation Title", { x: 0.5, y: 1.8, w: 9, h: 1.2, fontSize: 40, bold: true, color: "FFFFFF", align: "left", }); titleSlide.addText("Subtitle or date", { x: 0.5, y: 3.0, w: 9, h: 0.5, fontSize: 18, color: "A8C6E8", align: "left", }); await pres.writeFile({ fileName: "presentation.pptx" });
javascriptconst slide = pres.addSlide(); slide.addText("Key Metrics", { x: 0.5, y: 0.3, w: 9, h: 0.6, fontSize: 28, bold: true, color: COLORS.dark }); // Three metric blocks const metrics = [ { value: "810×", label: "Productivity increase" }, { value: "40+", label: "Features shipped" }, { value: "3", label: "Products launched" }, ]; metrics.forEach((m, i) => { const x = 0.5 + i * 3.2; // Big number slide.addText(m.value, { x, y: 1.2, w: 2.8, h: 1.4, fontSize: 60, bold: true, color: COLORS.primary, align: "center" }); // Label slide.addText(m.label, { x, y: 2.7, w: 2.8, h: 0.5, fontSize: 14, color: COLORS.muted, align: "center" }); });
javascriptconst slide = pres.addSlide(); // Left column — text slide.addText("Problem", { x: 0.5, y: 0.3, w: 4.2, h: 0.5, fontSize: 24, bold: true, color: COLORS.dark }); slide.addText("The current checkout flow has a 23% drop-off rate on mobile...", { x: 0.5, y: 1.0, w: 4.2, h: 3.5, fontSize: 14, color: COLORS.dark, valign: "top" }); // Right column — image or chart slide.addImage({ path: "chart.png", x: 5.2, y: 0.5, w: 4.3, h: 4.5 });
javascript// ❌ WRONG — # prefix corrupts the file color: "#FF0000" // ✅ CORRECT — 6 hex chars, no # color: "FF0000" // ❌ WRONG — sharing option objects causes corruption const shadow = { type: "outer", blur: 3, offset: 2, color: "000000" }; slide1.addShape(pptx.ShapeType.rect, { shadow }); // mutates shadow object slide2.addShape(pptx.ShapeType.rect, { shadow }); // now uses corrupted values // ✅ CORRECT — fresh object per call const makeShadow = () => ({ type: "outer", blur: 3, offset: 2, color: "000000" }); slide1.addShape(pptx.ShapeType.rect, { shadow: makeShadow() }); slide2.addShape(pptx.ShapeType.rect, { shadow: makeShadow() }); // ❌ WRONG — shadow offset must be >= 0 shadow: { offset: -2 } // corrupts file // ✅ CORRECT shadow: { offset: 2 }
pythonfrom pptx import Presentation from pptx.util import Inches, Pt, Emu from pptx.dml.color import RGBColor from pptx.enum.text import PP_ALIGN prs = Presentation() prs.slide_width = Inches(13.33) prs.slide_height = Inches(7.5) # Add a slide using blank layout blank_layout = prs.slide_layouts[6] slide = prs.slides.add_slide(blank_layout) # Add title text box txBox = slide.shapes.add_textbox(Inches(0.5), Inches(0.3), Inches(12), Inches(1)) tf = txBox.text_frame tf.word_wrap = True p = tf.add_paragraph() p.text = "Slide Title" p.font.bold = True p.font.size = Pt(36) p.font.color.rgb = RGBColor(0x1E, 0x3A, 0x5F) p.alignment = PP_ALIGN.LEFT prs.save("presentation.pptx")
bash# Unzip to inspect/edit mkdir deck_unpacked && cp deck.pptx deck.zip unzip deck.zip -d deck_unpacked/ # Slides are at: deck_unpacked/ppt/slides/slide1.xml, slide2.xml, etc. # Edit XML directly for text replacement, color changes, etc. # Repack cd deck_unpacked && zip -r ../deck_edited.pptx . && cd ..
For simple text replacement across all slides:
pythonfrom pptx import Presentation prs = Presentation("template.pptx") for slide in prs.slides: for shape in slide.shapes: if shape.has_text_frame: for para in shape.text_frame.paragraphs: for run in para.runs: run.text = run.text.replace("{{COMPANY}}", "Acme Corp") prs.save("output.pptx")
bash# Extract all text, slide by slide markitdown deck.pptx # Check for placeholder text (leftover template text) markitdown deck.pptx | grep -iE "\bx{3,}\b|lorem|ipsum|\bTODO|\[insert"
pythonfrom pptx import Presentation prs = Presentation("deck.pptx") for i, slide in enumerate(prs.slides, 1): print(f"\n--- Slide {i} ---") for shape in slide.shapes: if shape.has_text_frame: print(shape.text_frame.text)
| Palette | Primary | Accent | Background | |---|---|---|---| | Midnight Executive | 1E2761 | CADCFC | FFFFFF | | Forest & Moss | 2C5F2D | 97BC62 | F5F5F5 | | Coral Energy | F96167 | F9E795 | 2F3C7E | | Charcoal Minimal | 36454F | F2F2F2 | 212121 | | Teal Trust | 028090 | 00A896 | FFFFFF |
| Element | Size | Weight | |---|---|---| | Slide title | 36–44pt | Bold | | Section header | 20–24pt | Bold | | Body text | 14–16pt | Regular | | Captions / labels | 10–12pt | Regular |
Safe fonts (render correctly in both PowerPoint and LibreOffice): Arial, Calibri, Cambria, Times New Roman, Courier New
# prefix in color values (pptxgenjs)bash# 1. Content check — read all text markitdown output.pptx # 2. Check for leftover placeholder text markitdown output.pptx | grep -iE "\bx{3,}\b|lorem|ipsum|TODO|\[insert" # 3. Convert to PDF for visual check libreoffice --headless --convert-to pdf output.pptx # 4. Visual inspection checklist:
Visual QA checklist (check every slide):
pres.layout = "LAYOUT_16x9")# prefix, no 8-digit hexmarkitdown output.pptxlorem, TODO, [insert]Other measured skills in the registry, with their headline benchmark lift.