What is the Gradle Tooling API, and what models does an IDE typically request from it during sync?
answer
- programmatic API to drive Gradle
- ProjectConnection.getModel / newBuild
- GradleProject, IdeaProject, EclipseProject, BuildEnvironment
- BuildAction + ToolingModelBuilder for custom models
- daemon, cancellation, version-tolerant
basics
~20 sThe Tooling API is Gradle's programmatic API for driving a build from another process and getting structured models back (instead of parsing output). IDEs use it to fetch project models like GradleProject, IdeaProject/EclipseProject, build environment info, and to run tasks with progress events.
solid answer
~50 sThe **Tooling API** is the official, versioned API (`org.gradle:gradle-tooling-api`) for embedding/controlling Gradle from another JVM process — IDEs, CI tooling, custom launchers. A client opens a `ProjectConnection` to a project directory, then either **fetches a model** (`getModel(...)`) or **runs tasks/build actions** (`newBuild()`, `BuildActionExecuter`), receiving typed objects and **progress/event streams** rather than scraping console text. During sync an IDE requests models such as: - **`GradleProject`** — the project/task hierarchy. - **`IdeaProject`** (IntelliJ) / **`EclipseProject`** (Buildship) — IDE-oriented module, source-set, and dependency descriptions. - **`BuildEnvironment`** — Gradle version, JVM, daemon JVM args. - Custom models via a **`BuildAction`** run inside Gradle (`controller.getModel(...)`), letting plugins expose their own metadata to the IDE. Building these models forces init+configuration to run. The Tooling API manages the **daemon**, supports **cancellation**, and is **version-tolerant** (a newer client can talk to older Gradle, within support windows), which is why IDEs can drive many Gradle versions.
code
kotlin · 8 linesGradleConnector.newConnector()
.forProjectDirectory(File("/path/to/project"))
.connect().use { connection ->
val model = connection.getModel(IdeaProject::class.java)
model.modules.forEach { m ->
println(m.name + " deps=" + m.dependencies.size)
}
}go deeper
Know the Tooling API exists and the IDE uses it to talk to Gradle.
Describe ProjectConnection + getModel and name GradleProject/IdeaProject as sync models.
Explain model fetching vs build launching, custom models via BuildAction/ToolingModelBuilder, daemon/cancellation/version tolerance.
Reason about building custom IDE integrations or large-repo sync performance and the API's compatibility guarantees.
## What the Tooling API is The **Gradle Tooling API** (artifact `org.gradle:gradle-tooling-api`) is a stable, version-tolerant client library for **driving Gradle programmatically** from a separate process. Instead of running `gradle` and parsing stdout, a tool gets **typed model objects** and **structured progress events**. It is what IDEs (IntelliJ, Eclipse Buildship), build scan tooling, and custom launchers use under the hood. ## Core flow ```java try (ProjectConnection connection = GradleConnector.newConnector() .forProjectDirectory(new File("/path/to/project")) .connect()) { // 1) Fetch a model GradleProject project = connection.getModel(GradleProject.class); // 2) Or run a build connection.newBuild() .forTasks("build") .addProgressListener(event -> { /* live events */ }) .run(); } ``` Key pieces: `GradleConnector` → `ProjectConnection`; `getModel(Class)` to fetch a model; `newBuild()`/`BuildLauncher` to run tasks; `BuildActionExecuter` to run a **`BuildAction`** inside Gradle that can aggregate custom models across projects. ## Models an IDE requests at sync - **`GradleProject`** — the hierarchy of projects and their tasks; the backbone of the Gradle tool window. - **`IdeaProject` / `IdeaModule`** — IntelliJ's view: modules, **source sets** (main/test), output dirs, and **dependencies** (libraries + project deps), JDK/language level. - **`EclipseProject`** — the Buildship equivalent (classpath containers, source dirs). - **`BuildEnvironment`** — Gradle version, build JVM, daemon args (so the IDE shows/validates the environment). - **Custom models** — a plugin can register a `ToolingModelBuilder`; the IDE runs a `BuildAction` that calls `controller.getModel(MyModel.class)` to pull plugin-specific data (e.g. Android/Kotlin multiplatform metadata). Producing any of these requires Gradle to run **initialization + configuration** (which is exactly why sync executes those phases and your config-time code). ## Why it matters operationally - **Daemon-managed**: the Tooling API reuses the Gradle daemon, so repeated syncs/builds are warmer. - **Cancellation**: long syncs can be cancelled via a `CancellationToken` — that's the IDE's 'stop sync' button. - **Version tolerance**: a single Tooling-API client can talk to a range of Gradle versions, which is how one IDE supports many projects. - **Events, not text**: structured progress/test/task events power the IDE's progress UI and test tree without parsing logs. ## Takeaway Sync is a Tooling-API conversation: 'give me your IdeaProject/GradleProject model', which forces Gradle through init+configuration and returns typed structure the IDE maps onto modules, source sets, dependencies, and tasks.
- How can a plugin expose its own data to the IDE during sync?Register a ToolingModelBuilder for a custom model type; the IDE runs a BuildAction that calls controller.getModel(MyModel.class) to fetch it, so plugin-specific metadata (e.g. KMP/Android) reaches the IDE.
- Why can one IDE drive many Gradle versions?The Tooling API is version-tolerant within supported ranges — the client and the build's Gradle version are decoupled, so the same client connects to projects on different Gradle versions.
saying these in an interview costs you the question
- Saying the IDE parses Gradle console output to build the model — it uses typed Tooling-API models.
- Claiming fetching a model skips configuration — building any model runs init+configuration.