corespeed-slide

Generate professional PowerPoint (.pptx) presentations using JSX/TSX with Deno. Supports slides, text, shapes, tables, charts (bar, line, pie, donut), images, gradients, shadows, and flexible layouts. Use when a user asks to create presentations, slide decks, pitch decks, reports, or any PPTX file.

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "corespeed-slide" with this command: npx skills add zypher-agent/corespeed-slide

Corespeed PPTX — PowerPoint Generation with JSX

Generate professional .pptx files using TypeScript JSX via @pixel/pptx.

Workflow

  1. Write a .tsx file that exports a deck variable
  2. Run the generator to produce the .pptx

Usage

deno run --allow-read --allow-write --config {baseDir}/scripts/deno.json {baseDir}/scripts/generate.ts slides.tsx output.pptx [--json]
  • First arg: path to your .tsx slide file (must export const deck = ...)
  • Second arg: output .pptx filename
  • --json — structured JSON output for agent consumption

Design Principles

These rules are distilled from the three masters of presentation design:

  • Edward Tufte (Yale professor, The Visual Display of Quantitative Information) — maximize data-ink ratio, remove chartjunk, every pixel must earn its place
  • Nancy Duarte (designed Al Gore's An Inconvenient Truth, author of Slide:ology) — one idea per slide, visual contrast creates meaning, the audience is the hero
  • Garr Reynolds (author of Presentation Zen) — restraint, whitespace, signal over noise, simplicity is the ultimate sophistication

Follow these rules for every deck:

  1. One idea per slide (Duarte). If you need a second point, make a second slide.
  2. Font ≥ 24pt body, ≥ 32pt titles. If the audience can't read it from the back row, it's too small.
  3. Max 3 colors (Reynolds). One primary, one accent, one neutral. Derive the rest as tints/shades.
  4. Whitespace is design (Reynolds). Generous padding (≥ 0.5in slide margins, ≥ 0.2in element padding). Never fill every inch.
  5. Contrast over decoration (Duarte). No drop shadows unless essential. No gradients for ornament. Use contrast (size, weight, color) to create hierarchy.
  6. Data-ink ratio (Tufte). Every pixel should convey information. Remove gridlines, borders, and labels that don't add meaning.
  7. Visual hierarchy. Title → Key number/chart → Supporting text. The eye should know where to go instantly.
  8. Consistent rhythm. Same gaps, same padding, same font sizes across all slides. Use layout defaults on <Presentation>.
  9. 16:9 widescreen. Always set slideWidth={u.in(13.33)} slideHeight={u.in(7.5)} on <Presentation>. The library defaults to 4:3 which looks wrong on modern screens.

Preventing Text Overflow (critical)

The library uses fixed-size containers. Text that exceeds the container will overflow and be clipped. Follow these rules strictly:

  1. Use grow instead of fixed h whenever possible. Inside <Row> or <Column>, prefer grow={1} over explicit h={u.in(X)}. The layout engine will calculate the correct size.
  2. Budget height for text. Each line of 14pt text needs ~0.3in. A card with title + 4 bullet points needs at minimum: 0.3 (title) + 4×0.3 (bullets) + 0.6 (padding) = 1.8in. Always round up.
  3. Fewer words, never more containers. If text doesn't fit, shorten the text — don't shrink the font or the container.
  4. Max 5 bullet points per card. If you need more, split into two cards or two slides.
  5. Test the math. For <Align> with explicit h: count lines × 0.3in + padding × 2. If the result > h, increase h or cut text.
  6. Leave 20% headroom. If you calculate 2.0in needed, set h to at least 2.4in.
  7. Never nest <Align> with tight heights inside <Stack>. Use <Column> with grow instead — it flexes to fit content.
  8. Safe card pattern:
    {/* ✅ GOOD: grow handles height automatically */}
    <Column>
      <Shape preset="roundRect" style={cardStyle} grow={1}>
        <Text.P style={titleStyle}>Title</Text.P>
        <Text.P style={bodyStyle}>Body text here</Text.P>
      </Shape>
    </Column>
    
    {/* ❌ BAD: fixed h too small, text will overflow */}
    <Align x="center" y="center" w={u.in(3)} h={u.in(1.5)}>
      <Text>
        <Text.P>Title</Text.P>
        <Text.P>Line 1</Text.P>
        <Text.P>Line 2</Text.P>
        <Text.P>Line 3</Text.P>
        <Text.P>Line 4</Text.P>  {/* overflows! */}
      </Text>
    </Align>
    

Table Overflow Prevention (critical)

Tables are the most common source of overflow. Follow these rules:

  1. Column widths must sum to ≤ content width. For 16:9 slide with 1in padding each side: content width = 11.33in. All cols values must sum to ≤ 11.33in.

    // ✅ GOOD: 2.5 + 4.0 + 4.0 = 10.5in < 11.33in
    <Table cols={[u.in(2.5), u.in(4.0), u.in(4.0)]}>
    
    // ❌ BAD: 3.0 + 5.0 + 5.0 = 13.0in > 11.33in → overflows right
    <Table cols={[u.in(3.0), u.in(5.0), u.in(5.0)]}>
    
  2. Give tables grow weight in <Column>. <Column> distributes height equally by default. A table with 5 rows needs more space than a title. Use grow to allocate proportionally:

    // ✅ GOOD: table gets 4x the space of title
    <Column>
      <Text.P style={titleStyle}>Title</Text.P>       {/* grow=1 default */}
      <Table cols={[...]} grow={4}>                    {/* gets 4x height */}
        <Table.Row>...</Table.Row>
        ...
      </Table>
    </Column>
    
    // ❌ BAD: Column splits equally, table gets squeezed
    <Column>
      <Text.P>Label</Text.P>
      <Text.P>Title</Text.P>
      <Table cols={[...]}>    {/* gets only 1/3 of height → rows overflow */}
        ...5 rows...
      </Table>
    </Column>
    
  3. Budget row height. Each row of 12pt text needs ~0.45in (text + padding). Header row: 0.45in. A 5-row table needs: 0.45 + 4×0.45 = 2.25in minimum.

  4. Keep cell text short. Max ~40 chars per cell. If text wraps to 2 lines, the row needs 0.65in instead of 0.45in.

  5. Prefer fewer rows. Max 5-6 data rows per slide. If you need more, split into two slides.

Color Palettes (reference)

StyleBackgroundPrimaryAccentText
Dark (OpenAI)0D0D0D10A37F6E42D3FFFFFF
Warm (Anthropic)FDF6EED977061F4E791C1917
Clean (Apple)FFFFFF007AFFFF3B301D1D1F
Academic (Stanford)FFFFFF8C15152E2D292E2D29
Neutral (Stripe)F6F9FC635BFF0A25400A2540

Pick one palette. Don't mix.

Page Numbers

The library has no built-in page numbers. Use <Positioned> on every slide:

// Helper — put at top of every .tsx file
const TOTAL = 10; // update to actual slide count

// ⚠️ CRITICAL: <Positioned> coordinates are RELATIVE TO CONTENT AREA (after slide padding).
// For 16:9 slide (13.33 x 7.5in) with padding 0.8/1.0/0.7/1.0:
//   Content area = (13.33 - 1.0 - 1.0) x (7.5 - 0.8 - 0.7) = 11.33 x 6.0in
//   Bottom-right page number: x = contentWidth - 1.0, y = contentHeight - 0.4
const PageNum = ({ n }: { n: number }) => (
  <Positioned x={u.in(10.33)} y={u.in(5.6)} w={u.in(1)} h={u.in(0.4)}>
    <Text.P style={{ fontSize: u.font(12), fontColor: textColor, align: "right" }}>
      {n} / {TOTAL}
    </Text.P>
  </Positioned>
);

// Use on every slide — LAST child of <Slide> (renders on top, never occluded)
<Slide background={bg}>
  <Column>
    {/* ...slide content... */}
  </Column>
  <PageNum n={1} />  {/* ← MUST be last child for highest z-order */}
</Slide>

Rules:

  • Always add page numbers. They help the audience track progress and reference slides.
  • <Positioned> is relative to content area, NOT the slide origin. Calculate: slideWidth - leftPadding - rightPadding = contentWidth. Position within those bounds.
  • Use the main text color (not muted) — at 12pt it must be readable.
  • Place <PageNum> as the last child of <Slide> — PPTX has no z-index, rendering order = declaration order. Last element renders on top, so page numbers are never occluded by other content.

Writing Slides

Create a .tsx file. It must export a deck variable:

/** @jsxImportSource @pixel/pptx */
import { Align, clr, Presentation, Slide, Text, u } from "@pixel/pptx";

export const deck = (
  <Presentation title="My Deck" slideWidth={u.in(13.33)} slideHeight={u.in(7.5)}>
    <Slide background={{ kind: "solid", color: clr.hex("F7F4EE") }}>
      <Align x="center" y="center" w={u.in(8)} h={u.in(1.5)}>
        <Text.P style={{ fontSize: u.font(32), bold: true }}>
          Hello, World!
        </Text.P>
      </Align>
    </Slide>
  </Presentation>
);

Components

Layout

ComponentPurpose
<Presentation>Root container. Props: title, layout
<Slide>Single slide. Props: background, layout
<Row>Horizontal flex layout. Has <Row.Start>, <Row.End>
<Column>Vertical flex layout. Has <Column.Start>, <Column.End>
<Stack>Overlapping layers
<Align x y w h>Center/align a single child
<Positioned x y w h>Absolute positioning

Content

ComponentPurpose
<Text>Multi-paragraph text body. Props: gap, style
<Text.P>Single paragraph
<Text.Span>Inline text run
<Text.Bold>, <Text.Italic>, <Text.Underline>Inline formatting
<Text.Link href="...">Hyperlink
<Shape preset="...">Shape: rect, roundRect, ellipse, etc.
<Image src={bytes} w={...} h={...} />Embed image (Uint8Array)
<Table cols=[...]>Table with <Table.Row> and <Table.Cell>

Charts

ComponentPurpose
<Chart.Bar data={[...]} category="key" series={[...]} />Bar chart
<Chart.Line data={[...]} category="key" series={[...]} />Line chart
<Chart.Pie data={[...]} category="key" series={[...]} />Pie chart
<Chart.Donut data={[...]} category="key" series={[...]} />Donut chart

Units & Colors

import { u, clr } from "@pixel/pptx";

u.in(1)       // inches
u.cm(2.5)     // centimeters
u.pt(12)      // points
u.pct(50)     // percentage
u.font(24)    // font size (hundredths of a point)

clr.hex("1F4E79")  // hex color (no #)

Styling

Style props are plain objects. Use style on any component:

const style = {
  fill: { kind: "solid", color: clr.hex("1F4E79") },
  fontSize: u.font(24),
  fontColor: clr.hex("FFFFFF"),
  bold: true,
  italic: false,
  align: "center",
  verticalAlign: "middle",
  padding: u.in(0.2),
  shadow: {
    color: clr.hex("000000"),
    blur: u.emu(12000),
    distance: u.emu(4000),
    angle: 50,
    alpha: u.pct(18),
  },
  bullet: { kind: "char", char: "•" },
};

Backgrounds support solid, linear-gradient, and image.

Example: Professional Multi-Slide Deck (Anthropic-warm style)

/** @jsxImportSource @pixel/pptx */
import {
  Align, Chart, clr, Column, Presentation, Row, Shape, Slide,
  Stack, Table, Text, u, type Style,
} from "@pixel/pptx";

// --- Design tokens (pick ONE palette, use everywhere) ---
const bg     = clr.hex("FDF6EE");  // warm cream
const card   = clr.hex("FFFFFF");
const primary = clr.hex("D97706"); // amber
const dark   = clr.hex("1C1917");  // near-black
const muted  = clr.hex("78716C");  // warm gray
const accent = clr.hex("1F4E79");  // deep blue for charts

// --- Reusable styles ---
const s = {
  heroBar: {
    fill: { kind: "solid", color: primary },
    verticalAlign: "middle",
    padding: { top: u.in(0.3), right: u.in(0.5), bottom: u.in(0.3), left: u.in(0.5) },
  } satisfies Style,
  h1: { fontSize: u.font(36), fontColor: card, bold: true } satisfies Style,
  subtitle: { fontSize: u.font(16), fontColor: clr.hex("FEF3C7") } satisfies Style,
  h2: { fontSize: u.font(24), fontColor: dark, bold: true } satisfies Style,
  body: { fontSize: u.font(14), fontColor: muted } satisfies Style,
  bigNum: { fontSize: u.font(48), fontColor: primary, bold: true, align: "center" } satisfies Style,
  bigLabel: { fontSize: u.font(14), fontColor: muted, align: "center" } satisfies Style,
  cardBox: {
    fill: { kind: "solid", color: card },
    padding: u.in(0.3),
    shadow: { color: clr.hex("000000"), blur: u.emu(8000), distance: u.emu(2000), angle: 90, alpha: u.pct(8) },
  } satisfies Style,
};

export const deck = (
  <Presentation title="Q2 Review" slideWidth={u.in(13.33)} slideHeight={u.in(7.5)} layout={{
    slidePadding: u.in(0.6),
    rowGap: u.in(0.35),
    columnGap: u.in(0.35),
  }}>

    {/* Slide 1: Title — one idea only */}
    <Slide background={{ kind: "solid", color: bg }}>
      <Column>
        <Shape preset="roundRect" h={u.in(1.6)} style={s.heroBar}>
          <Text.P style={s.h1}>Q2 2025 Review</Text.P>
          <Text.P style={s.subtitle}>Growth ahead of plan · 15% QoQ</Text.P>
        </Shape>
        <Row>
          {/* Big number cards — Tufte: let the data speak */}
          {[
            { num: "$1.2M", label: "Revenue" },
            { num: "15%", label: "Growth" },
            { num: "61", label: "NPS" },
          ].map(({ num, label }) => (
            <Stack grow={1}>
              <Shape preset="roundRect" style={s.cardBox} />
              <Align x="center" y="center" w={u.in(2.5)} h={u.in(2.5)}>
                <Text gap={u.in(0.1)}>
                  <Text.P style={s.bigNum}>{num}</Text.P>
                  <Text.P style={s.bigLabel}>{label}</Text.P>
                </Text>
              </Align>
            </Stack>
          ))}
        </Row>
      </Column>
    </Slide>

    {/* Slide 2: Chart — one chart, full focus */}
    <Slide background={{ kind: "solid", color: bg }}>
      <Column>
        <Text.P style={s.h2}>Revenue by Quarter</Text.P>
        <Stack grow={1}>
          <Shape preset="roundRect" style={s.cardBox} />
          <Align x="center" y="center" w={u.in(8)} h={u.in(4)}>
            <Chart.Bar
              data={[
                { q: "Q1", rev: 0.8 }, { q: "Q2", rev: 1.2 },
                { q: "Q3", rev: 1.0 }, { q: "Q4", rev: 1.5 },
              ]}
              category="q"
              series={[{ name: "Revenue ($M)", value: "rev", color: accent }]}
              labels
              valueAxis={{ min: 0, max: 2 }}
            />
          </Align>
        </Stack>
      </Column>
    </Slide>

  </Presentation>
);

Notes

  • No manual setup required. Deno auto-downloads @pixel/pptx from JSR on first run.
  • The .tsx file must export const deck = ... (the JSX Presentation element).
  • Use --json for structured output: {"ok": true, "file": "...", "size": 1234}
  • Output opens in PowerPoint, Google Slides, LibreOffice Impress, and Keynote.
  • Use timestamps in filenames: yyyy-mm-dd-hh-mm-ss-name.pptx.

Support

Built by Corespeed. If you need help or run into issues:

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Multi Edge-TTS CN

Edge-TTS 在线语音合成 skill。基于微软 Edge TTS 引擎,生成速度快(1-2秒),支持多种音色和输出格式。同时支持飞书(OGG/Opus)和企业微信(AMR)。默认音色 xiaoxiao_lively。需联网。

Registry SourceRecently Updated
General

vedic-destiny

吠陀命盘分析中文入口。用于完整命盘研判、命主盘 Rashi chart 与九分盘 Navamsha chart 联读、既往事件回看、出生时间稳定度判断、事业主题、婚姻主题、时空盘专题,以及基于 Jagannatha Hora PDF、星盘截图或文本命盘数据的系统拆盘。当用户提到完整星盘、事业方向、婚姻问题、关系窗...

Registry SourceRecently Updated
General

One Person Company OS

Build a visual operating cockpit for an AI-native one-person company across promise, buyer, product, delivery, cash, learning, and assets. / 为 AI 一人公司建立可视化经营...

Registry SourceRecently Updated
General

健康追踪

健康追踪技能 - 追踪饮水、睡眠、步数等健康数据,JSON存储。

Registry SourceRecently Updated