Skip to main content

Installation

On the Hello Doodle page, you got a look at why Doodle might be worth your time. Now let's make it real: this page gets a project on your machine set up and building — no app code yet, just a clean foundation for Applications to build on next.

Before you start​

  • JDK 11 or newer. Both Gradle and Doodle's Desktop target need it.
  • An IDE with Kotlin support. IntelliJ IDEA is the natural choice, but any editor works.

Don't worry if Gradle isn't your comfort zone — everything you need is right here to copy in.

Two ways to get started​

  • Fastest: borrow a working example. Doodle Tutorials has several real, runnable apps waiting for you — a calculator, a contacts app, a photo stream, and more — each with its own tested build.gradle.kts ready to copy wholesale.
  • From scratch: build your own. That's the road the rest of this page takes, and it's exactly where Applications picks up.

Choosing your target​

If you want to build for...Use
Just the WebSingle-platform: Web (JavaScript) or Web (WebAssembly)
Just DesktopSingle-platform: Desktop (JVM)
BothMultiplatform

Still deciding? Go with a single platform for now. Doodle's core APIs — Application, Display, View, layout, rendering — are identical everywhere, so nothing you build here is wasted if you branch out to another target down the line.

Single-platform setup​

You can set up an app that runs in the Browser using JavaScript with the following build script.

build.gradle.kts

plugins { id ("org.jetbrains.kotlin.multiplatform") version "2.1.10" } version = "1.0.0" group = "com.my.cool.app" repositories { mavenCentral() } kotlin { js { browser { binaries.executable() } } val doodleVersion = "0.11.5" // <--- Latest Doodle version dependencies { implementation ("io.nacular.doodle:browser:$doodleVersion") // Optional // implementation ("io.nacular.doodle:controls:$doodleVersion" ) // implementation ("io.nacular.doodle:animation:$doodleVersion") // implementation ("io.nacular.doodle:themes:$doodleVersion" ) } }
tip

Learn more about Kotlin for Javascript.

Multiplatform setup​

Doodle's own libraries are Kotlin Multiplatform, so there's no reason yours can't be too. Write everything except main() in shared (commonMain) code, and watch it run unchanged on both Web and Desktop.

import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl import org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11 plugins { id ("org.jetbrains.kotlin.multiplatform") version "2.4.21" application } version = "1.0.0" group = "com.my.cool.app" repositories { mavenCentral() maven { url = uri("https://maven.pkg.jetbrains.space/public/p/compose/dev") } } // could be moved to buildSrc, but kept here for clarity fun osTarget(): String { val osName = System.getProperty("os.name") val targetOs = when { osName == "Mac OS X" -> "macos" osName.startsWith("Win" ) -> "windows" osName.startsWith("Linux") -> "linux" else -> error("Unsupported OS: $osName") } val targetArch = when (val osArch = System.getProperty("os.arch")) { "x86_64", "amd64" -> "x64" "aarch64" -> "arm64" else -> error("Unsupported arch: $osArch") } return "${targetOs}-${targetArch}" } kotlin { js { browser { binaries.executable() } } @OptIn(ExperimentalWasmDsl::class) wasmJs { browser { binaries.executable() } } jvm { compilerOptions { jvmTarget.set(JVM_11) // JVM 11 is needed for Desktop } } val doodleVersion = "0.11.0" // <--- Latest Doodle version sourceSets { commonMain.dependencies { // Optional // implementation ("io.nacular.doodle:controls:$doodleVersion" ) // implementation ("io.nacular.doodle:animation:$doodleVersion") // implementation ("io.nacular.doodle:themes:$doodleVersion" ) } jsMain.dependencies { implementation ("io.nacular.doodle:browser:$doodleVersion") } jvmMain.dependencies { // helper to derive OS/architecture pair when (osTarget()) { "macos-x64" -> implementation("io.nacular.doodle:desktop-jvm-macos-x64:$doodleVersion" ) "macos-arm64" -> implementation("io.nacular.doodle:desktop-jvm-macos-arm64:$doodleVersion" ) "linux-x64" -> implementation("io.nacular.doodle:desktop-jvm-linux-x64:$doodleVersion" ) "linux-arm64" -> implementation("io.nacular.doodle:desktop-jvm-linux-arm64:$doodleVersion" ) "windows-x64" -> implementation("io.nacular.doodle:desktop-jvm-windows-x64:$doodleVersion" ) "windows-arm64" -> implementation("io.nacular.doodle:desktop-jvm-windows-arm64:$doodleVersion") } } } } application { mainClass.set("YOUR_CLASS") }
tip

App launch code is the only part that needs to live in a platform-specific source set (jsMain, wasmJsMain, jvmMain) — everything else can go in commonMain.

Check your setup​

There's no app code yet — that's what Applications is for — so there's nothing to actually run just yet. What we can confirm right now is that the project builds cleanly, with every dependency resolved:

./gradlew build

A clean finish means your setup is correct — well done. Once you've built your first Application on the next page, come back to these commands to actually watch it appear on screen:

TargetRun with
Web (JavaScript)./gradlew jsBrowserDevelopmentRun
Web (WebAssembly)./gradlew wasmJsBrowserDevelopmentRun
Desktop (JVM)./gradlew run (single-platform) or ./gradlew jvmRun (multiplatform)

Recap​

  • Pick single-platform if you only need Web or only need Desktop; pick multiplatform if you need both.
  • Doodle's dependency (browser for Web, a desktop-jvm-* artifact for Desktop) goes in the source set for that platform — commonMain only ever holds platform-agnostic code.
  • ./gradlew build confirms your setup before you've written any app code; the per-platform run commands come into play once you have.

Next: head to Applications to write your first Application class and give these commands something to actually run.