PptxGenJS Slide Making Skill
This skill teaches how to generate native .pptx slides using PptxGenJS (JavaScript).
PptxGenJS Reference
Read pptxgenjs.md for the complete PptxGenJS API reference, including:
- Setup & basic structure
- Text & formatting
- Lists & bullets
- Shapes & shadows
- Images & icons
- Slide backgrounds
- Tables & charts
Font Rules
Font Family Standards
| Language | Default | Alternatives |
|---|---|---|
| Chinese | Microsoft YaHei (微软雅黑) | — |
| English | Arial | Georgia, Calibri, Cambria, Trebuchet MS |
javascriptfontFace: "Microsoft YaHei" // Chinese text fontFace: "Arial" // English text (or approved alternative)
Use system-safe fonts for cross-platform compatibility. Header/body can use different fonts (e.g., Georgia + Calibri).
No Bold for Body Text
Plain body text and caption/legend text must NOT use bold.
- Body paragraphs, descriptions → normal weight
- Captions, legends, footnotes → normal weight
- Reserve bold for titles and headings only
javascript// ✅ Correct slide.addText("Main Title", { bold: true, fontSize: 36, fontFace: "Arial" }); slide.addText("Body text here.", { bold: false, fontSize: 14, fontFace: "Arial" }); // ❌ Wrong slide.addText("Body text here.", { bold: true, fontSize: 14 });
Color Palette Rules (MANDATORY)
Strict Palette Adherence
Use ONLY the provided color palette. Do NOT create or modify colors.
- All colors must come from the user-provided palette
- Do NOT use colors outside the palette
- Do NOT modify palette colors (brightness, saturation, mixing)
- Only exception: Add transparency using the
transparencyproperty (0-100)
javascript// ✅ Correct: Using palette colors slide.addShape(pres.shapes.RECTANGLE, { fill: { color: theme.primary } }); slide.addText("Title", { color: theme.accent }); // ❌ Wrong: Colors outside palette slide.addShape(pres.shapes.RECTANGLE, { fill: { color: "1a1a2e" } });
No Gradients
Gradients are prohibited. Use solid colors only.
javascript// ✅ Correct: Solid colors slide.background = { color: theme.bg }; // ✅ Correct: Solid + transparency for overlay slide.addShape(pres.shapes.RECTANGLE, { fill: { color: theme.accent, transparency: 50 } });
No Animations
Animations and transitions are prohibited. All slides must be static.
Page Number Badge (REQUIRED)
All slides except Cover Page MUST include a page number badge in the bottom-right corner.
- Position: x: 9.3", y: 5.1"
- Show current number only (e.g.
3or03), NOT "3/12" - Use palette colors, keep subtle
Circle Badge (Default)
javascriptslide.addShape(pres.shapes.OVAL, { x: 9.3, y: 5.1, w: 0.4, h: 0.4, fill: { color: theme.accent } }); slide.addText("3", { x: 9.3, y: 5.1, w: 0.4, h: 0.4, fontSize: 12, fontFace: "Arial", color: "FFFFFF", bold: true, align: "center", valign: "middle" });
Pill Badge
javascriptslide.addShape(pres.shapes.ROUNDED_RECTANGLE, { x: 9.1, y: 5.15, w: 0.6, h: 0.35, fill: { color: theme.accent }, rectRadius: 0.15 }); slide.addText("03", { x: 9.1, y: 5.15, w: 0.6, h: 0.35, fontSize: 11, fontFace: "Arial", color: "FFFFFF", bold: true, align: "center", valign: "middle" });
Theme Object Contract (MANDATORY)
The compile script passes a theme object with these exact keys:
| Key | Purpose | Example |
|---|---|---|
theme.primary | Darkest color, titles | "22223b" |
theme.secondary | Dark accent, body text | "4a4e69" |
theme.accent | Mid-tone accent | "9a8c98" |
theme.light | Light accent | "c9ada7" |
theme.bg | Background color | "f2e9e4" |
NEVER use other key names like background, text, muted, darkest, lightest.
Subagent Output Format
Each subagent outputs a complete, runnable JS file:
javascript// slide-01.js const pptxgen = require("pptxgenjs"); const slideConfig = { type: 'cover', index: 1, title: 'Presentation Title' }; // ⚠️ MUST be synchronous (not async) function createSlide(pres, theme) { const slide = pres.addSlide(); slide.background = { color: theme.bg }; slide.addText(slideConfig.title, { x: 0.5, y: 2, w: 9, h: 1.2, fontSize: 48, fontFace: "Arial", // English text uses Arial color: theme.primary, bold: true, align: "center" }); return slide; } // Standalone preview - use slide-specific filename (slide-XX-preview.pptx) if (require.main === module) { const pres = new pptxgen(); pres.layout = 'LAYOUT_16x9'; const theme = { primary: "22223b", secondary: "4a4e69", accent: "9a8c98", light: "c9ada7", bg: "f2e9e4" }; createSlide(pres, theme); // Replace XX with actual slide index (01, 02, etc.) to avoid conflicts pres.writeFile({ fileName: "slide-01-preview.pptx" }); } module.exports = { createSlide, slideConfig };
Critical Pitfalls
NEVER use async/await in createSlide()
javascript// ❌ WRONG - compile.js won't await async function createSlide(pres, theme) { ... } // ✅ CORRECT function createSlide(pres, theme) { ... }
NEVER use "#" with hex colors
javascriptcolor: "FF0000" // ✅ CORRECT color: "#FF0000" // ❌ CORRUPTS FILE
NEVER encode opacity in hex strings
javascriptshadow: { color: "00000020" } // ❌ CORRUPTS FILE shadow: { color: "000000", opacity: 0.12 } // ✅ CORRECT
Prevent text wrapping in titles
javascript// ✅ Use fit:'shrink' for long titles slide.addText("Long Title Here", { x: 0.5, y: 2, w: 9, h: 1, fontSize: 48, fit: "shrink" });
Quick Reference
- Dimensions: 10" × 5.625" (LAYOUT_16x9)
- Colors: 6-char hex without # (e.g.,
"FF0000") - English font: Arial (default), or approved alternatives
- Chinese font: Microsoft YaHei
- Page badge position: x: 9.3", y: 5.1"
QA (Required)
Assume there are problems. Your job is to find them.
Your first render is almost never correct. Approach QA as a bug hunt, not a confirmation step. If you found zero issues on first inspection, you weren't looking hard enough.
Content QA
bashpython -m markitdown slide-XX-preview.pptx
Check for missing content, typos, wrong order.
Check for leftover placeholder text:
bashpython -m markitdown slide-XX-preview.pptx | grep -iE "xxxx|lorem|ipsum|placeholder"
If grep returns results, fix them before declaring success.
Verification Loop
- Generate slide → Extract text with
python -m markitdown slide-XX-preview.pptx→ Review content - List issues found (if none found, look again more critically)
- Fix issues
- Re-verify — one fix often creates another problem
- Repeat until verification reveals no new issues
Do not declare success until you've completed at least one fix-and-verify cycle.

