This template provides a starting point for building desktop applications using Compose for Desktop. It includes:
-
Navigation system with route configuration
-
Theming support with light and dark modes
-
Custom UI components and extensions
-
DSL-like syntax for building UIs
| Library | Version | Purpose |
|---|---|---|
Compose for Desktop |
1.8.0-rc01 |
UI toolkit for building desktop applications with Kotlin |
Kotlin JVM |
2.1.20 |
Kotlin programming language for JVM |
| Library | Version | Purpose |
|---|---|---|
PreCompose |
1.6.2 |
Navigation library for Compose applications |
Malefic Nav |
1.3.3 |
Custom navigation components and utilities |
| Library | Version | Purpose |
|---|---|---|
Malefic Components |
1.1.0 |
Custom UI components for Compose |
Malefic Theming |
1.1.2 |
Theming support with JSON configuration |
Malefic Engine |
1.3.0 |
UI building engine with DSL-like syntax |
| Library | Version | Purpose |
|---|---|---|
Malefic Extensions Core |
1.4.2 |
Core utility extensions for Kotlin |
Malefic Extensions Compose |
1.4.2 |
Compose-specific utility extensions |
The template includes a navigation system that allows you to:
-
Define routes in a configuration file (
routes.mcf) -
Navigate between screens with parameters
-
Use a sidebar for navigation
Example route configuration:
routes:
home* -> Home
app1 -> App1? [id, name?]
hidden -> Text? [text?]The template supports both light and dark themes:
-
Theme files are defined in JSON format
-
System theme detection is supported
-
Material Design color system is used
The template provides a DSL-like syntax for building UIs:
-
Factory classes for common UI elements (Row, Column, Button, Text)
-
Custom operators for applying modifiers and styles
-
Utility functions for common tasks
Example:
ColumnFactory {
ButtonFactory { TextFactory(text)() } / {
onClick = { text = text.either("Hello, World!", "Hello, Desktop!") }
} *= {
space(16.dp)
}
}-
Clone the repository
-
Open the project in your IDE (IntelliJ IDEA recommended)
-
Run
./gradlew desktop
To build a distributable package locally:
./gradlew packageDistributionForCurrentOSThis will create a platform-specific package (DMG for macOS, MSI for Windows, DEB for Linux).
The project includes a GitHub Actions workflow that automatically builds and packages the application:
-
Builds are triggered on pushes to the main branch and pull requests
-
Pre-releases are automatically created for every push to the main branch
-
Full releases can be created manually with version incrementing
-
Packages are built for all platforms (Windows, macOS, Linux)
-
All packages use the standard (non-release) distribution for better compatibility
Every push to the main branch automatically creates a pre-release with:
-
A "dev-X" tag (where X is the build number)
-
Packages for all platforms
-
Detailed information about the build
-
Pre-release flag to indicate it’s not a stable release
To create a full release with version incrementing:
-
Go to the "Actions" tab in the GitHub repository
-
Select the "Package Compose Desktop Application" workflow
-
Click "Run workflow"
-
Choose the release type:
-
patch- Increases the third number (e.g., 1.0.0 → 1.0.1) -
minor- Increases the second number and resets the third (e.g., 1.0.0 → 1.1.0) -
major- Increases the first number and resets the others (e.g., 1.0.0 → 2.0.0)
-
-
Click "Run workflow"
The workflow will:
-
Increment the version in build.gradle.kts
-
Commit and push the changes
-
Create a new tag with the version number
-
Build packages for all platforms
-
Create a GitHub release with the packages attached
ComposeDesktopTemplate/
├── .github/
│ └── workflows/
│ └── package.yml # GitHub Actions workflow for packaging
├── build.gradle.kts # Gradle build configuration
├── gradle/
│ └── libs.versions.toml # Library versions and bundles
├── src/
│ └── main/
│ ├── kotlin/
│ │ └── xyz/malefic/compose/
│ │ ├── Main.kt # Application entry point
│ │ └── screens/ # Screen composables
│ └── resources/
│ ├── routes.mcf # Route configuration
│ └── theme/ # Theme JSON files
└── README.adoc # This fileRoutes are configured in the routes.mcf file:
-
*indicates the default route -
?after a parameter name indicates it’s optional -
?after a route name indicates it is not shown in the sidebar, though this only matters when the RoutedSidebar is used (not recommended)
This project is licensed under the MIT License. See the LICENSE file for more details.
