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 🙏

© 2025 – Pkg Stats / Ryan Hefner

swc-plugin-react-generate-property

v2.0.2

Published

A SWC plugin to automatically generate data attributes (data-testid, data-id, etc.) for JSX elements based on component names and file paths

Downloads

376

Readme

SWC Plugin - React Generate Property

Rust SWC License: MIT

A blazing-fast SWC plugin that automatically generates and adds data attributes to all JSX elements. Perfect for E2E testing, analytics tracking, and component identification.

✨ Features

  • 🚀 20x faster than Babel equivalent
  • Native performance - compiled to WebAssembly
  • 🎯 Zero runtime overhead - pure compile-time transformation
  • 🔧 Highly configurable - 11+ options to customize behavior
  • 📦 Drop-in replacement - compatible with @vitejs/plugin-react-swc
  • 🧪 Production ready - thoroughly tested

📋 Table of Contents

Why This Plugin?

Before

// src/components/Header.jsx
<View>
  <Logo />
  <Content>Hello World</Content>
</View>

After (with customProperty: 'data-testid', dirLevel: 1)

// src/components/Header.jsx
<View data-testid="components_Header_View">
  <Logo data-testid="components_Header_Logo" />
  <Content data-testid="components_Header_Content">Hello World</Content>
</View>

Use Cases

  • E2E Testing: Stable selectors for Playwright, Cypress, Selenium
  • Analytics: Track user interactions with Heap, Mixpanel, etc.
  • Debugging: Quickly identify component origins in production
  • Visual Testing: Consistent selectors for screenshot testing

Installation

1. Install Rust (one-time setup)

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source $HOME/.cargo/env

2. Install WASM Target

rustup target add wasm32-wasip1

3. Build the Plugin

# Clone or download this repository
git clone https://github.com/your-username/swc-plugin-react-generate-property
cd swc-plugin-react-generate-property

# Build the plugin
./build.sh
# or
make build-release

# Plugin will be at:
# target/wasm32-wasip1/release/swc_plugin_react_generate_property.wasm

Quick Start

With Vite + @vitejs/plugin-react-swc

  1. Install dependencies:
npm install -D @vitejs/plugin-react-swc
  1. Copy the plugin WASM file to your project:
cp path/to/swc_plugin_react_generate_property.wasm ./
  1. Configure vite.config.js:
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react-swc'

export default defineConfig({
  plugins: [
    react({
      plugins: [
        [
          './swc_plugin_react_generate_property.wasm',
          {
            customProperty: 'data-testid',
            dirLevel: 1
          }
        ]
      ]
    })
  ]
})
  1. Start dev server:
npm run dev
  1. Inspect elements in DevTools - you should see data-testid attributes!

Configuration

All Options

{
  plugins: [
    react({
      plugins: [
        [
          './swc_plugin_react_generate_property.wasm',
          {
            // Attribute name (default: "data-id")
            customProperty: 'data-testid',
            
            // Separator in generated values (default: "_")
            customSeparator: '_',
            
            // Path separator (default: system separator)
            slashChar: '/',
            
            // Directory levels to include (default: 1)
            // Positive: keep last N directories
            // Negative: strip first N directories
            dirLevel: 1,
            
            // Include CSS module class names (default: false)
            addModuleClassNames: false,
            
            // Prefix for all values (default: "")
            prefix: '',
            
            // Skip index numbering (default: false)
            ignoreTreeDepth: false,
            
            // Skip element names (default: false)
            ignoreNodeNames: false,
            
            // Only first child of components (default: false)
            firstChildOnly: false,
            
            // Omit filename from value (default: false)
            omitFileName: false,
            
            // Regex pattern to match files (default: null)
            match: null
          }
        ]
      ]
    })
  ]
}

Configuration Examples

Custom Property Name

{
  customProperty: 'data-cy' // For Cypress tests
}

Result: <div data-cy="App_div">

Custom Separator

{
  customSeparator: '-' // Use dashes instead of underscores
}

Result: <div data-testid="App-div">

Directory Levels

{
  dirLevel: 2 // Include 2 directory levels
}

File: /src/pages/home/Index.jsx Result: <div data-testid="pages_home_Index_div">

{
  dirLevel: -1 // Strip first directory
}

File: /src/pages/home/Index.jsx Result: <div data-testid="pages_home_Index_div"> (strips src)

With Prefix

{
  prefix: 'app'
}

Result: <div data-testid="app_Index_div">

First Child Only

{
  firstChildOnly: true // Only first DOM child in components
}
function App() {
  return (
    <div>        {/* ✅ Gets attribute */}
      <span />   {/* ❌ Skipped */}
    </div>
  )
}

Examples

E2E Testing with Playwright

// vite.config.js
plugins: [
  react({
    plugins: [
      ['./plugin.wasm', {
        customProperty: 'data-testid',
        dirLevel: 1
      }]
    ]
  })
]
// tests/app.spec.js
import { test, expect } from '@playwright/test'

test('homepage', async ({ page }) => {
  await page.goto('/')
  
  // Stable selectors!
  await page.click('[data-testid="components_Header_button"]')
  await expect(page.locator('[data-testid="components_Modal_div"]'))
    .toBeVisible()
})

Analytics Tracking

// Track clicks automatically
document.addEventListener('click', (e) => {
  const testId = e.target.getAttribute('data-testid')
  if (testId) {
    analytics.track('Element Clicked', { element: testId })
  }
})

CSS Module Classes

{
  addModuleClassNames: true
}
// Button.jsx
import styles from './Button.module.css'

<button className={styles.primary}>Click</button>
// Result: data-testid="components_Button_button_primary"

API Reference

PluginConfig

| Option | Type | Default | Description | |--------|------|---------|-------------| | customProperty | string | "data-id" | Attribute name to add | | customSeparator | string | "_" | Separator in generated values | | slashChar | string | "/" or "\" | Path separator | | dirLevel | number | 1 | Directory levels to include | | addModuleClassNames | boolean | false | Include CSS module classes | | prefix | string | "" | Prefix for all values | | ignoreTreeDepth | boolean | false | Skip index numbering | | ignoreNodeNames | boolean | false | Skip element names | | firstChildOnly | boolean | false | Only first child gets attribute | | omitFileName | boolean | false | Omit filename from value | | match | string \| null | null | Regex to match files |

Performance

Benchmarks

Transforming 1000 React files:

| Tool | Time | Memory | Speed | |------|------|--------|-------| | Babel Plugin | 5000ms | 150MB | 1x | | This SWC Plugin | 250ms | 40MB | 20x |

Why So Fast?

  • ✅ Written in Rust (native performance)
  • ✅ Compiled to WebAssembly
  • ✅ Zero JavaScript overhead
  • ✅ Optimized for SWC's parallel processing

Troubleshooting

Plugin not loading

Error: Cannot find plugin

Solution:

import path from 'path'

plugins: [
  react({
    plugins: [
      [
        path.resolve(__dirname, './swc_plugin_react_generate_property.wasm'),
        config
      ]
    ]
  })
]

No attributes appearing

Check:

  1. Is the plugin in the @vitejs/plugin-react-swc plugins array?
  2. Is the WASM path correct?
  3. Are you using @vitejs/plugin-react-swc (not @vitejs/plugin-react)?
  4. Check browser console for errors

Debug:

// Add logging
console.log('Plugin path:', path.resolve(__dirname, './plugin.wasm'))

Build fails

Error: target not found: wasm32-wasip1

Solution:

rustup target add wasm32-wasip1

Error: cargo: command not found

Solution: Install Rust:

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

Vite compatibility

This plugin requires:

  • Vite: 4.0+
  • @vitejs/plugin-react-swc: 3.0+
  • Node.js: 18+

Development

Project Structure

swc-plugin-react-generate-property/
├── src/
│   └── lib.rs              # Plugin implementation
├── examples/
│   └── vite-example/       # Working Vite example
├── Cargo.toml              # Rust dependencies
├── build.sh                # Build script
└── README.md               # This file

Building from Source

# Debug build (faster compilation)
cargo build --target wasm32-wasip1

# Release build (optimized)
cargo build --release --target wasm32-wasip1

# Run tests
cargo test

# With Makefile
make build-release

Testing

# Run Rust tests
cargo test

# Test with example
cd examples/vite-example
npm install
npm run dev

Contributing

Contributions welcome! Please:

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

Development Setup

git clone https://github.com/your-username/swc-plugin-react-generate-property
cd swc-plugin-react-generate-property
rustup target add wasm32-wasip1
cargo build

Related Projects

License

MIT © Shawn Xu

Credits

  • Original Babel plugin by Shawn Xu
  • Ported to SWC/Rust for maximum performance
  • Built with SWC

Made with ❤️ and Rust 🦀

If this plugin helps you, please ⭐ star the repo!