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

@zseven-w/pen-figma

v0.7.6

Published

Figma .fig file parser and converter for OpenPencil

Downloads

2,061

Readme

@zseven-w/pen-figma

Figma .fig file parser and converter for OpenPencil. Import Figma designs directly into the OpenPencil document model — binary file parsing, multi-page support, clipboard paste, and full style conversion.

Install

npm install @zseven-w/pen-figma
# or
bun add @zseven-w/pen-figma

Overview

This package handles the complete pipeline from Figma's proprietary binary format to OpenPencil's PenDocument:

.fig binary → Kiwi schema decode → FigmaNodeChange[] → tree building → PenNode[] → PenDocument

It supports:

  • Binary .fig files (Kiwi schema + zstd/zip compression)
  • Figma clipboard HTML (copy from Figma → paste in OpenPencil)
  • All node types: frames, groups, components, instances, shapes, text, vectors, images
  • Full style conversion: fills, strokes, effects, gradients, auto-layout, typography

Usage

Parse a .fig file

import { parseFigFile, figmaAllPagesToPenDocument } from '@zseven-w/pen-figma';

const buffer = await fs.readFile('design.fig');
const figFile = parseFigFile(buffer);
const document = figmaAllPagesToPenDocument(figFile);

console.log(`Imported ${document.pages?.length} pages`);

Single page import

import { parseFigFile, getFigmaPages, figmaToPenDocument } from '@zseven-w/pen-figma';

const figFile = parseFigFile(buffer);
const pages = getFigmaPages(figFile);

// Import just the first page
const document = figmaToPenDocument(figFile, pages[0]);

Clipboard paste

Detect and convert Figma clipboard data (when users copy from Figma and paste into OpenPencil):

import {
  isFigmaClipboardHtml,
  extractFigmaClipboardData,
  figmaClipboardToNodes,
} from '@zseven-w/pen-figma';

document.addEventListener('paste', (e) => {
  const html = e.clipboardData?.getData('text/html');
  if (html && isFigmaClipboardHtml(html)) {
    const data = extractFigmaClipboardData(html);
    const nodes = figmaClipboardToNodes(data);
    // Insert nodes into document...
  }
});

Convert individual nodes

For lower-level access (e.g., incremental sync):

import { figmaNodeChangesToPenNodes } from '@zseven-w/pen-figma';

const penNodes = figmaNodeChangesToPenNodes(figmaNodeChanges, options);

Icon resolution

Register an icon lookup function for converting Figma component instances to icon nodes:

import { setIconLookup } from '@zseven-w/pen-figma';

setIconLookup((name) => {
  // Return SVG path data for the icon name, or null
  return iconRegistry[name]?.path ?? null;
});

Image resolution

Resolve embedded image blob references to data URLs:

import { resolveImageBlobs } from '@zseven-w/pen-figma';

const images = resolveImageBlobs(figFile);
// Map<blobHash, dataURL>

Conversion Coverage

Node Types

| Figma Type | PenNode Type | Notes | | ---------- | ------------ | ------------------------------------------- | | FRAME | frame | With auto-layout, constraints, clip content | | GROUP | group | Preserves child transforms | | COMPONENT | frame | Marked as reusable | | INSTANCE | frame | Resolved with overrides | | RECTANGLE | rectangle | Corner radius (uniform + per-corner) | | ELLIPSE | ellipse | Arc support | | LINE | line | Stroke properties | | TEXT | text | Rich text with styled segments | | VECTOR | path | Complex paths, boolean ops, stars, polygons | | IMAGE | image | Embedded or referenced |

Styles

| Figma Style | Conversion | | ---------------- | --------------------------------------------------------------------- | | Solid fills | PenFill with solid type | | Linear gradients | PenFill with gradient stops + angle | | Radial gradients | PenFill with center + radius | | Image fills | PenFill with image source | | Strokes | PenStroke with cap, join, dash | | Drop shadows | PenEffect shadow | | Inner shadows | PenEffect inner shadow | | Blur | PenEffect blur | | Auto-layout | layout, gap, padding, justifyContent, alignItems | | Text styles | fontSize, fontWeight, fontFamily, lineHeight, letterSpacing | | Rich text | StyledTextSegment[] with per-run styles |

API Reference

| Function | Description | | ------------------------------------- | --------------------------------------------- | | parseFigFile(buffer) | Parse binary .fig file → FigmaDecodedFile | | figmaAllPagesToPenDocument(file) | Convert all pages → PenDocument | | figmaToPenDocument(file, page) | Convert single page → PenDocument | | getFigmaPages(file) | List available pages | | figmaNodeChangesToPenNodes(changes) | Convert raw node changes → PenNode[] | | isFigmaClipboardHtml(html) | Detect Figma clipboard data | | extractFigmaClipboardData(html) | Extract base64 .fig from clipboard HTML | | figmaClipboardToNodes(data) | Convert clipboard data → PenNode[] | | resolveImageBlobs(file) | Resolve image references → data URLs | | setIconLookup(fn) | Register icon name → SVG path resolver |

License

MIT