Skip to content

0x31/oxc-remove-attributes

Repository files navigation

oxc-remove-attributes

License Version Downloads Vite Badge oxc Badge TypeScript Badge

A Vite/Rolldown plugin that removes JSX attributes (e.g. data-testid) from production builds. Parses with oxc and emits accurate sourcemaps via magic-string.

Intended as a replacement for @swc/plugin-react-remove-properties after the move from @vitejs/plugin-react-swc to the oxc-based @vitejs/plugin-react in Vite 8, where no oxc equivalent of that SWC plugin exists.

Install

yarn add -D oxc-remove-attributes

or

npm i --save-dev oxc-remove-attributes

Usage

In vite.config.ts or vite.config.js:

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { removeAttributes } from "oxc-remove-attributes";

export default defineConfig({
  plugins: [react(), removeAttributes()],
});

By default the plugin only runs during vite build, so data-testid attributes remain in dev and in vite build --mode test builds used by e2e suites.

Options

removeAttributes({
  // Attribute names to remove (exact match).
  attributes: ["data-testid"],

  // File extensions to scan.
  extensions: [".tsx", ".jsx"],

  // When this plugin runs in the Vite pipeline.
  enforce: "pre",

  // Active in 'build', 'serve', or 'both'.
  apply: "build",
});

Strip multiple attributes

removeAttributes({
  attributes: ["data-testid", "data-cy", "data-test"],
});

Always active (incl. dev server)

removeAttributes({ apply: "both" });

Limitations

The plugin operates on JSX attributes statically. It will not strip targets that arrive at runtime via a spread, e.g.:

const props = { "data-testid": "x" };
<div {...props} />;

If you rely on the bundle being completely free of test IDs, either avoid spreading them or pair this plugin with an oxlint / eslint rule that forbids data-testid in the value side of a spread source.

Namespaced attributes (xlink:href, xml:lang, etc.) and component-prop attributes whose names don't match exactly are also untouched by design.

Prop-chain pass-through

The plugin matches attribute names exactly. A component that accepts a camelCase prop and forwards it to a DOM data-testid looks like this:

// Consumer
<Modal dataTestId="checkout-modal" />;

// Inside Modal.tsx
<div data-testid={dataTestId}>{children}</div>;

With the default attributes: ['data-testid'], the DOM data-testid={dataTestId} is stripped (production DOM is clean), but the dataTestId prop is not — "checkout-modal" survives in the bundle as a JSX prop value even though it's never written to the DOM.

If you want to strip prop pass-through too, include both names:

removeAttributes({ attributes: ["data-testid", "dataTestId"] });

License

ISC

About

oxc-powered Vite plugin to strip JSX attributes like data-testid from production builds. Drop-in for @swc/plugin-react-remove-properties on Vite 8.

Topics

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors