Gamma Migration Deep Dive
SkillDev tools'Deep dive into migrating to Gamma from other presentation platforms.
Use Gamma Migration Deep Dive in Claude, ChatGPT or Ahel Desktop
Free. Sign in, add Gamma Migration Deep Dive and connect your AI. About a minute.
Also: Claude Code · Cursor · Codex
Then ask your AI: use the Gamma Migration Deep Dive skill
Details
Instructions available. Your AI can read the instructions. Execution depends on the setup they require.
Account requirements not reviewed. Check the skill instructions before use; Ahel provides instructions and does not run this skill.
No other account needed.
Add Ahel to your AI once: Claude, ChatGPT, Cursor, Claude Code or Codex. Then ask it to use this.
What this skill tells your AI
The instructions your AI receives, as published by jeremylongshore/tons-of-skills-marketplace in skills/.curated/gamma-migration-deep-dive/SKILL.md and read by Ahel’s review.
Output
Record source/target scope, mapping decision, staging and canary results, aggregate reconciliation, approver, and rollback state without copying content or viewer data.
Examples
Migrate a fictional presentation in staging, compare approved metadata and route behavior, introduce an unknown field, and confirm the canary stops for review.
Current State
!npm list 2>/dev/null | head -10
Overview
Migrate presentation workflows from PowerPoint, Google Slides, Canva, or other platforms to Gamma's AI-powered generation. Gamma takes a fundamentally different approach -- instead of manually placing slides, you provide content and Gamma generates the presentation. Migration is about converting your content pipeline, not your slide files.
Prerequisites
- Gamma API access (Pro+ plan)
- Source presentations accessible for content extraction
- Node.js 18+ for migration scripts
- Completed
gamma-install-authsetup
Migration Approaches
| Approach | When to Use | Effort |
|---|---|---|
| Content extraction + regeneration | Lots of text-heavy presentations | Medium |
| Import via Gamma UI | One-off migration of key decks | Low |
| Template recreation | Repeatable presentation formats | Medium |
| Parallel operation | Gradual transition over time | Low |
Key insight: You don't "import" slides into Gamma. You extract content from old presentations and regenerate them using Gamma's AI. This often produces better results than the originals.
Instructions
Step 1: Inventory Source Presentations
// scripts/inventory-presentations.ts
import { readdir, stat } from "node:fs/promises";
import { join, extname } from "node:path";
interface PresentationInfo {
path: string;
format: string;
sizeMB: number;
lastModified: Date;
}
async function inventoryPresentations(dir: string): Promise<PresentationInfo[]> {
const entries = await readdir(dir, { recursive: true });
const presentations: PresentationInfo[] = [];
for (const entry of entries) {
const ext = extname(entry).toLowerCase();
if ([".pptx", ".ppt", ".key", ".pdf", ".md"].includes(ext)) {
const fullPath = join(dir, entry);
const info = await stat(fullPath);
presentations.push({
path: fullPath,
format: ext,
sizeMB: info.size / (1024 * 1024),
lastModified: info.mtime,
});
}
}
console.log(`Found ${presentations.length} presentations:`);
const byFormat = presentations.reduce((acc, p) => {
acc[p.format] = (acc[p.format] || 0) + 1;
return acc;
}, {} as Record<string, number>);
console.log("By format:", byFormat);
return presentations;
}
Step 2: Extract Content from PowerPoint
// scripts/extract-pptx.ts
// Use 'pptx-parser' or 'officegen' to extract text content
import JSZip from "jszip";
import { readFile } from "node:fs/promises";
import { DOMParser } from "xmldom";
async function extractPptxContent(pptxPath: string): Promise<string[]> {
const buffer = await readFile(pptxPath);
const zip = await JSZip.loadAsync(buffer);
const slides: string[] = [];
const slideFiles = Object.keys(zip.files)
.filter((f) => f.match(/ppt\/slides\/slide\d+\.xml$/))
.sort();
for (const slideFile of slideFiles) {
const xml = await zip.file(slideFile)!.async("string");
const doc = new DOMParser().parseFromString(xml);
// Extract all text elements
const textNodes = doc.getElementsByTagName("a:t");
const texts: string[] = [];
for (let i = 0; i < textNodes.length; i++) {
const text = textNodes[i].textContent?.trim();
if (text) texts.push(text);
}
slides.push(texts.join("\n"));
}
return slides;
}
// Convert extracted content to Gamma prompt
function slidesToGammaPrompt(slides: string[], title: string): string {
let prompt = `${title}\n\n`;
slides.forEach((content, i) => {
prompt += `Slide ${i + 1}:\n${content}\n\n`;
});
return prompt;
}
Step 3: Batch Migration Script
// scripts/migrate-to-gamma.ts
import { createGammaClient } from "../src/client";
import { pollUntilDone } from "../src/poll";
import pLimit from "p-limit";
const gamma = createGammaClient({ apiKey: process.env.GAMMA_API_KEY! });
const limit = pLimit(2); // Max 2 concurrent generations
interface MigrationItem {
title: string;
content: string;
sourceFile: string;
}
async function migrateBatch(items: MigrationItem[]) {
const results = await Promise.allSettled(
items.map((item) =>
limit(async () => {
console.log(`Migrating: ${item.title}`);
const { generationId } = await gamma.generate({
content: item.content,
outputFormat: "presentation",
textMode: "condense", // AI condenses extracted text
exportAs: "pptx", // Get PPTX for comparison
});
const result = await pollUntilDone(gamma, generationId);
return {
title: item.title,
sourceFile: item.sourceFile,
gammaUrl: result.gammaUrl,
exportUrl: result.exportUrl,
creditsUsed: result.creditsUsed,
};
})
)
);
// Report
const succeeded = results.filter((r) => r.status === "fulfilled");
const failed = results.filter((r) => r.status === "rejected");
console.log(`\nMigration complete: ${succeeded.length} succeeded, ${failed.length} failed`);
for (const r of results) {
if (r.status === "fulfilled") {
console.log(` OK: ${r.value.title} → ${r.value.gammaUrl}`);
} else {
console.log(` FAIL: ${r.reason}`);
}
}
}
Step 4: Template Recreation
For recurring presentation types (weekly reports, proposals, etc.), create Gamma templates:
Migration steps for templates:
1. Identify repeating presentation formats in your org
2. Create a one-page template gamma in the Gamma app:
- gamma.app → Create → design a single representative page
3. Note the template gamma ID from the URL
4. Use POST /v1.0/generations/from-template with the gammaId
5. Update your automation scripts to use generateFromTemplate()
// After template creation in Gamma UI
const MIGRATED_TEMPLATES: Record<string, string> = {
"weekly-report": "gamma_template_weekly_abc123",
"sales-proposal": "gamma_template_proposal_def456",
"team-update": "gamma_template_update_ghi789",
};
async function generateFromMigratedTemplate(
templateKey: string,
content: string
) {
const gammaId = MIGRATED_TEMPLATES[templateKey];
if (!gammaId) throw new Error(`Unknown template: ${templateKey}`);
const { generationId } = await gamma.generateFromTemplate({
gammaId,
prompt: content,
exportAs: "pdf",
});
return pollUntilDone(gamma, generationId);
}
Step 5: Validation Checklist
After migrating each presentation:
- [ ] Content accuracy: AI-generated text matches source intent
- [ ] Slide count: reasonable for the content volume
- [ ] Theme/branding: workspace theme applied correctly
- [ ] Export quality: PDF/PPTX downloads successfully
- [ ] Links preserved: any URLs from original are in the content
- [ ] Stakeholder review: key presentations reviewed by owners
Supported Migration Paths
| Source | Method | Fidelity | Notes |
|---|---|---|---|
| PowerPoint (.pptx) | Extract text → regenerate | Content-high, design-new | AI redesigns slides |
| Google Slides | Export as .pptx → extract | Content-high, design-new | Export first |
| Canva | Export as .pdf → extract text | Medium | Limited text extraction |
| Keynote (.key) | Export as .pptx → extract | Content-high, design-new | Export first |
| Markdown (.md) | Direct use as content | High | Best migration path |
| Notion pages | Export as .md → use directly | High | Clean text extraction |
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Content too long | Exceeds 100K token limit | Split into multiple presentations |
| Credit budget exceeded | Too many migrations at once | Batch over multiple days |
| Poor output quality | Content too unstructured | Add structure (headings, bullets) to extracted content |
| Missing images | Images in source not extracted | Gamma generates new images; reference image concepts in text |
Resources
Next Steps
Review gamma-core-workflow-a for ongoing content generation after migration.
Signals
- GitHub stars
- 3k
- Forks
- 415
- Last commit
- Oct 2026
Advanced
- Item type
- skill
- Key
gamma-migration-deep-dive- Source
- github.com/jeremylongshore/tons-of-skills-marketplace
github.com/jeremylongshore/tons-of-skills-marketplace
Related picks
Skill · thedaviddias
The pick for JavaScriptmodern-javascript-patterns
Skill · wshobson
The pick for JavaScriptsetup-ts-deep-modules
Skill · mattpocock
The pick for TypeScripttypescript-pro
Skill · jeffallan
The pick for TypeScriptgoogle-slides-export
Skill · ai-analyst-lab
The pick for Google Slidesgoogleslides-automation
Skill · composio-community
The pick for Google Slides