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

@tapestrylab/extract

v0.3.1

Published

Extract component metadata from source files for Tapestry design systems

Readme

@tapestrylab/extract

A powerful, fast component metadata extractor for component libraries. Parse React components and automatically extract structured metadata including names, props, types, defaults, and documentation.

Features

  • ⚡ Lightning Fast: Built on oxc-parser (Rust-based parser for blazing-fast AST parsing)
  • 📦 Component Extraction: Automatically finds and analyzes React components
  • 🏷️ Prop Detection: Extracts prop names, types, defaults, and descriptions from JSDoc
  • 🔤 TypeScript Support: Full TypeScript type information and complex type serialization
  • 🎯 Flexible Matching: Include/exclude patterns for fine-grained file selection
  • 📝 Multiple Formats: Outputs structured metadata JSON for use in dev/design tools
  • 🔌 Plugin Architecture: Extensible system for adding custom extractors

Quick Start

Installation

npm install @tapestrylab/extract
# or
pnpm add @tapestrylab/extract

Usage

CLI Usage: For command-line usage, install @tapestrylab/cli which provides the unified tapestry command. See the CLI documentation for details.

Programmatic API

import { extract } from "@tapestrylab/extract";

// Simple usage - includes and excludes use smart defaults
const result = await extract({
  root: "./src",
});

console.log(result.metadata); // Component metadata
console.log(result.stats); // Extraction statistics

// Or with custom patterns
const customResult = await extract({
  root: "./src",
  include: ["**/*.tsx"], // Optional - defaults to common patterns
  exclude: ["**/*.test.tsx"], // Optional - defaults exclude tests, node_modules, etc.
});

Convenience Functions:

import { extractComponent, extractFromPattern, extractFromDirectory } from "@tapestrylab/extract";

// Extract a single component
const button = await extractComponent('./src/components/Button.tsx');

// Extract components matching a pattern
const components = await extractFromPattern('**/*.tsx', {
  root: './src'
});

// Extract from a directory (non-recursive by default)
const allComponents = await extractFromDirectory('./src/components');

// Extract recursively
const recursive = await extractFromDirectory('./src/components', {
  recursive: true
});

Browser-Compatible Core API

For edge runtimes, browsers, or environments without Node.js (like Convex, Cloudflare Workers, or Vercel Edge Functions), use the /core export which provides pure extraction without file system dependencies:

import { createReactExtractor } from "@tapestrylab/extract/core";

// Create an extractor
const extractor = createReactExtractor();

// Extract from in-memory code (no file I/O needed)
const sourceCode = `
  export function Button({ label }: { label: string }) {
    return <button>{label}</button>;
  }
`;

const metadata = await extractor.extract("Button.tsx", sourceCode);
console.log(metadata); // [{ name: "Button", props: [...], ... }]

Use cases for /core:

  • ✅ Convex functions (TypeScript edge runtime)
  • ✅ Cloudflare Workers / Vercel Edge Functions
  • ✅ Browser-based code editors (CodeSandbox, StackBlitz)
  • ✅ Build tools that work with in-memory code
  • ✅ Any environment without Node.js file system APIs

The core API only extracts metadata from code strings - you're responsible for providing the source code (from a database, API, user input, etc.).

Configuration

Create a tapestry.config.js in your project root:

export default {
  root: "./src",
  include: ["**/*.tsx", "**/*.jsx"],
  exclude: ["**/*.test.tsx", "**/*.stories.tsx"],
  output: "./metadata.json",
};

Or use other config file formats:

  • .tapestryrc
  • .tapestryrc.json
  • .tapestryrc.js
  • tapestry.config.mjs
  • tapestry.config.cjs

Example Output

{
  "metadata": [
    {
      "name": "Button",
      "filePath": "src/components/Button.tsx",
      "exportType": "default",
      "description": "A customizable button component",
      "props": [
        {
          "name": "label",
          "type": "string",
          "required": true,
          "description": "Button label text"
        },
        {
          "name": "variant",
          "type": "primary | secondary | danger",
          "required": false,
          "defaultValue": "primary",
          "description": "Button style variant"
        }
      ]
    }
  ],
  "stats": {
    "filesScanned": 15,
    "filesProcessed": 15,
    "componentsFound": 8,
    "duration": 245
  }
}

Development

Requirements

  • Node 22+ (use fnm use to switch to the correct version)
  • pnpm (fast, disk space efficient package manager)

Setup

# Install dependencies
pnpm install

# Watch mode development
pnpm dev

# Type checking
pnpm type-check

Testing

# Run extraction on test fixtures
pnpm test:extract

# Run full test suite
pnpm test:ci

Building

# Build the project
pnpm build

Architecture

The extraction pipeline consists of three main stages:

  1. Configuration: Loads settings from config files or CLI arguments using cosmiconfig
  2. Scanning: Uses fast-glob to find matching files based on include/exclude patterns
  3. Extraction: Routes files to appropriate extractors via the plugin system

Plugin System

@tapestrylab/extract uses a flexible plugin architecture. The current React extractor handles TypeScript and JavaScript files:

  • Parses files into an Abstract Syntax Tree (AST)
  • Identifies components using PascalCase naming conventions
  • Validates JSX return statements
  • Extracts typed props with defaults
  • Parses JSDoc comments for descriptions

Supported Component Patterns

// Function declarations
export function Button({ label }: { label: string }) {
  return <button>{label}</button>;
}

// Arrow functions
export const Card = ({ title }: Props) => {
  return <div>{title}</div>;
};

// Default exports
export default function Modal() {
  return <div role="dialog" />;
}

// With JSDoc
/**
 * A reusable button component
 * @param {string} label - Display text
 */
export function Button({ label }) {
  return <button>{label}</button>;
}

Contributing

We welcome contributions! Whether you're fixing bugs, adding features, or improving documentation, your help makes this project better.

For detailed instructions on how to contribute, including step-by-step commands for every phase of the process, see CONTRIBUTING.md.

Quick start:

git checkout -b feat/your-feature
pnpm install
pnpm dev
# ... make your changes ...
pnpm build && pnpm test:ci
pnpm changeset
git add . && git commit -m "feat: describe your changes"
git push origin feat/your-feature

Then open a pull request on GitHub!

License

MIT

Support