eslint-plugin-react: [react/no-unknown-property] rule conflicts with `@react-three/fiber` on `` and other tags

I’m using @react-three/fiber in my app, and updating eslint-plugin-react broke the linting.

You did not took into account custom renderers while introducing this changes.

on <mesh /> false negatives:

Unknown property ‘castShadow’ found Unknown property ‘receiveShadow’ found Unknown property ‘dispose’ found Unknown property ‘geometry’ found Unknown property ‘userData’ found Unknown property ‘rotation’ found

on <meshStandardMaterial /> false negatives:

Unknown property ‘metalness’ found Unknown property ‘roughness’ found Unknown property ‘side’ found

on <planeBufferGeometry />

Unknown property ‘args’ found

on <meshPhongMaterial />

Unknown property ‘flatShading’ found Unknown property ‘shininess’ found Unknown property ‘side’ found Unknown property ‘specular’ found

and a lot more.

Please fix support for @react-three/fiber

Meanwhile I had to disable react/no-unknown-property rule

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 25
  • Comments: 85 (35 by maintainers)

Commits related to this issue

Most upvoted comments

The HTML standard says they shouldn’t, and it’s the authority on that.

@CodyJasonBennett I’m not sure what you mean. Anything lowercased either conforms to the html standard or is invalid, incorrect, and bad - that’s just the way react works.

Not cool. This is needlessly contrarian and frankly unprofessional. If you only want to support a subset of JSX that’s fine, but don’t play this blame game with anything outside of this model.

For anyone running into this issue in the future, the react fiber maintainers have released their own eslint plugin which fixes the issue.

(Also thanks to the maintainers of the react eslint plugin, it’s been a staple install for me for years!)

Since <mesh> is not a standard tag, and isn’t a custom element, it shouldn’t be used at all by that library.

That said, since React ignores nonstandard tags, so should we, which makes this a duplicate of #3420.

these assumptions

I’m aware that react 19 may support custom html elements React is react-dom mesh is not a standard tag Anything lowercased either conforms to the html standard or is invalid

are 100% wrong @ljharb, and it would be so easy for you to verify. lowercase in react has nothing to do with html or custom html elements. it designates a native host element. each renderer defines these for its host platform. this is fundamentally how react works.

renderers in react are a first class principle, react-dom adheres to the exact same rules every other renderer, including fiber. they all create a reconciler form defining their lowercase host elements. react-dom defines div and span, fiber mesh and group, and there are countless of others.

React isn’t a renderer but a reconciliation algorithm. react-three-fiber isn’t doing something terribly niche with React; it’s just not react-dom. React Native and projects like react-blessed have been using this renderer-agnostic aspect of JSX/React for far longer than React 19; I’m surprised this specifically didn’t come up in November. It’s certainly not true that anything lowercase conforms to the html standard; I don’t even think that’s true for react-dom.

I don’t really know how this relates to eslint in particular, but yeah this basically makes this plugin eslint-plugin-react-dom, not eslint-plugin-react.

@coobeeyon custom compoments are defined by their author; html elements are defined by the browser.

there’s multiple libraries that do things they shouldn’t

Who says they shouldn’t? Many Custom react renderers exist and I am not aware of anyone saying this shouldn’t be done. If anything, the react team has been supportive.

That is not true. I suggest learning how React and host components work; React is x-platform in nature.

This is advanced stuff, so I guess advanced people can handle to manually setup the config by copy-pasting somebody’s solution. We already configuring an advanced list of plugins and rules for eslint.

There should be a way to use custom renderers. Three.js and react-three-fiber are perfect combination for performant 3d in canvas.

I’ve attempted 3d in react multiple times through 8 years, but it was always not ready for production, until react-three-fiber has been created. It is popular enough, and constantly maintained to be at least considered essential for developers.

Well it seems like there are a lot of libraries which are not currently compliant. From what I can see it’d be a very small chance to add a “lenient” or “legacy” setting which would skip checking lower cased components if they weren’t defined in the standard. And that change would help the lives of a lot of folks.

ok - thanks for responding - appreciate that. I’ll probably need to ignore 1,000 properties. Unfortunately it looks like you don’t understand how renderers work. PascalCase are components handled by react. lowercase components are intrinsic elements handled by the renderer (not just the DOM renderer). In other words, lowercased components in react are NOT only HTML elements. Your profile says you are obsessed with backwards compatibility, so bit surprising, but thanks again for clarifying! cheers.

The former would be a potential footgun - the latter, though, seems workable, albeit complex.

This library is definitely a part of eslint-config-react-app, which is propagated to other libraries and projects including nextjs and I think gatsbyjs too. So basicaly this issue would be facing everybody who tries to use custom renderers in any of major frameworks. I’m sure this issue already killed a ton of time of everybody following it and will kill much more in the future and this thread will continue until somebody do something about it.

Hmm, that actually might be a reasonable compromise. Is there any overlap between fiber’s made-up element tag names and HTML element tag names? If not, we could add an option to ignoreUnknownHostElements.

Here’s a list of non-DOM renderers this rule ignores:

https://github.com/chentsulin/awesome-react-renderer

For anyone running into this issue in the future, the react fiber maintainers have released their own eslint plugin which fixes the issue.

(Also thanks to the maintainers of the react eslint plugin, it’s been a staple install for me for years!)

That doesn’t fix the issue, it can’t replace eslint-plugin-react.

@brianzinn in the sense that any bugfix is a breaking change, sure - but this was how the rule was always meant to behave.

@FalconPilot Regarding jsx, it’s not a convention - the jsx specification says that lowercase tag names are “host” elements, which means they indeed delegate to the renderer.

The react renderer (including RN), however, has made host elements largely be HTML (and sometimes SVG) elements. This means that when a custom renderer chooses a different semantic for host elements (which jsx allows!) then it’s no longer compatible with react-specific jsx - which is what this plugin is solely focused on.

In react, anything lowercase can’t be a custom component, which is why React Native uses non-lowercase components for its primitives like Text etc.

React is react-dom (RN specifically doesn’t clash with react-dom, on purpose). It’s not eslint-plugin-jsx, it’s eslint-plugin-react, and that means the react ecosystem. This isn’t a renderer-agnostic plugin, nor are most things in the ecosystem.

You are welcome to disable the rule if it doesn’t work for you.

@cruhl let’s consolidate it a bit - what about something where it’s a single rule config keyed object, where the keys of the object are tag names, and the values are also an object, which has a “tag” string and a “properties” object (that lists the valid property names for that tag)?

it’d be a bit annoying if you have a single property you want added to a dozen tags, but i don’t think config convenience is what’s important here.

@cruhl it doesn’t necessarily work with React Native either, so yes, it’s a React DOM plugin, named “react” because at the time it was created that was the only renderer.

It could potentially handle additional renderers, but that would have to be approached with the attitude of “please add this complexity” and not “i’m entitled to your free labor and how dare you not have already thought of my use case in advance”.

I think react and its arbitrary renderers are being conflated:

CleanShot 2024-02-06 at 17 18 39

React does not contain a renderer, ReactDOM does, so for this to be considered the “React plugin” and not the “React DOM plugin” it would need to support arbitrary renderers right?

CRA is deprecated anyways and should never have been used for anything but rapid prototyping, or learning.

The react/no-unknown property makes the perfectly reasonable and virtually universally true assumption that react-dom is being used for non-custom JSX components.

The complexity is in designing a schema that can cover “any random hallucination some renderer can come up with” while still being trivial to configure to common use cases, and while avoiding confusing, slow, and hard to maintain code in the rule itself.

@brianzinn there’s nothing to accept - the rule already has an ignore config, which you can use to ignore any nonstandard properties you like.

If you want free reign to name properties anything you like, then components need to be named in PascalCase, since lowercased components in react are only HTML elements.

I also agree that it is a non standard tag, but three.js has massive user base, so could it be a separate option to support react-three-fiber tags and attributes? They do have good typescript support.