SYSTEM Cited by 1 source
DIWYDU (Don't Include What You Don't Use)¶
What it is¶
DIWYDU (Don't Include What You Don't Use) is Figma's internal static-
analysis tool for detecting unnecessary #include directives in C++ source
and header files. It runs in CI on feature branches as part of Figma's
broader effort to keep post-pre-
processing byte counts under control.
Built on libclang's Python bindings; parses every first-party source + header file, walks the Abstract Syntax Tree, and for each file captures the set of symbols (types, functions, variables) the file directly references. An included header is flagged "unnecessary" if none of its exported symbols appear among the file's direct references.
What makes it different from IWYU¶
The closest public analogue is Google's IWYU, also Clang-based. The key policy difference:
- IWYU requires the precise minimal include set. Every symbol used
must have its exact defining header
#included directly — no relying on transitive includes. Provably correct; maximally strict. - DIWYDU requires only that every
#includehave something directly used from it. Extra direct includes are fine; relying on transitive includes for symbols whose home-header isn't directly included is fine.
The trade-off is retrofittability. From the article:
[IWYU] strives for each file to have the precise set of includes, which makes it challenging to apply retroactively to a substantial codebase.
Instead of requiring that you include the exact set of headers, it would only ensure that the current file utilizes something directly from each header it includes. While IWYU was more stringent, we took a more relaxed approach so that it would be easier to implement and deploy in our codebase.
Figma attempted IWYU adoption twice before building DIWYDU; both rolled back. DIWYDU's laxer policy is explicitly what made a codebase-wide rollout tractable.
What it misses (by construction)¶
DIWYDU cannot catch the "used-but-enormous" regression class: when a file directly references a symbol from a header, DIWYDU sees a valid direct use and is silent — even if including that header drags in megabytes of transitive content. This is why Figma also built systems/includes-py — the complementary measurement tool for the other cost mode.
Known limitations¶
- STL headers excluded. Standard-library headers commonly define
exported symbols (e.g.
std::vector) in private includes not named by the public header. DIWYDU's "this header declares this symbol" check can't follow the private chain, so it skips stdlib. IWYU has the same limitation. Safe for Figma because stdlib usage is gated to one wrapper directory. UNEXPOSED_EXPRAST nodes. libclang's Python bindings wrap its C bindings, which expose a reduced view of the Clang AST compared to the native C++ library. Some expressions surface asUNEXPOSED_EXPRwith incomplete type information; DIWYDU falls back to "less elegant solutions" (presumably heuristic or dropped). Article flags reimplementing DIWYDU in C++ (full Clang API) as a possible next step.
Deployment¶
- Runs in CI on feature branches.
- Figma reports the full tooling suite (DIWYDU + systems/includes-py) prevents 50-100 potential slowdowns per day from reaching master.
- Initial deployment + one-shot cleanup of the largest files produced 31% compiled-byte reduction and 25% cold-build-time reduction — evidence that unused includes were a dominant cost driver.
Relationship to includes.py¶
| DIWYDU | systems/includes-py | |
|---|---|---|
| What it catches | Includes never directly used | Includes that are used but bring huge transitive trees |
| Mechanism | Clang AST → symbol-to-header map | Pure-Python byte counter over include DAG |
| Fix recipe | Delete the #include |
concepts/forward-declaration / split the header |
| Runtime | AST parse (slower) | Seconds (no Clang) |
| CI role | Feature-branch lint | Per-PR regression gate |
Both are precursor technologies to the patterns/ci-regression-budget-gate pattern at Figma.
Seen in¶
- sources/2024-04-27-figma-speeding-up-c-build-times — two-tool split
(DIWYDU for "unused" class,
includes.pyfor "used-but-huge" class) as the build-time mitigation architecture after IWYU adoption failed twice.