Yep that’s why said it’s a gotcha. As a team you have to decide the attribute/prop tradeoff and stick to it in a consistent way.
By using attrs, they show up in dom explorer, so it’s neat, don’t need another devtool. attributeChangedCallback will only be called when the attribute changes.
For props, it’s a bit more work since HTMLElement itself has a ton of built in props, using a setter means anytime something sets, it will he called, even if the property value isn’t different. the worst thing is when you end up overriding an internal prop and weird things happen.
In practice, most libraries built around web components only use attributes when serializing / deserializing HTML strings. When performing updates to existing DOM, it is very common for a library to use a corresponding property instead. This is very fast, supports all types of values, and many libraries enable users to think in terms of attributes while the library updates properties under the hood (conceptually similar to the React mental model).