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

@wy-ai-labs/figma-tables-core

v0.1.0

Published

Figma Auto Layout frames → table model → Markdown / JSON / XLSX (zero-dependency OOXML writer), a Figma link parser and a REST client with injectable fetch

Downloads

110

Readme

@wy-ai-labs/figma-tables-core

Figma Auto Layout frames → rectangular table model → Markdown / JSON / XLSX (zero-dependency OOXML writer), plus a Figma link parser and a REST client that never logs the token and always carries a timeout.

npm License: MIT Node ≥22 runtime deps: 0

Part of the wy-ai-labs parts monorepo (packages/figma-tables-core) · contract v1 · no Python twin

Figma has no native table element: designers build tables by nesting Auto Layout frames (rows inside a vertical stack, cells inside each row — or columns inside a horizontal stack). This part reconstructs rows, columns and cells from that nesting, exactly the way the source products proved on real files, and exports the result.

Install

npm install @wy-ai-labs/figma-tables-core      # Node ≥22.11, ESM only (import — no require)

30-second usage

Offline — any Figma REST / plugin node tree you already have (no token, no network):

import { extractTables, tablesToMarkdown, tablesToJson, tablesToXlsx, CONTRACT_VERSION } from '@wy-ai-labs/figma-tables-core';
import { writeFile } from 'node:fs/promises';

const cell = (id, t) => ({ id, name: t, type: 'FRAME', layoutMode: 'HORIZONTAL', children: [{ id: `${id}t`, name: t, type: 'TEXT', characters: t }] });
const row = (id, ...cells) => ({ id, name: 'Row', type: 'FRAME', layoutMode: 'HORIZONTAL', children: cells.map((t, i) => cell(`${id}c${i}`, t)) });
const people = { id: '1:2', name: 'People', type: 'FRAME', layoutMode: 'VERTICAL', children: [row('r1', 'Name', 'Age'), row('r2', 'Alice', '30'), row('r3', 'Bob', '25')] };

const tables = extractTables(people);                 // [{ name: 'People', nodeId: '1:2', header: ['Name','Age'], rows: [['Alice','30'],['Bob','25']], columns: 2, source }]
console.log(CONTRACT_VERSION, tablesToMarkdown(tables));
console.log(tablesToJson(tables));                    // [{ name, nodeId, columns, header, rows, records: [{ Name: 'Alice', Age: '30' }, …], source }]
await writeFile('tables.xlsx', tablesToXlsx(tables)); // one worksheet per table, bold header, zero dependencies

Online — from a "Copy link" URL (the token comes from FIGMA_TOKEN or the option; it is sent only as X-Figma-Token):

import { createFigmaClient, extractFromFigma, tablesToMarkdown } from '@wy-ai-labs/figma-tables-core';

const client = createFigmaClient({ token: process.env.FIGMA_TOKEN });      // apiBase defaults to https://api.figma.com/v1
const { tables, file } = await extractFromFigma(client, 'https://www.figma.com/design/<fileKey>/Title?node-id=12-34');
console.log(file.name, file.lastModified, tablesToMarkdown(tables));

A node link fetches just that node (GET /files/:key/nodes?ids=…); a whole-file link fetches the document (GET /files/:key) — link a node for large files. Every request carries a 120 000 ms budget (timeoutMs) and honours an AbortSignal.

API at a glance

| Area | Symbols | |---|---| | Links | parseFigmaLink(url){ fileKey, nodeId, kind, branchOf } · normalizeNodeId('12-34')'12:34' | | Extraction | extractTables(nodeOrDocument, { firstRowHeader, minRows, minCols, includeHidden, nameFilter }) · tableFromNode · collectText · tableMatrix | | Export | tableToMarkdown · tablesToMarkdown · tableToRecords · tablesToJson · tablesToXlsx(tables, { sheetPerTable, sheetNameMax }) · sanitizeSheetName | | Spec workbook | buildSpecDocument(tables, { schema, title, generatedAt }) · tablesToSpecJson · buildSpecLayout · buildSpecWorkbook (sheets "Spec" + "Tables") · resolveAncestorTags · normalizeListKey · safeFileName | | REST | createFigmaClient({ token, apiBase, fetch, timeoutMs, dispatcher, log })getFile / getNodes / health · extractFromFigma(client, link, options) | | Errors | FigmaTablesError { code, status, retryable, upstreamText, cause } — codes bad_link · invalid_argument · auth · not_found · rate_limited · network · timeout · aborted · upstream |

Behind an HTTP proxy (enterprise networks)

Node's global fetch ignores HTTP(S)_PROXY. Inject a proxy-aware fetch instead of patching the part — for example with undici:

import { EnvHttpProxyAgent, fetch as proxyFetch } from 'undici';
import { createFigmaClient } from '@wy-ai-labs/figma-tables-core';

const client = createFigmaClient({
  token: process.env.FIGMA_TOKEN,
  fetch: proxyFetch,
  dispatcher: new EnvHttpProxyAgent(),        // reads HTTP_PROXY / HTTPS_PROXY / NO_PROXY
  apiBase: process.env.FIGMA_API_BASE,        // optional: an API gateway in front of api.figma.com
});
console.log(await client.health());           // { ok, apiBase, tokenConfigured, customFetch, dispatcherConfigured, proxyEnv: ['HTTPS_PROXY'], … }

health() is offline diagnostics: it names which proxy variables are set, never their values.

Spec workbook

buildSpecWorkbook ports the source plugin's structured export: many tables → one record set. Rows are read through header aliases, classification values come from key=value tags in ancestor node names (category=Living; group=Oven on a page, section or frame — the nearest ancestor wins), rows sharing the key fields merge into one record (comma lists compare as sets), conflicting values are joined with line breaks, and every degradation is a warning (MISSING_HEADER, DUPLICATE_HEADER, MERGED_VALUE_CONFLICT, ANCESTOR_TAG_CONFLICT, INVALID_FLAG, FLAG_CONFLICT, MISSING_GROUP_KEY, MISSING_NODE_TAG, EMPTY_TABLE). Without a schema the columns are derived from the tags and headers found; with one you control keys, aliases, required headers, O/X flag columns, widths, tones and vertical merging — see CONTRACT.md → Configuration.

Contract

Public API, invariants and error model are fixed in CONTRACT.md; the tests in test/ are the contract suite (test/contract.test.mjs: one test per numbered invariant). Three invariants to know before depending on this part:

  1. Pure by default — parsing, extraction, export and the spec builder touch neither network nor filesystem; identical input gives identical output, byte-for-byte for XLSX.
  2. Never logs or echoes the token — it travels only in the X-Figma-Token header; log lines, error messages and upstreamText never contain it, and errors keep the upstream body (≥ 500 chars) with the status.
  3. XLSX is a valid OOXML package with zero dependencies — STORE zip with verified CRC-32s, inline strings only, formula-looking text stays text, unique sheet names ≤ 31 chars.

An incompatible change bumps CONTRACT_VERSION and the major version together (CONTRACT.md → Compatibility).

Mined from

Extracted from a private source repository (figma2Excel, modules server/src/tableExtractor.ts, server/src/figmaClient.ts, server/src/figmaTypes.ts, server/src/index.ts, plugin/src/tableModel.ts, plugin/src/didExport.ts, plugin/src/workbookLayout.ts, plugin/src/workbookExport.ts, web/src/exporters.ts, developed 2026-07-10 – 2026-07-21), generalized and re-tested for publication. What was kept, generalized and stripped: PROVENANCE.md.

Used by

| Client | Role of this part there | |---|---| | (none yet — wave 0) | first candidates: a CLI and a local web app mirroring the source product (link → preview → download) |

Dependencies & budget

  • Runtime dependencies: 0 (budget 0) — enforced by scripts/check-budget.mjs. The XLSX writer, the zip packager and the REST client are built on Node's standard library only.
  • Allowed: other @wy-ai-labs/* parts, pinned as caret ranges from the registry. Never a client, never file: / link: / git URLs / ../.
  • No private host or key as a default: the API base is the public https://api.figma.com/v1 (override via apiBase / FIGMA_API_BASE), the token comes from the caller or FIGMA_TOKEN / FIGMA_ACCESS_TOKEN.

Gates

| Command | What | When | |---|---|---| | npm test | contract suite (node:test), offline, seconds | every save | | npm run gates:core | dependency budget + independence + engines.node + tests | before every commit / PR | | npm run gates:full | everything above | nightly / before release |

CI only calls these scripts (wy-ai-labs/.githubnode-gates.yml). Releases: Keep a Changelog + npm publish --provenance.

License

MIT © 2026 waneekim

한국어 요약

  • @wy-ai-labs/figma-tables-core — Figma 오토레이아웃 프레임을 표 모델로 복원해 Markdown · JSON · XLSX(의존성 0의 OOXML 작성기)로 내보내고, Figma 링크 파서와 토큰을 절대 로그에 남기지 않는 REST 클라이언트를 제공합니다. 공개 API·불변식·오류 모델은 CONTRACT.md에 고정되어 있고, 테스트가 곧 계약 스위트입니다.
  • 설치 npm install @wy-ai-labs/figma-tables-core(Node ≥22, ESM). 런타임 의존성 0, 다른 part에만 핀 버전으로 의존, 사설 호스트 기본값 없음(기본 API는 공개 https://api.figma.com/v1, 토큰은 FIGMA_TOKEN).
  • 프록시 환경에서는 프록시 인식 fetch/dispatcher를 주입하세요(README → Behind an HTTP proxy). 비공개 저장소 figma2Excel에서 추출·일반화했습니다(PROVENANCE.md). 커밋 전 npm run gates:core.