Aplicativos desktop com Kotlin: como criar?

Sim, e possível criar aplicativos desktop completos e profissionais usando Kotlin. A principal opção em 2026 é 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 opções também. Vamos explorar tudo em detalhes.

Compose for Desktop: a principal opção

Compose for Desktop é 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 você já 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 começar com Compose for Desktop

Configuração do projeto:

A forma mais fácil de começar 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 avançadas 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 opções 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 opção válida para projetos que precisam de compatibilidade com sistemas mais antigos, embora a API seja imperative e menos moderna.

Kotlin/Native

Para aplicações desktop que precisam de performance maxima e acesso direto ao sistema operacional, Kotlin/Native compila para binarios nativos sem dependência da JVM.

Comparação de opções desktop

CaracteristicaCompose DesktopTornadoFXSwingKotlin/Native
ParadigmaDeclarativoMistoImperativoNativo
ModernidadeMuito modernoModernoDatadoModerno
Curva aprendizadoModeradaModeradaBaixaAlta
PerformanceMuito boaBoaBoaExcelente
ComunidadeCrescentePequenaGrandePequena
FuturoPromissorEstagnadomanutençãoEm evolução

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 única linguagem para mobile e desktop
  • Distribuição multiplataforma (Windows, macOS, Linux)
  • IntelliJ IDEA e o próprio 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 memória que apps nativos puros
  • O ecossistema de componentes prontos e menor que em web
  • Distribuição de apps JVM requer empacotamento do runtime (JPackage ou similar)
  • Menos vagas de emprego específicas 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

Distribuição de apps desktop

Para distribuir seu app Kotlin desktop, você 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 já 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 prático: conversor de arquivos

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

  • Interface com Compose Desktop
  • manipulação 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 próprio 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 também precisam de versões mobile. A convergencia entre desktop e mobile através do Compose Multiplatform e um dos desenvolvimentos mais empolgantes no ecossistema Kotlin.

Perguntas relacionadas