Agent skill

Safe Element Comparison

by seasonedcc in seasonedcc/remix-forms

Maintain element type comparison safety in remix-forms. An agent skill from seasonedcc/remix-forms.

MITAuto-check passedFrontend & Design

Install Safe Element Comparison

skills CLI
$ npx skills add seasonedcc/remix-forms --skill safe-element-comparison -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install seasonedcc/remix-forms safe-element-comparison --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/seasonedcc/remix-forms.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/safe-element-comparison .claude/skills/safe-element-comparison && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
safe-element-comparison
GitHub stars
514
Token cost
~1.8k tokens
SKILL.md length
863 words
Files
1
Skills in repo
3
Repo updated
First seen
Licence
MIT

At a glance

Maintain element type comparison safety in remix-forms. An agent skill from seasonedcc/remix-forms.

  • Works in 4 steps: Create a Default* forwardRef wrapper at… → Use it as the default parameter value —… → If the component will be compared via… → …
  • Modifying component mappings
  • SKILL.md covers How It Works, Current Architecture, Rules for Development and User-Facing Guidance, plus 2 more sections
  • Instructions only: no scripts, shell commands, URLs or credentials in SKILL.md

What it does

Safe Element Comparison is an agent skill from seasonedcc/remix-forms. Maintain element type comparison safety in remix-forms. Use when modifying component mappings, adding new components to mapChildren, investigating unexpected HTML attributes or prop injection, writing docs about component customization, or responding to user issues about wrong elements receiving props.

Its SKILL.md is about 1.8k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering React components. It works with React, React Router, Remix and TypeScript. The repository describes itself as: Full-stack forms for React Router. The licence is MIT.

When your agent uses it

  • Modifying component mappings
  • Adding new components to mapChildren
  • Investigating unexpected HTML attributes
  • Writing docs about component customization

Example prompts

  • “/safe-element-comparison”

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Create a Default* forwardRef wrapper at module scope in the appropriate file.
  2. Use it as the default parameter value — never use a string tag name.
  3. If the component will be compared via child.type === in any mapChildren callback, write a test verifying plain HTML elements of the same…
  4. Update the inventory table in this skill.

What it can do on your machine

Read from SKILL.md and the folder at commit 7030d30. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    No scripts in the folder and no shell commands in SKILL.md.

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Safe Element Comparison loads about 1.8k tokens when it runs. Until then it costs about 82 tokens; SKILL.md has 863 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~82
When it runs · the whole SKILL.md, loaded when a task matches
~1.8k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from seasonedcc/remix-forms at commit 7030d30, republished under its MIT licence (© seasonedcc). 863 words, ~1,805 tokens.

Download SKILL.mdSave it as .claude/skills/safe-element-comparison/SKILL.md (or your agent's skills folder).
name
safe-element-comparison
description
Maintain element type comparison safety in remix-forms. Use when modifying component mappings, adding new components to mapChildren, investigating unexpected HTML attributes or prop injection, writing docs about component customization, or responding to user issues about wrong elements receiving props.
metadata.internal
true

Safe Element Comparison

remix-forms identifies components in JSX trees using child.type === Component. This pattern is central to how mapChildren injects props into the right elements. This skill covers the architecture, the rules for keeping it safe, and guidance for users.

How It Works

mapChildren in children-traversal.ts recursively walks the React element tree returned by user render functions. Callback functions in create-field.tsx and schema-form.tsx compare child.type against component references to decide which props to inject.

React element types follow these rules:

  • <div> compiles to React.createElement('div') — type is the string 'div'
  • <MyComponent /> compiles to React.createElement(MyComponent) — type is the function/object reference
  • React.forwardRef(fn) returns a unique object — === comparison works reliably when defined at module scope
  • React.cloneElement preserves .type exactly
  • React Fast Refresh preserves component identity in development

If a component reference were a string like 'div', then child.type === Component would match every <div> in the tree — not just the intended component. This is why all default components are React.forwardRef wrappers with unique object identity.

Current Architecture

All default components are defined at module scope as React.forwardRef wrappers. Each renders its corresponding HTML element and nothing else. Components that render the same HTML tag (e.g. DefaultInput, DefaultCheckbox, DefaultRadio all render <input>) are separate objects with distinct identities.

create-field.tsx
Default wrapperRendersUsed as default for
DefaultField<div>fieldComponent
DefaultLabel<label>labelComponent
DefaultInput<input>inputComponent
DefaultMultiline<textarea>multilineComponent
DefaultSelect<select>selectComponent
DefaultCheckbox<input>checkboxComponent
DefaultRadio<input>radioComponent
DefaultRadioGroup<fieldset>radioGroupComponent
DefaultRadioLabel<label>radioLabelComponent
DefaultCheckboxLabel<label>checkboxLabelComponent
DefaultFieldErrors<div>fieldErrorsComponent
DefaultFieldError<div>errorComponent
schema-form.tsx
Default wrapperRendersUsed as default for
DefaultFieldsWrapper<div>fieldsComponent
DefaultGlobalErrors<div>globalErrorsComponent
DefaultButton<button>buttonComponent

DefaultFieldError is imported from create-field.tsx and reused as the default for errorComponent in SchemaForm.

Rules for Development

Adding a new component mapping
  1. Create a Default* forwardRef wrapper at module scope in the appropriate file.
  2. Use it as the default parameter value — never use a string tag name.
  3. If the component will be compared via child.type === in any mapChildren callback, write a test verifying plain HTML elements of the same tag are not affected.
  4. Update the inventory table in this skill.
Modifying existing components
  • Preserve unique identity. Each default must be its own distinct object, even when multiple defaults render the same HTML tag.
  • Keep defaults at module scope. Moving them inside a function creates new references each call, breaking === comparisons and causing React remounts.
Never do
  • Never use a string tag name as a default — it matches every element of that tag in the tree.
  • Never wrap defaults in React.memo() — memo creates a new wrapper object; child.type === original silently fails.
  • Never wrap defaults in React.lazy() — lazy also creates a wrapper that doesn't match the inner component.
  • Never define defaults inside render functions — new identity each render breaks === and causes full remounts.

User-Facing Guidance

When communicating with users about component customization:

Passing custom components
  • Recommended: Pass a React component (function, class, or forwardRef). The === comparison is safe because each component has a unique reference.
  • Not recommended: Pass a string tag name like "div". The comparison becomes ambiguous — any element of that tag in the children function will be matched.
  • When a user reports unexpected attributes on their elements, check whether they passed a string for a component prop.
Show full SKILL.md (329 more words)Show less
The React.memo limitation

If a user wraps a custom component in React.memo() before passing it, the comparison will fail silently — memo() creates a wrapper object that doesn't match the inner component. This is an inherent limitation of the child.type === pattern. Advise users to pass the unwrapped component.

What users should know
  • Components passed to SchemaForm (like inputComponent, labelComponent, etc.) are identified by reference equality in the JSX tree.
  • Custom HTML elements of the same tag type as a component prop will not be misidentified — the library's defaults use unique component wrappers.
  • When using the children render function pattern (renderField or SchemaForm children), any component received from the helpers object (e.g. Label, Input, Errors) has special identity that the library uses to inject the right props.

Diagnosing Issues

When a user reports unexpected HTML attributes (e.g. role="alert" on a wrapper div, or name="..." on an unrelated input):

  1. Check if they're using the children render function — this is where mapChildren runs and where false matches can occur.
  2. Check if they passed a string for a component prop — e.g. fieldErrorsComponent="div". This restores the ambiguity the defaults are designed to prevent.
  3. Check if they wrapped a component in React.memo() — this causes false negatives (the component is NOT recognized, so it doesn't receive its intended props).
  4. Check mapChildren callbacks — verify that the child.type === comparison targets the correct variable and that the variable is a unique component reference.
  5. Check for new comparisons — if someone added a new child.type === check, verify it follows the rules above.

Testing

For each component compared in mapChildren, maintain a regression test that:

  1. Renders a Field (or SchemaForm) with a children function.
  2. Includes BOTH the library component AND a plain HTML element of the same tag.
  3. Asserts the library component receives injected props.
  4. Asserts the plain HTML element does NOT receive injected props.

Existing tests live in create-field.test.tsx (describe block: "element type comparison safety") and schema-form.test.tsx (describe block: "element type comparison safety").

© seasonedcc, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/safe-element-comparison of seasonedcc/remix-forms.

Open the folder on GitHubat commit 7030d30

Compare with similar skills

Safe Element Comparison next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Safe Element Comparison compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Safe Element Comparison this skillseasonedcc/remix-forms514—~1.8kAutomated safety check: PassMIT
React Devdavila7/claude-code-templates33k2 repos~2.6kAutomated safety check: PassMIT
React Idiomsirahardianto/awesome-agv156—~3.8kAutomated safety check: PassMIT
Using Docs Kitlobehub/lobe-ui2.2k—~2.8kAutomated safety check: PassMIT
React Render Types CompositionHorusGoul/eslint-plugin-react-render-types111—~1.1kAutomated safety check: PassMIT
Frontend Typescript Rulesshinpr/ai-coding-project-boilerplate234—~1.7kAutomated safety check: PassMIT

Similar skills

  • React Dev

    davila7/claude-code-templates

    This skill should be used when building React components with TypeScript, typing hooks, handling events, or when React TypeScript, React 19, Server Components are mentioned.

    33k GitHub starsUsed in 2 repos~2.6k tokens
    Frontend & DesignAuto-check passed
  • React Idioms

    irahardianto/awesome-agv

    React 19+ patterns: custom hooks, Suspense boundaries, state management, component composition, and web performance.

    156 GitHub stars~3.8k tokensUpdated 5 days ago
    Frontend & DesignAuto-check passed
  • Using Docs Kit

    lobehub/lobe-ui

    Set up and author a documentation site with @lobehub/docs-kit (the lobedocs CLI, React Router + Vite static docs used by ui.lobehub.com).

    2.2k GitHub stars~2.8k tokensUpdated today
    Frontend & DesignAuto-check passed
  • React Render Types Composition

    HorusGoul/eslint-plugin-react-render-types

    Composition patterns for building React components with @renders type annotations from eslint-plugin-react-render-types.

    111 GitHub stars~1.1k tokensUpdated 2 mo ago
    Frontend & DesignAuto-check passed
  • Frontend Typescript Rules

    shinpr/ai-coding-project-boilerplate

    Applies React/TypeScript type safety, component design, and state management rules.

    234 GitHub stars~1.7k tokensUpdated 6 days ago
    Frontend & DesignAuto-check passed
  • Typescript Rules

    shinpr/claude-code-workflows

    React/TypeScript frontend development rules including type safety, component design, state management, and error handling.

    694 GitHub stars~1.8k tokensUpdated 9 days ago
    Frontend & DesignAuto-check passed

More from seasonedcc/remix-forms

  • Release

    seasonedcc/remix-forms

    Release a new version of the remix-forms npm package. An agent skill from seasonedcc/remix-forms.

    514 GitHub stars~1.3k tokensUpdated 5 mo ago
    Auto-check passed
  • Skill Manager

    seasonedcc/remix-forms

    Create, manage, and debug Claude Code Agent Skills. An agent skill from seasonedcc/remix-forms.

    514 GitHub stars~6.1k tokensUpdated 5 mo ago
    Auto-check passed

Questions about Safe Element Comparison

What does Safe Element Comparison do?

Maintain element type comparison safety in remix-forms. An agent skill from seasonedcc/remix-forms. Safe Element Comparison is an agent skill from seasonedcc/remix-forms. Maintain element type comparison safety in remix-forms.

When should I use Safe Element Comparison?

Safe Element Comparison fits situations like: modifying component mappings; adding new components to mapChildren; investigating unexpected HTML attributes; writing docs about component customization.

How do I install Safe Element Comparison in Claude Code?

Run `npx skills add seasonedcc/remix-forms --skill safe-element-comparison -a claude-code`. Or copy the skill folder (.claude/skills/safe-element-comparison in seasonedcc/remix-forms) into .claude/skills/safe-element-comparison in your project. Claude Code loads it when a task matches its description.

How do I install Safe Element Comparison in Codex?

Run `npx skills add seasonedcc/remix-forms --skill safe-element-comparison -a codex`. Or copy the skill folder (.claude/skills/safe-element-comparison in seasonedcc/remix-forms) into .agents/skills/safe-element-comparison in your project. Codex loads it when a task matches its description.

Can I use Safe Element Comparison in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add seasonedcc/remix-forms --skill safe-element-comparison -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/safe-element-comparison, .gemini/skills/safe-element-comparison, .github/skills/safe-element-comparison and .opencode/skills/safe-element-comparison in your project.

What does Safe Element Comparison need to run?

SKILL.md names no scripts, command-line tools or credentials: Safe Element Comparison is instructions for the agent only.

Does Safe Element Comparison access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Safe Element Comparison safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Safe Element Comparison use?

Safe Element Comparison is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Safe Element Comparison use?

About 1.8k tokens (SKILL.md is roughly 7.2k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Safe Element Comparison?

Skills that share tags, products or a category with Safe Element Comparison: React Dev (davila7/claude-code-templates, 33k stars), React Idioms (irahardianto/awesome-agv, 156 stars), Using Docs Kit (lobehub/lobe-ui, 2.2k stars) and React Render Types Composition (HorusGoul/eslint-plugin-react-render-types, 111 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Safe Element Comparison?

seasonedcc (a GitHub organization) maintains it in seasonedcc/remix-forms, which has 514 GitHub stars. The repository holds 3 skills in this directory. The repository was last updated on April 15, 2026.

Source: seasonedcc/remix-forms on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.