I found IWYU pretty annoying, due to its tendency to also include transitive includes. Some of those often end up about implementation details and are much more likely to be added/removed. But maybe the projects using it that I worked on were using it wrong?

If the issue is with including transitive dependencies that are in your own codebase, then you should annotate the public interface header to the implementation details with IWYU Pragmas [1] that export the implementation (for example [2]).

If this is in third-party libraries, you can use IWYU Mappings [3] to map the "private" headers (usually the transitive include) to the public interface. An example that I use for the PEGTL library [4].

[1]: https://github.com/include-what-you-use/include-what-you-use...

[2]: https://github.com/anand-bala/signal-temporal-logic/blob/800...

[3]: https://github.com/include-what-you-use/include-what-you-use...

[4]: https://github.com/anand-bala/signal-temporal-logic/blob/800...