Aplicativos desktop com Kotlin: como criar?

Sim, e possivel criar aplicativos desktop completos e profissionais usando Kotlin. A principal opcao em 2026 e o Compose for Desktop, parte do projeto Compose Multiplatform da JetBrains, que permite usar a mesma API declarativa do Jetpack Compose para construir interfaces desktop nativas. Mas existem outras opcoes tambem. Vamos explorar tudo em detalhes.

Compose for Desktop: a principal opcao

Compose for Desktop e a forma mais moderna e recomendada de criar aplicativos desktop com Kotlin. Ele usa a mesma API declarativa que o Jetpack Compose para Android, o que significa que se voce ja conhece Compose, a transicao e praticamente instantanea.

import androidx.compose.desktop.ui.tooling.preview.Preview
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Window
import androidx.compose.ui.window.application

fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        title = "Gerenciador de Tarefas"
    ) {
        MaterialTheme {
            AppPrincipal()
        }
    }
}

@Composable
fun AppPrincipal() {
    var tarefas by remember { mutableStateOf(listOf<String>()) }
    var novaTarefa by remember { mutableStateOf("") }

    Column(
        modifier = Modifier
            .fillMaxSize()
            .padding(24.dp)
    ) {
        Text(
            text = "Minhas Tarefas",
            style = MaterialTheme.typography.headlineMedium
        )

        Spacer(modifier = Modifier.height(16.dp))

        Row(
            modifier = Modifier.fillMaxWidth(),
            verticalAlignment = Alignment.CenterVertically
        ) {
            OutlinedTextField(
                value = novaTarefa,
                onValueChange = { novaTarefa = it },
                label = { Text("Nova tarefa") },
                modifier = Modifier.weight(1f)
            )
            Spacer(modifier = Modifier.width(8.dp))
            Button(
                onClick = {
                    if (novaTarefa.isNotBlank()) {
                        tarefas = tarefas + novaTarefa
                        novaTarefa = ""
                    }
                }
            ) {
                Text("Adicionar")
            }
        }

        Spacer(modifier = Modifier.height(16.dp))

        tarefas.forEachIndexed { indice, tarefa ->
            Card(
                modifier = Modifier
                    .fillMaxWidth()
                    .padding(vertical = 4.dp)
            ) {
                Row(
                    modifier = Modifier
                        .fillMaxWidth()
                        .padding(16.dp),
                    horizontalArrangement = Arrangement.SpaceBetween,
                    verticalAlignment = Alignment.CenterVertically
                ) {
                    Text(text = tarefa)
                    IconButton(onClick = {
                        tarefas = tarefas.filterIndexed { i, _ -> i != indice }
                    }) {
                        Text("X")
                    }
                }
            }
        }

        if (tarefas.isEmpty()) {
            Box(
                modifier = Modifier.fillMaxWidth().padding(32.dp),
                contentAlignment = Alignment.Center
            ) {
                Text(
                    text = "Nenhuma tarefa cadastrada",
                    color = MaterialTheme.colorScheme.outline
                )
            }
        }
    }
}

Como comecar com Compose for Desktop

Configuracao do projeto:

A forma mais facil de comecar e usando o assistente do IntelliJ IDEA ou o Kotlin Multiplatform Wizard.

O arquivo build.gradle.kts tipico para um projeto Compose Desktop:

plugins {
    kotlin("jvm")
    id("org.jetbrains.compose")
}

dependencies {
    implementation(compose.desktop.currentOs)
    implementation(compose.material3)
}

compose.desktop {
    application {
        mainClass = "MainKt"
    }
}

Funcionalidades avancadas do Compose Desktop

Menus e barras de ferramentas:

import androidx.compose.ui.window.*

fun main() = application {
    Window(
        onCloseRequest = ::exitApplication,
        title = "Editor de Texto",
        state = rememberWindowState(width = 800.dp, height = 600.dp)
    ) {
        MenuBar {
            Menu("Arquivo") {
                Item("Novo", onClick = { /* novo arquivo */ })
                Item("Abrir", onClick = { /* abrir arquivo */ })
                Item("Salvar", onClick = { /* salvar arquivo */ })
                Separator()
                Item("Sair", onClick = ::exitApplication)
            }
            Menu("Editar") {
                Item("Copiar", onClick = { /* copiar */ })
                Item("Colar", onClick = { /* colar */ })
            }
            Menu("Ajuda") {
                Item("Sobre", onClick = { /* mostrar sobre */ })
            }
        }

        MaterialTheme {
            EditorConteudo()
        }
    }
}

System Tray (icone na bandeja do sistema):

fun main() = application {
    Tray(
        icon = painterResource("icone.png"),
        menu = {
            Item("Abrir", onClick = { /* abrir janela */ })
            Item("Sair", onClick = ::exitApplication)
        }
    )

    Window(onCloseRequest = ::exitApplication, title = "Meu App") {
        MaterialTheme {
            Text("Aplicativo com System Tray")
        }
    }
}

Acesso ao sistema de arquivos:

import java.io.File
import javax.swing.JFileChooser

@Composable
fun SeletorDeArquivos(aoSelecionarArquivo: (File) -> Unit) {
    Button(onClick = {
        val seletor = JFileChooser()
        val resultado = seletor.showOpenDialog(null)
        if (resultado == JFileChooser.APPROVE_OPTION) {
            aoSelecionarArquivo(seletor.selectedFile)
        }
    }) {
        Text("Selecionar arquivo")
    }
}

Outras opcoes para desktop com Kotlin

TornadoFX (baseado em JavaFX)

TornadoFX e um framework Kotlin construido sobre JavaFX. Embora seja mais antigo que Compose Desktop, ainda e usado em projetos existentes.

Swing com Kotlin

Java Swing funciona perfeitamente com Kotlin. E uma opcao valida para projetos que precisam de compatibilidade com sistemas mais antigos, embora a API seja imperative e menos moderna.

Kotlin/Native

Para aplicacoes desktop que precisam de performance maxima e acesso direto ao sistema operacional, Kotlin/Native compila para binarios nativos sem dependencia da JVM.

Comparacao de opcoes desktop

CaracteristicaCompose DesktopTornadoFXSwingKotlin/Native
ParadigmaDeclarativoMistoImperativoNativo
ModernidadeMuito modernoModernoDatadoModerno
Curva aprendizadoModeradaModeradaBaixaAlta
PerformanceMuito boaBoaBoaExcelente
ComunidadeCrescentePequenaGrandePequena
FuturoPromissorEstagnadoManutencaoEm evolucao

Pros e contras de apps desktop com Kotlin

Vantagens:

  • Compose Desktop permite compartilhar UI entre desktop, Android e iOS
  • Acesso a todo ecossistema de bibliotecas JVM
  • Kotlin idiomatico: null safety, coroutines, extensoes
  • Uma unica linguagem para mobile e desktop
  • Distribuicao multiplataforma (Windows, macOS, Linux)
  • IntelliJ IDEA e o proprio melhor exemplo de app desktop em Kotlin/JVM

Desvantagens:

  • Compose Desktop ainda e menos maduro que frameworks nativos de cada sistema
  • Apps JVM consomem mais memoria que apps nativos puros
  • O ecossistema de componentes prontos e menor que em web
  • Distribuicao de apps JVM requer empacotamento do runtime (JPackage ou similar)
  • Menos vagas de emprego especificas para desktop comparado com web e mobile

Tipos de aplicativos desktop ideais para Kotlin

Kotlin e especialmente adequado para:

  • Ferramentas de produtividade e utilitarios
  • Aplicativos empresariais internos
  • Editores e IDEs (a JetBrains comprova isso)
  • Dashboards e aplicativos de monitoramento
  • Aplicativos que precisam funcionar offline
  • Extensoes de ferramentas de desenvolvimento

Distribuicao de apps desktop

Para distribuir seu app Kotlin desktop, voce pode usar:

JPackage: ferramenta oficial do JDK que cria instaladores nativos (.msi para Windows, .dmg para macOS, .deb/.rpm para Linux).

Compose Gradle Plugin: o plugin do Compose ja inclui tarefas de empacotamento que geram executaveis nativos para cada plataforma.

// No build.gradle.kts
compose.desktop {
    application {
        mainClass = "MainKt"

        nativeDistributions {
            targetFormats(
                TargetFormat.Dmg,    // macOS
                TargetFormat.Msi,    // Windows
                TargetFormat.Deb     // Linux
            )
            packageName = "MeuApp"
            packageVersion = "1.0.0"
        }
    }
}

Projeto pratico: conversor de arquivos

Para quem quer comecar, um projeto excelente e criar um conversor de arquivos com interface grafica. Ele envolve:

  • Interface com Compose Desktop
  • Manipulacao de arquivos do sistema
  • Processamento em background com coroutines
  • Barra de progresso e feedback visual

O futuro do Kotlin Desktop

O Compose Multiplatform continua evoluindo rapidamente. A JetBrains investe pesado nessa tecnologia porque e a base do seu proprio ecossistema de IDEs futuro. Isso garante que Compose Desktop tera suporte e melhorias por muito tempo.

A tendencia e que cada vez mais aplicativos desktop sejam construidos com Kotlin, especialmente aqueles que tambem precisam de versoes mobile. A convergencia entre desktop e mobile atraves do Compose Multiplatform e um dos desenvolvimentos mais empolgantes no ecossistema Kotlin.

Perguntas relacionadas