npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@tech-alfia/pitch-deck-editor

v1.1.2

Published

A reusable pitch deck editor component library

Readme

Pitch Deck Editor Library

A reusable Canva-like pitch deck editor component that can be integrated into any React project.

Features

  • Drag-and-drop slide editor
  • Rich text elements
  • Shapes and icons
  • Image support
  • Tables and charts
  • Drawing tools
  • AI panel integration
  • Template library
  • Presentation mode
  • Undo/redo functionality
  • Auto-save with custom API endpoints
  • Dark/light theme support
  • Fully customizable API layer

Documentation

| Document | Audience | |----------|----------| | docs/PITCH_DECK_EDITOR_SPEC.md | Full JSON schema, element types, canvas rules, React/API integration | | docs/AI_GENERATION_PROMPT.md | Copy-paste system prompt: editor tools + JSON rules only (no fixed slide templates) |

Use these when wiring AI-generated decks in production: the system prompt explains capabilities; the user message carries topic, outline, and brand. Pass parsed JSON as initialDeck to PitchDeckEditor.


Installation

Install the package:

npm install @tech-alfia/pitch-deck-editor

If you use pnpm:

pnpm add @tech-alfia/pitch-deck-editor

Required Setup

This library depends on Tailwind CSS v3.

1. Install Tailwind CSS

pnpm install -D tailwindcss@3

Or with npm:

npm install -D tailwindcss@3

2. Initialize Tailwind

npx tailwindcss init

3. Generate Tailwind CSS Output

npx tailwindcss -i ./src/index.css -o ./src/app.css --watch

4. Configure tailwind.config.js

/** @type {import('tailwindcss').Config} */
export default {
  content: [
    "./index.html",
    "./src/**/*.{js,jsx,ts,tsx}",
    "./node_modules/@alfia/pitch-deck-editor/dist/**/*.{js,jsx,ts,tsx}"
  ],
  darkMode: "class",
  theme: {
    extend: {
      colors: {
        "alfia-black": "#000000",
        "alfia-white": "#ffffff",

        "alfia-bg-root": "#000000",
        "alfia-bg-surface": "#0b0b0b",
        "alfia-bg-elevated": "#111111",
        "alfia-bg-hover": "#1a1a1a",
        "alfia-bg-active": "#222222",

        "alfia-bg-root-light": "#ffffff",
        "alfia-bg-surface-light": "#F9F9F9",
        "alfia-bg-elevated-light": "#fafafa",
        "alfia-bg-hover-light": "#EAEAEA",
        "alfia-bg-active-light": "#EAEAEA",

        "alfia-border-subtle": "#1f1f1f",
        "alfia-border-default": "#2a2a2a",
        "alfia-border-strong": "#3a3a3a",

        "alfia-border-subtle-light": "#e0e0e0",
        "alfia-border-default-light": "#d4d4d4",
        "alfia-border-strong-light": "#b3b3b3",

        "alfia-text-primary": "#ffffff",
        "alfia-text-secondary": "#b3b3b3",
        "alfia-text-muted": "#7a7a7a",
        "alfia-text-disabled": "#4d4d4d",
        "alfia-text-inverse": "#000000",

        "alfia-text-primary-light": "#000000",
        "alfia-text-secondary-light": "#838383",
        "alfia-text-muted-light": "#7a7a7a",
        "alfia-text-disabled-light": "#b3b3b3",
        "alfia-text-inverse-light": "#ffffff",

        "alfia-btn-primary": "#ffffff",
        "alfia-btn-primary-hover": "#e6e6e6",
        "alfia-btn-secondary": "#1a1a1a",
        "alfia-btn-secondary-hover": "#262626",
        "alfia-btn-ghost-hover": "#1f1f1f",

        "alfia-btn-primary-light": "#000000",
        "alfia-btn-primary-hover-light": "#1a1a1a",
        "alfia-btn-secondary-light": "#f5f5f5",
        "alfia-btn-secondary-hover-light": "#e6e6e6",
        "alfia-btn-ghost-hover-light": "#e0e0e0",

        "alfia-icon-default": "#b3b3b3",
        "alfia-icon-active": "#ffffff",
        "alfia-icon-muted": "#666666",

        "alfia-icon-default-light": "#4d4d4d",
        "alfia-icon-active-light": "#000000",
        "alfia-icon-muted-light": "#7a7a7a",

        "alfia-grad-start": "#ffffff",
        "alfia-grad-mid": "#bfbfbf",
        "alfia-grad-end": "#000000",

        "alfia-accent": "#3b82f6",
        "alfia-accent-hover": "#2563eb",

        "alfia-status-pending": "#6b7280",
        "alfia-status-rejected": "#dc2626",
        "alfia-status-live": "#16a34a",
        "alfia-status-upcoming": "#2563eb",
        "alfia-status-completed": "#6b7280",
      },

      backgroundImage: {
        "alfia-gradient-main":
          "linear-gradient(135deg, #ffffff 0%, #bfbfbf 50%, #000000 100%)",
      },

      keyframes: {
        "ai-glow-border": {
          "0%": { backgroundPosition: "0% 50%" },
          "100%": { backgroundPosition: "100% 50%" },
        },
      },

      animation: {
        "ai-glow-border": "ai-glow-border 3.5s linear infinite",
      },
    },
  },

  plugins: [],
};

5. Configure postcss.config.js

export default {
  plugins: {
    tailwindcss: {},
  },
}

6. Import Your CSS File

Inside your main entry file (main.jsx, main.tsx, etc.):

import "./app.css";

Usage

Basic Usage

import React from 'react';
import { PitchDeckEditor } from '@alfia/pitch-deck-editor';

function App() {
  const handleDeckChange = (deck) => {
    console.log('Deck changed:', deck);
  };

  return (
    <div style={{ height: '100vh' }}>
      <PitchDeckEditor
        initialDeck={null}
        onChange={handleDeckChange}
        onNavigateBack={() => console.log('Navigate back')}
      />
    </div>
  );
}

export default App;

With Custom API Integration

import React from 'react';
import { PitchDeckEditor } from '@alfia/pitch-deck-editor';

function App() {
  const apiClient = {
    updatePitchDeck: async (deckId, payload) => {
      const response = await fetch(`/api/decks/${deckId}`, {
        method: 'PATCH',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });

      return response.json();
    },

    getPitchDeck: async (deckId) => {
      const response = await fetch(`/api/decks/${deckId}`);
      return response.json();
    }
  };

  return (
    <div style={{ height: '100vh' }}>
      <PitchDeckEditor
        initialDeck={null}
        apiClient={apiClient}
        deckId="my-deck-id"
        onChange={(deck) => console.log(deck)}
        onNavigateBack={() => console.log('Back')}
      />
    </div>
  );
}

export default App;

With AI Integration

import React from 'react';
import { PitchDeckEditor } from '@alfia/pitch-deck-editor';

function App() {
  const ai = {
    generateSlide: async (prompt) => {
      // Your AI generation logic
    },

    improveDeck: async (deck) => {
      // Your AI deck improvement logic
    }
  };

  return (
    <div style={{ height: '100vh' }}>
      <PitchDeckEditor
        initialDeck={null}
        ai={ai}
        onChange={(deck) => console.log(deck)}
        onNavigateBack={() => console.log('Back')}
      />
    </div>
  );
}

export default App;

API Reference

PitchDeckEditor Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | initialDeck | Object | No | Initial deck state | | onChange | Function | Yes | Callback when deck changes | | onNavigateBack | Function | Yes | Callback for back navigation | | saveStatus | String | No | Save status (idle, saving, saved, error) | | className | String | No | Additional CSS classes | | apiClient | Object | No | Custom API client for persistence | | deckId | String | No | Deck ID for API operations | | ai | Object | No | AI integration methods |


API Client Interface

interface ApiClient {
  updatePitchDeck: (deckId: string, payload: any) => Promise<any>;
  getPitchDeck?: (deckId: string) => Promise<any>;
  createPitchDeck?: (payload: any) => Promise<any>;
  deletePitchDeck?: (deckId: string) => Promise<any>;
}

Re-exported Hooks and Types

import {
  useEditor,
  createEmptyEditorDeck,
  ElementType,
  ShapeType,
  BackgroundType,
  CANVAS_WIDTH,
  CANVAS_HEIGHT,
  FONT_FAMILIES,
  DEFAULT_THEME
} from '@alfia/pitch-deck-editor';

Development

# Install dependencies
npm install

# Build the library
npm run build

# Run development mode
npm run dev

# Run tests
npm test

# Lint code
npm run lint

Troubleshooting

Tailwind styles are not working

Make sure:

  • Tailwind CSS v3 is installed
  • The library path is included inside content
  • Your generated CSS file is imported
  • The Tailwind watcher/build process is running

Correct path:

"./node_modules/@alfia/pitch-deck-editor/dist/**/*.{js,jsx,ts,tsx}"

Dark mode does not work

Ensure your application adds the dark class to the root HTML element:

document.documentElement.classList.add("dark");

License

MIT License — see LICENSE file for details.