Skip to content

adapter-evm: /networks pulls @web3icons/react (+React) into headless consumers via iconComponent catalog data #61

Description

@pasevin

Summary

@openzeppelin/adapter-evm/networks pulls @web3icons/react (and therefore React) into consumers, because the network catalog carries iconComponent as data on every entry. For headless consumers this bloats the bundle substantially and has no functional purpose.

Follow-up to #59 (which fixed the capability subpaths for platform: node bundling in 2.3.1). This issue is the remaining half: the catalog subpath.

Evidence

Measured on @openzeppelin/adapter-evm@2.3.1, bundling a headless OpenZeppelin Relayer plugin with the relayer's own esbuild options:

esbuild entry.ts --bundle --platform=node --format=cjs --target=node22 \
  --external:'node:*' --external:'@openzeppelin/relayer-sdk'
  • Result: compiles (0 errors — fix(adapter-evm): bundle headless capability sub-paths for platform node #59 fixed the fatal .css import), but output is 1.0 MB
  • 2179 of 3616 bundle inputs are react / @web3icons/react, e.g.
    node_modules/@web3icons/react/dist/icons/tokens/TokenTOP.js, TokenRAVEN.js, TokenLEOX.js, …
  • Source: dist/networks*.mjs@web3icons/react; every catalog entry has iconComponent: _web3icons_react.NetworkEthereum (etc.)

The consumer only needs chain metadata (chainId, name, rpc, explorer). It never renders an icon — it is a headless Node process.

Why it matters

  • Headless consumers (relayer plugins, CLIs, codegen, indexers) ship an entire React icon library into a worker process
  • @web3icons/react is also ESM-only ("type": "module", exports["."] has no require condition), so require() of a CJS consumer that touches /networks fails with ERR_PACKAGE_PATH_NOT_EXPORTED

Suggested fix

Provide an icon-free catalog subpath — the chain data without the React component, e.g.:

  • @openzeppelin/adapter-evm/networks/data (or /networks-core) exporting the same entries minus iconComponent, or
  • make iconComponent lazily resolved / optional so it is not part of the catalog's static import graph

Browser consumers keep the current icon-bearing export unchanged.

Guard

#59 added a dist-level import-graph assertion (test/ri-capabilities-dist-isolation.test.ts) because the pre-existing ri-capabilities-subpath-isolation.test.ts is deliberately "build-free" and so analysed source graphs while the defect lived in the built chunks (specs/002-ri-evm-capabilities/spec.md:229 / SC-003 asks for built-entry analysis). Worth extending that same assertion to cover react / @web3icons reachability from the catalog subpaths.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions