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

lexical-pdf

v0.1.5

Published

Convert Lexical editor content to PDF - Core function and React component

Readme

⭐ If you find this useful, please consider starring the repo!

It helps others discover the project and motivates continued development.

🤝 Looking for contributors! Whether it's bug fixes, new features, or documentation improvements, all contributions are welcome. See Contributing below to get started.

lexical-pdf

npm version npm downloads license

Convert Lexical editor content to PDF with ease in the browser. This package provides both a core function for any frontend framework (Vue, Svelte, Angular, vanilla JS) and a ready-to-use React component.

Features

  • 🔧 Core Function: Use with any frontend framework (Vue, Svelte, Angular, vanilla JS)
  • ⚛️ React Component: Drop-in PDF download button with customizable styling
  • 📄 High Quality: Uses html2canvas and jsPDF for crisp PDF generation
  • 🎨 Customizable: Configure page size, orientation, scaling, and more
  • 🔒 Type Safe: Full TypeScript support with comprehensive types
  • 📦 Lightweight: Minimal dependencies, optional React support

Installation

For React Usage

npm install lexical-pdf lexical @lexical/html react @lexical/react lucide-react

For Core Usage (Vue, Svelte, Angular, Vanilla JS)

npm install lexical-pdf lexical @lexical/html

Usage

React Component

Use the DownloadPDFPlugin component in your Lexical React setup:

import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
import { DownloadPDFPlugin } from "lexical-pdf/react";

function MyEditor() {
  return (
    <LexicalComposer initialConfig={editorConfig}>
      <div className="editor-container">
        <RichTextPlugin
          contentEditable={<ContentEditable />}
          placeholder={<div>Enter some text...</div>}
          ErrorBoundary={ErrorBoundary}
        />
        {/* PDF Export Button */}
        <DownloadPDFPlugin filename="my-document.pdf" />

        {/* Custom PDF Button with fast compression */}
        <DownloadPDFPlugin
          filename="custom.pdf"
          containerClassName="flex justify-center"
          compression="FAST"
        >
          <button className="px-4 py-2 bg-blue-500 text-white rounded">
            Export PDF
          </button>
        </DownloadPDFPlugin>

        {/* Custom icon styling */}
        <DownloadPDFPlugin
          filename="styled-icon.pdf"
          iconSize={24}
          iconColor="#3b82f6"
          iconStrokeWidth={2}
        />
      </div>
    </LexicalComposer>
  );
}

Core Function

Use the core exportToPdf function with any frontend framework:

import { exportToPdf } from "lexical-pdf";
import { LexicalEditor } from "lexical";

// Basic usage
await exportToPdf(editor);

// With custom options
await exportToPdf(editor, {
  filename: "my-document.pdf",
  orientation: "landscape",
  format: "a4",
  scale: 2,
  compression: "FAST",
});

Vue Example

<template>
  <div>
    <div ref="editorContainer"></div>
    <button @click="exportPdf">Export PDF</button>
  </div>
</template>

<script>
import { exportToPdf } from "lexical-pdf";

export default {
  methods: {
    async exportPdf() {
      try {
        await exportToPdf(this.lexicalEditor, {
          filename: "vue-document.pdf",
        });
      } catch (error) {
        console.error("Export failed:", error);
      }
    },
  },
};
</script>

Svelte Example

<script>
  import { exportToPdf } from 'lexical-pdf';

  let lexicalEditor;

  async function handleExportPdf() {
    try {
      await exportToPdf(lexicalEditor, {
        filename: 'svelte-document.pdf'
      });
    } catch (error) {
      console.error('Export failed:', error);
    }
  }
</script>

<div>
  <div bind:this={editorContainer}></div>
  <button on:click={handleExportPdf}>Export PDF</button>
</div>

Angular Example

// component.ts
import { Component } from "@angular/core";
import { exportToPdf } from "lexical-pdf";

@Component({
  selector: "app-editor",
  template: `
    <div #editorContainer></div>
    <button (click)="exportPdf()">Export PDF</button>
  `,
})
export class EditorComponent {
  lexicalEditor: any; // Your Lexical editor instance

  async exportPdf() {
    try {
      await exportToPdf(this.lexicalEditor, {
        filename: "angular-document.pdf",
      });
    } catch (error) {
      console.error("Export failed:", error);
    }
  }
}

API Reference

exportToPdf(editor, options?)

Parameters

  • editor (LexicalEditor): The Lexical editor instance
  • options (ExportToPdfOptions, optional): Configuration options

Options

interface ExportToPdfOptions {
  filename?: string; // Default: "document.pdf"
  containerWidth?: string; // Default: "816px" (letter width)
  containerHeight?: string; // Default: "1056px" (letter height)
  containerPadding?: string; // Default: "30px"
  orientation?: "portrait" | "landscape"; // Default: "portrait"
  format?: string | number[]; // Default: "letter" (jsPDF formats)
  scale?: number; // Default: 3 (higher = better quality)
  compression?: "NONE" | "FAST" | "MEDIUM" | "SLOW"; // Default: "SLOW"
}

Returns

  • Promise<void>: Resolves when PDF is generated and downloaded

DownloadPDFPlugin React Component

Props

interface DownloadPDFPluginProps {
  filename?: string; // Default: "document.pdf"
  children?: ReactNode; // Custom button content
  containerClassName?: string; // Default: "flex w-full justify-end"
  containerWidth?: string; // Default: "816px"
  containerHeight?: string; // Default: "1056px"
  containerPadding?: string; // Default: "30px"
  compression?: "NONE" | "FAST" | "MEDIUM" | "SLOW"; // Default: "SLOW"
  iconSize?: number; // Default: 18
  iconColor?: string; // Default: undefined (uses theme)
  iconStrokeWidth?: number; // Default: undefined (uses lucide default)
}

Advanced Examples

Custom Page Formats

// A4 landscape
await exportToPdf(editor, {
  format: "a4",
  orientation: "landscape",
});

// Custom size (width, height in points)
await exportToPdf(editor, {
  format: [595, 842], // A4 in points
  orientation: "portrait",
});

// Legal size
await exportToPdf(editor, {
  format: "legal",
});

// Fast compression for smaller files
await exportToPdf(editor, {
  compression: "FAST", // Smaller file, lower quality
});

// High quality compression (default)
await exportToPdf(editor, {
  compression: "SLOW", // Larger file, higher quality
});

Compression Options

Choose the right compression level based on your needs:

// No compression - fastest processing, largest files
await exportToPdf(editor, { compression: "NONE" });

// Fast compression - quick processing, smaller files, lower quality
await exportToPdf(editor, { compression: "FAST" });

// Medium compression - balanced processing time and quality
await exportToPdf(editor, { compression: "MEDIUM" });

// Slow compression - longer processing, highest quality (default)
await exportToPdf(editor, { compression: "SLOW" });

When to use each:

  • NONE: Large documents where file size isn't a concern
  • FAST: Quick exports, email attachments, draft documents
  • MEDIUM: General purpose, good balance of quality and size
  • SLOW: Final documents, presentations, archival purposes

Error Handling

try {
  await exportToPdf(editor, { filename: "my-doc.pdf" });
  console.log("PDF exported successfully!");
} catch (error) {
  console.error("Export failed:", error.message);
  // Handle error (show user notification, etc.)
}

React with Custom Styling

{
  /* Custom button with children */
}
<DownloadPDFPlugin
  filename="styled-document.pdf"
  containerClassName="flex items-center gap-2"
  containerWidth="800px"
  containerPadding="40px"
>
  <div className="flex items-center gap-2 px-3 py-2 bg-green-600 text-white rounded-lg hover:bg-green-700 transition-colors">
    <DownloadIcon size={16} />
    Download PDF
  </div>
</DownloadPDFPlugin>;

{
  /* Default button with custom icon styling */
}
<DownloadPDFPlugin
  filename="custom-icon.pdf"
  iconSize={20}
  iconColor="#ef4444"
  iconStrokeWidth={2.5}
/>;

How It Works

  1. Extract HTML: Uses @lexical/html to convert editor state to HTML
  2. Render Off-screen: Creates a temporary DOM container with your content
  3. Capture Canvas: Uses html2canvas-pro to render HTML to canvas
  4. Generate PDF: Uses jsPDF to create PDF from canvas image
  5. Download: Automatically triggers browser download

Environment Support

Browser Support

  • Chrome/Edge: ✅ Full support
  • Firefox: ✅ Full support
  • Safari: ✅ Full support
  • IE11: ❌ Not supported

Framework Support

  • React: ✅ Dedicated component included
  • Vue: ✅ Use core function
  • Svelte: ✅ Use core function
  • Angular: ✅ Use core function
  • Vanilla JS: ✅ Use core function

Node.js Support

Not supported - This package requires browser DOM APIs (document, html2canvas, etc.)

For server-side PDF generation, consider:

Peer Dependencies

This package requires:

  • lexical: >=0.12.0 <1.0.0 (always required)
  • @lexical/html: >=0.12.0 <1.0.0 (always required)
  • react: ^18.0.0 || ^19.0.0 (only for React component usage)
  • @lexical/react: >=0.12.0 <1.0.0 (only for React component usage)
  • lucide-react: ^0.200.0 (only for React component usage)

Contributing

Contributions are welcome! Here are some areas where we'd especially appreciate help:

  • 🐛 Bug fixes - Found an issue? PRs welcome!
  • New features - Pagination support, more export formats, better compression algorithms
  • 🧩 Framework components - Vue, Angular, Svelte components (we currently only have React)
  • 📚 Documentation - Examples, tutorials, translations
  • 🧪 Testing - Unit tests and integration tests
  • 🎨 Styling options - More customization for the React component

How to Contribute

  1. Fork the repository
  2. Create your feature branch: git checkout -b feature/amazing-feature
  3. Commit your changes: git commit -m 'Add amazing feature'
  4. Push to the branch: git push origin feature/amazing-feature
  5. Open a Pull Request

License

MIT © Stefan Leoussis

Changelog

0.1.5

  • Updated jspdf from ^3.0.3 to ^4.0.0 to avoid security vulnerabilities.

0.1.4

  • Update @lexical/html and @lexical/react to v0.38.2 for latest features and bug fixes
  • Improved stability and compatibility with Lexical ecosystem

0.1.3

  • Breaking Fix: Move @lexical/html to peerDependencies to prevent version conflicts

0.1.2

  • Security Fix: Update jsPDF to v3.0.3 (fixes moderate/high security vulnerabilities)
  • Update all dependencies to latest versions for better security and compatibility
  • Update development dependencies: TypeScript 5.9.3, React 19, Node types 22.9.1
  • Improve peer dependency constraints: lexical >=0.12.0 <1.0.0
  • Support both React 18 and React 19
  • Fix Lexical editor state compatibility issues

0.1.1

  • Fix peer dependency compatibility with newer Lexical versions (now supports >=0.12.0)
  • Support for Lexical v0.35.0 and beyond

0.1.0

  • Initial release
  • Core exportToPdf function with configurable compression
  • React DownloadPDFPlugin component with customizable icon
  • TypeScript support with full ES module compatibility
  • Comprehensive error handling
  • Support for all major frontend frameworks (React, Vue, Svelte, Angular)