# Include What You Use: what IWYU enforces, and what it costs to run it on a real C++ tree

> Include What You Use is a Clang-based analyzer that reports which headers each C++ source or header file should include, and which of its current includes are unused. It is aimed at teams that can pin their compiler and accept some false positives in exchange for removing transitive include dependencies.

**include-what-you-use/include-what-you-use** — A tool for use with clang to analyze #includes in C and C++ source files

- Repository: https://github.com/include-what-you-use/include-what-you-use
- Website: https://include-what-you-use.org
- Stars: 4,772 · Forks: 435
- Language: C++
- License: NOASSERTION
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/include-what-you-use-include-what-you-use

## The problem IWYU solves, and the rule it enforces

The rule is stated plainly in the README: for every symbol (type, function, variable, or macro) used in foo.cc, either foo.cc or foo.h should include a header that exports the declaration of that symbol. Symbols defined in foo.cc itself are exempt. The consequence the README draws is that when every file includes what it uses, you can edit any file and remove unused headers without breaking the upward dependencies of that file.

This is a dependency-hygiene tool, not a linter for style. It is for C and C++ codebases where headers are pulled in transitively: foo.cc compiles because foo.h includes bar.h, and nobody notices that foo.cc never needed bar.h. The audience is maintainers of long-lived trees, particularly ones with a build system that can already emit a compilation database, since the tool needs real compile flags to parse each file. The README also notes the tool was originally written to work specifically in the Google source tree, and may make assumptions or have gaps that are immediately evident in other types of code. That sentence should shape your expectations more than any feature list.

## How the analysis works and what the driver emits

IWYU is not a standalone parser. The repository layout shows a driver (iwyu_driver.cc, iwyu_main.cc) plus a set of analysis units: iwyu_ast_util.cc for AST queries, iwyu_preprocessor.cc, iwyu_lexer_utils.cc, iwyu_location_util.cc, iwyu_include_picker.cc and iwyu_cache.cc. It hooks into Clang's compilation and observes which declarations the compiler actually resolves for each symbol use, then compares that set against the includes present in the file. The include picker is what decides which header should provide a symbol, and that is where the mapping files at the repository root come in: boost-all.imp, boost-1.75-all.imp, clang-22.intrinsics.imp, gcc-8.intrinsics.imp and similar .imp files map symbols to the headers the tool should recommend.

The output is a report, not a rewrite. The README describes two companion scripts in the tree: iwyu_tool.py, which drives the analysis over a project, and fix_includes.py, which applies the suggested edits. Because the suggestions are textual, the review burden is real: a wrong suggestion that removes a header still needed by a platform-specific branch will surface as a build break, not as a warning. The README's own caveat says the project is experimental as of June 2024 and that new features are being held back while quality work and known bugs are prioritized.

## Installing IWYU: match the Clang branch before you build

The README states IWYU is released in source form, both as GitHub releases and at include-what-you-use.org. There is no binary installer described in the README. The build depends on prebuilt LLVM and Clang libraries, and the version pairing is the first thing to get right: the README's table maps Clang 22 to IWYU 0.26 and branch clang_22, Clang 21 to 0.25 and clang_21, and so on down the table. The IWYU master branch follows the Clang main branch.

Start by cloning and checking out the branch that matches your installed Clang:

```bash
git clone https://github.com/include-what-you-use/include-what-you-use.git
cd include-what-you-use
git checkout clang_6.0
```

The README uses clang_6.0 as its example; substitute the branch from the table that matches your Clang. Then configure out of tree. For IWYU 0.11 and later the README uses CMAKE_PREFIX_PATH rather than the older IWYU_LLVM_ROOT_PATH variable:

```bash
cd ..
mkdir build && cd build
cmake -G "Unix Makefiles" -DCMAKE_PREFIX_PATH=/usr/lib/llvm-7 ../include-what-you-use
make
```

If you built LLVM yourself, the README shows passing that build tree instead, for example -DCMAKE_PREFIX_PATH=~/llvm-project/build. On Debian or Ubuntu using the packages from apt.llvm.org, the README lists llvm-<version>-dev, libclang-<version>-dev and clang-<version> as the packages you need, and warns that packaging on other platforms will likely be subtly different. Releases are signed; the README documents verifying an archive with gpg against the public key published at include-what-you-use.org.

## A first real run over one translation unit

A first run should be one file, not the whole tree. The tool needs the same flags your build uses, because it parses the file the way the compiler would. The repository ships iwyu_tool.py, which is the practical entry point for a project because it takes a compilation database and runs the analyzer per entry.

The README does not spell out a full command line for iwyu_tool.py in the section reproduced here, so treat the script's own usage output as the source of truth for flags. What is documented is the workflow: analyze, then apply. After the analysis produces its report, fix_includes.py consumes it and edits the files. Run it on a clean working tree, and read the diff before committing, because the tool is making textual edits based on the diagnostics. The repository also contains iwyu-run-stdin-tests.bash and iwyu-dogfood.bash, scripts the project uses to exercise the tool on its own sources.

The analysis is invoked per translation unit with the compile flags your build already uses, and the resulting report is what fix_includes.py reads. Expect the first pass on an unfamiliar codebase to produce a large number of suggestions, some of which you will reject. That is normal for a tool whose README calls itself experimental.

## Where IWYU is the wrong tool

The sharpest limitation is compiler coupling. The README says IWYU makes heavy use of Clang internals and will occasionally break when Clang is updated, and that the project builds regularly against Clang mainline to catch those breaks. That is a maintenance commitment on the project's side, but it is also a commitment on yours: if you upgrade Clang without moving to the matching IWYU branch, you are outside the supported pairing. A team that tracks a rolling Clang from a distribution channel, or that builds with GCC as the primary compiler, gets much less from this tool than the README's framing suggests.

The second limitation is accuracy. The README is unusually direct: this is experimental software, it was written for the Google source tree, and it may make assumptions or have gaps that are immediately evident elsewhere. The stated policy is to stint new features and prioritize reported bugs, including the many known ones. So a suggestion you disagree with is not necessarily a bug you can get fixed quickly; the README says the best chance of a fix is a patch with a test case. If your code relies on macro-heavy headers, generated headers, or platform conditionals that the analyzer cannot see through, the reports will include false positives, and the cost of triaging them falls on you. For a small project with few headers, the effort of setting up a matching Clang and reviewing diffs can exceed the benefit of tidying includes by hand.

## How IWYU differs from a compiler warning or a formatter

The obvious alternative is doing nothing beyond what the compiler already reports. GCC and Clang will tell you about missing declarations, but they will not tell you that a header you include is unnecessary, because unnecessary includes are not errors. Clang's own -Wunused-* family covers unused variables and functions, not unused #includes. That difference in scope is the whole reason IWYU exists: it answers a question the compiler has no reason to ask.

A second alternative is include-what-you-use's own mapping files used by hand, or a style guide that says include only what you use and leaves enforcement to review. That approach costs nothing to install and fails silently the moment a reviewer is busy. IWYU trades that silence for a build that is coupled to a specific Clang version and a report that needs triage. The trade is worth it in a tree where headers have accumulated transitive dependencies over years, and it is not worth it in a tree where the include graph is already small enough to read.

## Maintenance cost, licence status and what to verify

The release cadence visible in the repository is roughly two per year: 0.24 in April 2025, 0.25 in September 2025, 0.26 in March 2026. The last push to the repository was on 2026-09-16, so the project is being worked on, but the README's own framing is that quality work and known bugs take priority over new features. Budget for the version pairing as recurring work: every Clang upgrade means checking the table, switching to the matching IWYU branch, and rebuilding against the new LLVM and Clang libraries. The .imp mapping files at the repository root are also versioned per toolchain, with separate files for boost 1.64, boost 1.75, clang 6 and clang 22 intrinsics, and gcc 8 intrinsics, which tells you the mappings are not universal.

The repository's licence file is LICENSE.TXT, and the metadata reports the licence as NOASSERTION, meaning the machine-readable licence field could not be resolved to a standard identifier. That is not a statement that the project is unlicensed; it means you should read LICENSE.TXT and, if your organisation has rules about which licences may be used, have someone confirm the terms before you ship anything derived from the tree. This article is not legal advice. Before adopting, verify three things: that a branch exists for your Clang version in the compatibility table, that the build succeeds against your installed LLVM and Clang packages, and that a trial run on one translation unit produces suggestions you would accept.

## Conclusion

Adopt Include What You Use if your project already builds with a specific Clang release you can pin, and you want include hygiene enforced rather than reviewed by eye. Do not adopt it if you build with GCC as your only compiler, if you compile against a moving LLVM main, or if you cannot review automated include edits. Before anything else, match your Clang version to the IWYU branch in the compatibility table, build the tool, and run it on one translation unit to see how many suggestions you actually agree with.

## FAQ

### What does Include What You Use (IWYU) do?

It analyzes a C or C++ file and reports which headers that file should include in order to declare the symbols it uses, and which of its current includes are unnecessary. It runs as part of a Clang-based compilation and ships fix_includes.py to apply the suggestions.

### Is there an alternative to Include What You Use?

The practical alternative is relying on compiler diagnostics and code review, since compilers report missing declarations but not unnecessary includes. IWYU's value is exactly the case the compiler does not cover: includes that are present but unneeded.

### Which Clang version does Include What You Use need?

The README provides a mapping table pairing Clang releases with IWYU versions and branches, for example Clang 22 with IWYU 0.26 on branch clang_22. The IWYU master branch follows the Clang main branch.

### How do I install Include What You Use?

The README states it is released in source form. You clone the repository, check out the branch matching your Clang version, and configure with CMake using CMAKE_PREFIX_PATH pointing at your LLVM and Clang installation, then run make.

### Does Include What You Use work with GCC?

The tool is built on Clang internals and its build instructions require LLVM and Clang libraries. The repository does ship gcc-8.intrinsics.imp, a mapping file for GCC intrinsics, but the analyzer itself is a Clang-based build.

## Sources

- [include-what-you-use/include-what-you-use on GitHub](https://github.com/include-what-you-use/include-what-you-use)
- [Issues](https://github.com/include-what-you-use/include-what-you-use/issues)
- [Project website](https://include-what-you-use.org)
- [README](https://github.com/include-what-you-use/include-what-you-use/blob/master/README.md)
- [Releases](https://github.com/include-what-you-use/include-what-you-use/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/include-what-you-use-include-what-you-use
