BowlerKitBowlerKit

Project Structure

10/11/2026

Where things live in a BowlerKit Kotlin Multiplatform project.

The CLI generates a profile-specific project. .bowlerkit/project.json records the framework, profile, and cleanup baseline. Account includes Laravel admin-panel/ and Go api-backend/; Guest runs without these services.

KMP app

mobile-app/
├── sharedLogic/   Kotlin: models, repositories, stores, Koin graph, Ktor client
├── sharedUI/      Android only: Compose pages, components, theme
├── androidApp/    Android application: manifest, config, native service wiring
├── iosApp/        SwiftUI application
├── tools/         design-token, icon, localization sources and branding assets
└── scripts/       icon, app-asset and localization scripts

The Kotlin source package stays com.soewidiputra.kmponlate, even after you rename the application.

Generated files

Update generator inputs and regenerate these outputs rather than editing them by hand:

ScriptProduces
scripts/generate-design-tokens.shCompose and SwiftUI theme tokens
scripts/generate-icons.shAndroid vector resources/Kotlin icon enum and iOS SF Symbol enum/logo assets
scripts/generate-app-assets.pyLauncher icons and splash screens (--sync, --check; needs Pillow)
scripts/generate-localizations.shLocalized strings

The theme, icon, and localization scripts currently read sources from the sibling Flutter template in the source repository. Theme export also requires the Flutter SDK. These are not standalone generation commands for a generated KMP app unless you supply those source dependencies. Branding assets come from tools/branding/; the app-asset script requires Python and Pillow.

Profile source of truth

  • sharedLogic/src/commonMain/kotlin/com/soewidiputra/kmponlate/BowlerKitProfile.kt — generated Account/Guest selection; the source template defaults to Account.
  • .bowlerkit/project.json at the project root — framework, profile, and cleanup baseline.

See Guest mode and deep cleanup before removing Account code.

Both platforms together

A screen change is made twice: the Compose page under sharedUI/ and the SwiftUI page under iosApp/iosApp/Pages/. Keep shared rules, validation, and state in sharedLogic, and verify the behavior on both platforms.