SkillAgentSearch skills...

react

Show how to use custom elements in React, including workarounds for React 18 vs 19 differences

Install / Use

npx skills add bennypowers/cem --skill react

Installs into whichever agent you are using.

About this skill
📄

SKILL.md

Installable skill definition

Quality Score

76/100

Supported Platforms

Universal

Our assessment of react

react scores 76/100 on our quality scale, 3675th of 4,617 Development & Engineering skills we index.

Its SKILL.md is 6.1 KB long, well organised into 13 sections with 8 code examples: a thorough specification that gives an agent plenty to work with.

It has no GitHub stars yet, so there is no community track record; judge it on its content.

Substance
29/30
Structure
20/20
Description
12/15
Adoption
0/20
Freshness
15/15

Maintenance, license and trust

  • The repository was last updated 3 days ago, so react is actively maintained.
  • Our last check on 2026-09-26 found the source still online.
  • No license is declared. By default that means all rights are reserved: you can read it, but reusing or redistributing it is not clearly permitted. Ask the author before building on it commercially.
  • Its trust signals score 80/100, with 2 cautions from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

Safety scan

No issues found

Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful.

AI review by kimi-k2.7-code on 2026-09-24. Automated pattern scan on 2026-09-24. It catches known dangerous patterns, not every risk — read a skill before letting an agent act on it.

react compared with similar skills

All 4 of these similar skills score higher than react; compare them before choosing.

SkillScoreStarsUpdatedFormat
react (this skill)by bennypowers7603d agoSKILL.md
taste-skillby Leonxlnx100110.6ktodayCLAUDE.md
ai-job-searchby ai-job-search-dev10069.8ktodayCLAUDE.md
claude-howtoby luongnv8910046.6k2d agoCLAUDE.md
algorithmic-artby anthropics100177.9k44d agoSKILL.md

Frequently asked questions

How do I install react?
Run npx skills add bennypowers/cem --skill react. The install tabs above show the steps for each supported agent.
Which AI agents does react work with?
It is written for Universal, as a SKILL.md file. Other agents that read the same format can often use it too.
Is react safe to use?
Our scan of the whole file found no instruction hijacking, hidden characters, credential access, data exfiltration or destructive commands. An AI review of the same text found nothing harmful. It declares no license and scores 80/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is react still maintained?
The repository was last updated 3 days ago, so react is actively maintained.

name: react description: Show how to use custom elements in React, including workarounds for React 18 vs 19 differences. Use when the user asks to "use in React", "React wrapper", "custom elements in React", "JSX custom element", or mentions "React 18", "React 19", or "react integration". tools: Read, Glob, Grep

Custom Elements in React

Generate framework-specific guidance for using custom elements in React, adapting to the project's React version.

Workflow

Phase 1: Detect React Version

Search the project for React version:

# Check package.json for react version
grep -A1 '"react"' package.json

Determine if the project uses:

  • React 19+: Native custom element support
  • React 18 or earlier: Requires workarounds for properties and events

Also check for:

  • TypeScript (need JSX type declarations)
  • Existing wrapper patterns in the codebase
  • Whether @lit/react or similar wrapper libraries are already in use

Phase 2: Gather Element Data

Read the target element(s):

cem://element/{tagName}
cem://element/{tagName}/attributes
cem://element/{tagName}/events

Understand the element's API to know which features need framework-specific handling:

  • Attributes (string-only): Work in all React versions
  • Properties (complex types): Need workarounds in React 18
  • Events (custom events): Need workarounds in React 18
  • Slots: Map to children and named slot patterns in JSX
  • Boolean attributes: Differ between React and HTML semantics

Phase 3: Generate Integration Code

React 19+

React 19 supports custom elements natively. Properties are set correctly and custom events are handled.

// Direct usage — no wrappers needed
function MyComponent() {
  return (
    <my-element
      variant="primary"
      complexData={someObject}
      onMyEvent={(e) => handleEvent(e)}
    >
      <span slot="icon">★</span>
      Button text
    </my-element>
  );
}

Key React 19 behaviors:

  • Props matching an element property are set as properties, not attributes
  • on + PascalCase event name maps to custom events (e.g., onChange -> change)
  • className is set as the class attribute
  • Boolean attributes work correctly

React 18 and Earlier

React 18 treats custom elements like unknown HTML elements — all props are set as attributes (stringified), and custom events are not supported via JSX.

Option A: Use @lit/react wrappers (recommended)

import { createComponent } from '@lit/react';
import { MyElement } from 'my-element-library';

export const MyElementReact = createComponent({
  tagName: 'my-element',
  elementClass: MyElement,
  react: React,
  events: {
    onMyEvent: 'my-event',
    onChange: 'change',
  },
});

// Usage
function MyComponent() {
  return (
    <MyElementReact
      variant="primary"
      complexData={someObject}
      onMyEvent={(e) => handleEvent(e)}
    >
      Button text
    </MyElementReact>
  );
}

Option B: Use refs for properties and events

function MyComponent() {
  const ref = useRef<HTMLElement>(null);

  useEffect(() => {
    const el = ref.current;
    if (!el) return;

    // Set complex properties via ref
    (el as any).complexData = someObject;

    // Add event listeners
    const handler = (e: Event) => handleEvent(e);
    el.addEventListener('my-event', handler);
    return () => el.removeEventListener('my-event', handler);
  }, [someObject]);

  return (
    <my-element ref={ref} variant="primary">
      Button text
    </my-element>
  );
}

Option C: Use the CEM export react wrappers

If the project uses CEM's export command, check for pre-generated React wrappers:

cem export react

This generates typed React wrapper components from the manifest.

TypeScript Declarations

For both React versions, add JSX type declarations so TypeScript knows about custom element attributes:

// custom-elements.d.ts
import type { MyElement } from 'my-element-library';

declare global {
  namespace JSX {
    interface IntrinsicElements {
      'my-element': React.DetailedHTMLProps<
        React.HTMLAttributes<MyElement> & {
          variant?: 'primary' | 'secondary';
          disabled?: boolean;
          // For React 18: only string attributes here
          // For React 19: include property types too
        },
        MyElement
      >;
    }
  }
}

For React 19, the declaration can include complex property types. For React 18, only include attributes (strings/booleans) since complex types won't pass through correctly without a wrapper.

Slot Mapping

Map named slots to JSX:

// HTML slots -> JSX
<my-element>
  {/* Default slot */}
  <span>Default content</span>

  {/* Named slots */}
  <span slot="header">Header content</span>
  <span slot="footer">Footer content</span>
</my-element>

Phase 4: Output

Present the integration code with:

  1. Version-appropriate code: Only show React 19 patterns if the project uses React 19+
  2. TypeScript declarations: If the project uses TypeScript
  3. Event handling: For each event in the manifest
  4. Property passing: For each non-string property
  5. Import statements: Show how to import the element registration

React Version Reference

| Feature | React 18 | React 19+ | |---------|----------|-----------| | String attributes | Passed as attributes | Passed as attributes | | Boolean attributes | "" or undefined | Correct HTML behavior | | Complex properties | Stringified (broken) | Set as properties | | Custom events | Not supported in JSX | onEventName works | | className | Set as attribute | Set as class | | ref | Works | Works | | SSR | Attributes only | Attributes only |

Guidelines

  • Check the React version first: The guidance differs significantly between 18 and 19
  • Prefer @lit/react wrappers for React 18: They handle properties and events correctly with minimal boilerplate
  • Generate TypeScript declarations from the manifest: The element's attributes and their types are all available
  • Don't suggest dangerouslySetInnerHTML: Custom elements use slots, not innerHTML
  • Handle SSR: Note that server-rendered custom elements only have access to attributes, not properties

Related Skills

View on GitHub
GitHub Stars0
CategoryDevelopment
Updated3d ago
Forks0

Trust signals

80/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 medium1 low