How do you set the JDK and Java language level for the generated IDEA project, and where does that configuration live?
answer
- idea.project root-only
- jdkName + languageLevel -> .ipr
- vcs = 'Git'
- default inferred from Java sourceCompatibility
- native import reads toolchain instead
basics
~10 sConfigure idea.project { jdkName = "21"; languageLevel = "21" } in the root project. These write the JDK and language level into the generated .ipr. The project block only exists on the root project.
solid answer
~40 sThe `idea.project { ... }` block configures the generated `.ipr` and is **only available on the root project** (the project that owns the `.ipr`). Key settings are `jdkName` (the named SDK IDEA should use, e.g. `"21"`), `languageLevel` (the Java language level, e.g. `"21"` / `JavaVersion.VERSION_21`), and `vcs` (e.g. `"Git"`). You can also tune `wildcards`, `ipr.withXml { ... }` for raw edits, and `vcs`. By contrast, JDK/language-level can also be expressed per-module via `idea.module`, but project-level is the usual place. When `languageLevel` isn't set explicitly, the plugin derives a default from the project's Java configuration. As with the rest of the plugin, all of this drives generated files — under native import IDEA reads the toolchain/`sourceCompatibility` instead.
code
kotlin · 13 linesidea {
project {
jdkName = "21"
languageLevel = "21"
vcs = "Git"
ipr.withXml { /* raw .ipr tweaks */ }
}
}
// modern equivalent that ALSO drives native import:
java {
toolchain { languageVersion = JavaLanguageVersion.of(21) }
}go deeper
Know idea.project { jdkName; languageLevel } sets the IDEA project JDK/level.
Know it is root-only, what each property writes, and that defaults derive from the Java config.
Contrast generated .ipr vs native import, and steer teams to the toolchain for the modern flow.
Standardize JDK/version policy via toolchains so the IDE, CLI, and CI all agree, instead of hand-maintaining .ipr values.
## The `idea.project` block `idea.project { ... }` configures the `IdeaProject` model serialized into the **`.ipr`**. Because there is exactly one `.ipr` per build, this block is **only defined on the root project** — applying it on a subproject is an error/no-op. Configure it from the root `build.gradle(.kts)` or guard with `if (project == rootProject)`. ### Key properties - **`jdkName: String`** — the name of the IDEA SDK to attach (e.g. `"21"`, `"corretto-21"`). It's a *label*; the matching SDK must exist in IDEA. - **`languageLevel`** — the Java language level for the project. Accepts a string (`"21"`), an int, or `JavaVersion`. Controls which syntax IDEA's inspector allows. - **`targetBytecodeVersion`** — the bytecode target IDEA records. - **`vcs: String`** — e.g. `"Git"`, written into the project's VCS mapping. - **`wildcards`** — resource wildcard patterns. - **`ipr`** — the merge/`withXml` hooks, mirroring `iml` on the module: `beforeMerged`, `whenMerged`, `withXml`. ### Example ```kotlin idea { project { jdkName = "21" languageLevel = "21" vcs = "Git" } } ``` ### Defaults and interaction with the Java plugin If you don't set `languageLevel`, the `idea` plugin infers a sensible default from the project's Java setup (e.g. `sourceCompatibility`/toolchain). Setting it explicitly pins what the generated `.ipr` records, which matters when developers have multiple JDKs. ### Generated vs native again These values land in the `.ipr` only. With **native Gradle import**, IDEA does not read `idea.project`; it derives the SDK and language level from your **Java toolchain** (`java { toolchain { languageVersion = JavaLanguageVersion.of(21) } }`) and `sourceCompatibility`/`targetCompatibility`. So for the modern workflow, set the toolchain — not `idea.project` — to control the IDE.
- Why can't you put `idea.project { }` in a subproject build script?There is a single `.ipr` for the whole build, owned by the root project, so the `project` block is only defined on the root. Subprojects only get the `module` block.
- If a team uses native Gradle import, how should they really control the IDE's JDK and language level?Via the Java toolchain and `sourceCompatibility`/`targetCompatibility`, since native import reads those rather than `idea.project`.
saying these in an interview costs you the question
- Putting `idea.project` in a subproject and expecting it to work.
- Believing `jdkName`/`languageLevel` affect native import — they only write the .ipr.
- Confusing `jdkName` (an IDEA SDK label) with an actual JDK installation path.