<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vivien Mahé</title>
    <description>The latest articles on DEV Community by Vivien Mahé (@vivien_mahe).</description>
    <link>https://dev.to/vivien_mahe</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3272720%2Fb63dd254-c4a6-4694-a431-820951a10a52.png</url>
      <title>DEV Community: Vivien Mahé</title>
      <link>https://dev.to/vivien_mahe</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vivien_mahe"/>
    <language>en</language>
    <item>
      <title>I just launched my first affiliate program (50% commission!) - here's why and what I learned</title>
      <dc:creator>Vivien Mahé</dc:creator>
      <pubDate>Wed, 27 Aug 2025 17:36:56 +0000</pubDate>
      <link>https://dev.to/vivien_mahe/i-just-launched-my-first-affiliate-program-50-commission-heres-why-and-what-i-learned-5a1f</link>
      <guid>https://dev.to/vivien_mahe/i-just-launched-my-first-affiliate-program-50-commission-heres-why-and-what-i-learned-5a1f</guid>
      <description>&lt;p&gt;Today I launched something I never thought I'd do as a solo developer: an affiliate program for my Kotlin Multiplatform boilerplate, KMPShip.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; After 3 months of grinding solo marketing, I realized I needed help. So I launched a 50% commission affiliate program. No idea if it'll work, but here's my thinking.&lt;/p&gt;

&lt;h2&gt;
  
  
  The reality check 📊
&lt;/h2&gt;

&lt;p&gt;Let me be transparent about where KMPShip stands:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;21 customers&lt;/strong&gt; since launch&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;€900 revenue&lt;/strong&gt; &lt;/li&gt;
&lt;li&gt;Tried &lt;strong&gt;7+ marketing channels&lt;/strong&gt;: Twitter, Reddit, LinkedIn, HackerNews, ProductHunt, Uneed, TinyLaunch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The problem? I'm burning out trying to do all the marketing myself. Building the product was the easy part - getting it in front of the right developers is exhausting.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why affiliates, why now? 🤔
&lt;/h2&gt;

&lt;p&gt;Honestly? I saw other boilerplate creators doing it and thought "maybe I should try this too." Not the most strategic reasoning, but sometimes you just need to experiment.&lt;/p&gt;

&lt;p&gt;My logic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Solo marketing is hard and time-consuming&lt;/li&gt;
&lt;li&gt;Other developers might have audiences I can't reach&lt;/li&gt;
&lt;li&gt;50% commission means they're incentivized to actually promote it&lt;/li&gt;
&lt;li&gt;If it doesn't work, I'll shut it down and try something else&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The program details 📋
&lt;/h2&gt;

&lt;p&gt;Here's what I set up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;50% commission&lt;/strong&gt; (yes, half the revenue - figured go big or go home)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;60-day cookie duration&lt;/strong&gt; (seems fair for a developer tool)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No minimum payout&lt;/strong&gt; (pay them even for one sale)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monthly payments&lt;/strong&gt; on the 10th&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Manual approval&lt;/strong&gt; (I review each application)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Using &lt;a href="https://www.refindie.com/" rel="noopener noreferrer"&gt;Refindie&lt;/a&gt; to manage it all.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I don't know (yet) 🤷‍♂️
&lt;/h2&gt;

&lt;p&gt;Being honest, I'm making educated guesses:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should I create marketing materials for affiliates?&lt;/li&gt;
&lt;li&gt;What promotion methods should I restrict?&lt;/li&gt;
&lt;li&gt;What results can I realistically expect?&lt;/li&gt;
&lt;li&gt;Is 50% too generous or not enough?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I launched it literally today, so zero affiliates and zero conversions so far.&lt;/p&gt;

&lt;h2&gt;
  
  
  My developer's hypothesis 🔬
&lt;/h2&gt;

&lt;p&gt;I'm betting that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Developers trust other developers&lt;/strong&gt; more than my solo marketing efforts&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;High commission&lt;/strong&gt; will motivate quality promotion over quantity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;People already building with KMP&lt;/strong&gt; will be natural advocates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It's better than doing nothing&lt;/strong&gt; while I figure out other growth channels&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The Kotlin Multiplatform community is pretty tight-knit, so word-of-mouth could actually work well here.&lt;/p&gt;

&lt;h2&gt;
  
  
  The technical setup 🛠️
&lt;/h2&gt;

&lt;p&gt;Since we're on DEV.to, here are the technical details:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Platform:&lt;/strong&gt; Using Refindie for affiliate management&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean dashboard for affiliates&lt;/li&gt;
&lt;li&gt;Automatic tracking and attribution&lt;/li&gt;
&lt;li&gt;Built-in payment processing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Integration:&lt;/strong&gt; Pretty straightforward setup&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Added tracking scripts to KMPShip website&lt;/li&gt;
&lt;li&gt;Created affiliate registration flow&lt;/li&gt;
&lt;li&gt;Set up automated email notifications&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Tracking:&lt;/strong&gt; 60-day cookie duration should capture the typical developer evaluation cycle (we all know how long it takes to decide on tooling!).&lt;/p&gt;

&lt;h2&gt;
  
  
  Questions for fellow developers 💭
&lt;/h2&gt;

&lt;p&gt;For those who've built dev tools and run affiliate programs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What marketing materials are essential for affiliates?&lt;/li&gt;
&lt;li&gt;How do you prevent low-quality promotional tactics?&lt;/li&gt;
&lt;li&gt;What's a realistic timeline to see results?&lt;/li&gt;
&lt;li&gt;Any red flags I should watch for?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For potential affiliates in the KMP space:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What would make you want to promote a developer tool?&lt;/li&gt;
&lt;li&gt;Is the &lt;a href="https://www.kmpship.app/affiliates" rel="noopener noreferrer"&gt;application process&lt;/a&gt; too formal?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The bigger picture 🎯
&lt;/h2&gt;

&lt;p&gt;This feels like another experiment in the long journey of building a developer tool business. Some channels work, others don't. Twitter, Reddit, and ProductHunt all brought decent traffic, but I need more consistent reach.&lt;/p&gt;

&lt;p&gt;Maybe affiliates will be the thing that unlocks growth, or maybe I'll learn something valuable trying. Either way, I'm committed to sharing the results here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Will update this post in 30 days with real numbers.&lt;/strong&gt; 📈&lt;/p&gt;

&lt;h2&gt;
  
  
  For the curious 🔍
&lt;/h2&gt;

&lt;p&gt;KMPShip is a production-ready Kotlin Multiplatform + Compose Multiplatform boilerplate that helps developers ship Android &amp;amp; iOS apps faster. It includes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Firebase Auth integration&lt;/li&gt;
&lt;li&gt;RevenueCat for in-app purchases&lt;/li&gt;
&lt;li&gt;Push notifications setup&lt;/li&gt;
&lt;li&gt;CI/CD with GitHub Actions&lt;/li&gt;
&lt;li&gt;Clean architecture foundation&lt;/li&gt;
&lt;li&gt;And a lot more boring-but-necessary setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Perfect for indie developers, freelancers, and small teams who want to focus on building features rather than configuring dependencies.&lt;/p&gt;




&lt;p&gt;What do you think? Too generous with the commission? Missing something obvious? &lt;/p&gt;

&lt;p&gt;And if you're building mobile apps with Kotlin Multiplatform, feel free to &lt;a href="https://www.kmpship.app" rel="noopener noreferrer"&gt;check out KMPShip&lt;/a&gt; 🚀&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Follow me for more updates on this experiment and other indie dev adventures!&lt;/em&gt;&lt;/p&gt;

</description>
      <category>startup</category>
      <category>entrepreneurship</category>
      <category>kotlin</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Alarmee: Local and Push Notifications in Kotlin Multiplatform (KMP)</title>
      <dc:creator>Vivien Mahé</dc:creator>
      <pubDate>Wed, 02 Jul 2025 05:21:08 +0000</pubDate>
      <link>https://dev.to/vivien_mahe/alarmee-local-and-push-notifications-in-kotlin-multiplatform-kmp-i08</link>
      <guid>https://dev.to/vivien_mahe/alarmee-local-and-push-notifications-in-kotlin-multiplatform-kmp-i08</guid>
      <description>&lt;p&gt;Handling notifications in Kotlin Multiplatform isn’t exactly fun. Android wants &lt;code&gt;AlarmManager&lt;/code&gt; or &lt;code&gt;WorkManager&lt;/code&gt;, iOS expects &lt;code&gt;UNUserNotificationCenter&lt;/code&gt;, and good luck trying to share any logic.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Alarmee&lt;/strong&gt;, a Kotlin/Compose Multiplatform library to schedule local and push notifications using a single, shared API. It works on Android and iOS, and lets you create one-off or repeating alarms, send push notifications, and even show instant alerts.&lt;/p&gt;

&lt;p&gt;Let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Features
&lt;/h2&gt;

&lt;p&gt;➡️ Schedule one-time alarms&lt;br&gt;
➡️ Set repeating alarms (hourly, daily, weekly, etc.)&lt;br&gt;
➡️ Trigger instant notifications&lt;br&gt;
➡️ Handle push notifications (FCM and APNs)&lt;br&gt;
➡️ Customize platform behaviors&lt;/p&gt;

&lt;p&gt;Alarmee works with Kotlin Multiplatform and Compose Multiplatform, so you can use it from your shared codebase.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;To get started, add the Maven Central repository in your &lt;code&gt;settings.gradle.kts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;repositories&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;mavenCentral&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're using a version catalog (&lt;code&gt;libs.versions.toml&lt;/code&gt;), declare the version and dependency like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight toml"&gt;&lt;code&gt;&lt;span class="nn"&gt;[versions]&lt;/span&gt;
&lt;span class="py"&gt;alarmee&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.0.0"&lt;/span&gt; &lt;span class="c"&gt;# Or the latest version&lt;/span&gt;

&lt;span class="nn"&gt;[libraries]&lt;/span&gt;
&lt;span class="py"&gt;alarmee&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="py"&gt;group&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"io.github.tweener"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"alarmee"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="py"&gt;version.ref&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"alarmee"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then use it in your &lt;code&gt;build.gradle.kts&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nf"&gt;dependencies&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;alarmee&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you’re not using a catalog, add the dependency directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;alarmee_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"2.0.0"&lt;/span&gt;
&lt;span class="nf"&gt;implementation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"io.github.tweener:alarmee:$alarmee_version"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuration (Android &amp;amp; iOS)
&lt;/h2&gt;

&lt;p&gt;Before using Alarmee, you’ll need to provide platform-specific configuration. Here's how to do it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Declare an expect function in shared code
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;commonMain&lt;/code&gt; sourceSet:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;expect&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;createAlarmeePlatformConfiguration&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;AlarmeePlatformConfiguration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Android implementation
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;androidMain&lt;/code&gt;, provide the actual configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;createAlarmeePlatformConfiguration&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;AlarmeePlatformConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="nc"&gt;AlarmeeAndroidPlatformConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;notificationIconResId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drawable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ic_notification&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;notificationIconColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Red&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;notificationChannels&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;listOf&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="nc"&gt;AlarmeeNotificationChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dailyNewsChannelId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Daily news notifications"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;importance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NotificationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IMPORTANCE_HIGH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;soundFilename&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"notifications_sound"&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="nc"&gt;AlarmeeNotificationChannel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;id&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"breakingNewsChannelId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"Breaking news notifications"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;importance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;NotificationManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;IMPORTANCE_LOW&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: iOS implementation
&lt;/h3&gt;

&lt;p&gt;In your &lt;code&gt;iosMain&lt;/code&gt; sourceSet, return the built-in platform config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;actual&lt;/span&gt; &lt;span class="k"&gt;fun&lt;/span&gt; &lt;span class="nf"&gt;createAlarmeePlatformConfiguration&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt; &lt;span class="nc"&gt;AlarmeePlatformConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt;
    &lt;span class="nc"&gt;AlarmeeIosPlatformConfiguration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;⚠️ Make sure to add Firebase to your Xcode project and enable Remote notifications and Push notifications in the capabilities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Initialize in your root Composable
&lt;/h3&gt;

&lt;p&gt;Then, in your &lt;code&gt;commonMain&lt;/code&gt; sourceSet, Use the rememberAlarmeeService helper in a Composable function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;alarmService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;rememberAlarmeeService&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;platformConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createAlarmeePlatformConfiguration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;First, make sure your app has notification permissions. You can use &lt;a href="https://github.com/icerockdev/moko-permissions" rel="noopener noreferrer"&gt;moko-permissions&lt;/a&gt; to help with this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access the local notification service
&lt;/h3&gt;

&lt;p&gt;To use local notifications, you need to get the &lt;code&gt;LocalNotificationService&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;localService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;alarmService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;local&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Access the push notification service (mobile only)
&lt;/h3&gt;

&lt;p&gt;To use push notifications, you need to get the &lt;code&gt;PushNotificationService&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;pushService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;alarmService&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;MobileAlarmeeService&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;push&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Push notifications are only supported on Android and iOS, so be sure to call this from one of those targets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Schedule one-off alarm
&lt;/h2&gt;

&lt;p&gt;To schedule an alarm for a specific date and time, pass an &lt;code&gt;Alarmee&lt;/code&gt; instance with &lt;code&gt;scheduledDateTime&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;localService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;schedule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alarmee&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Alarmee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"myAlarmId"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;scheduledDateTime&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LocalDateTime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2025&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;17&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;notificationTitle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"🎉 Congratulations!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;notificationBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"This will appear at the specified time."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;deepLinkUri&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"https://example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;androidNotificationConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AndroidNotificationConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AndroidNotificationPriority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;HIGH&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;channelId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"dailyNewsChannelId"&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;iosNotificationConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IosNotificationConfiguration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Schedule repeating alarm
&lt;/h2&gt;

&lt;p&gt;Alarmee supports both fixed and custom repeat intervals.&lt;/p&gt;

&lt;h3&gt;
  
  
  Daily at 9:30 AM
&lt;/h3&gt;

&lt;p&gt;Here's how to repeat an alarm every day at the same time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;repeatInterval&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RepeatInterval&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Daily&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Every 15 minutes (custom)
&lt;/h3&gt;

&lt;p&gt;If you want a custom duration (like every 15 minutes), use &lt;code&gt;RepeatInterval.Custom&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;repeatInterval&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RepeatInterval&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Custom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;duration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;minutes&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Cancel an alarm
&lt;/h2&gt;

&lt;p&gt;To stop a scheduled alarm, just cancel it by its &lt;code&gt;uuid&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;localService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cancel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"myAlarmId"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Trigger an instant notification
&lt;/h2&gt;

&lt;p&gt;You can display a notification immediately using &lt;code&gt;immediate(...)&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;localService&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;immediate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;alarmee&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Alarmee&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;uuid&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"now"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;notificationTitle&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"🚀 Instant alert!"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;notificationBody&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"This shows right away."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;androidNotificationConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AndroidNotificationConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;priority&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;AndroidNotificationPriority&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;DEFAULT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;channelId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"immediateChannelId"&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;iosNotificationConfiguration&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;IosNotificationConfiguration&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Customize notifications
&lt;/h2&gt;

&lt;p&gt;Alarmee supports custom sound files, icon colors, and badge updates on iOS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Custom sound
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Android: Place the &lt;code&gt;.ogg&lt;/code&gt; file in &lt;code&gt;res/raw&lt;/code&gt; and reference it in &lt;code&gt;soundFilename&lt;/code&gt; when defining your notification channel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;iOS: Add the file to the main bundle and pass it in &lt;code&gt;IosNotificationConfiguration&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Custom icon (Android only)
&lt;/h3&gt;

&lt;p&gt;Set a default icon in the platform config or override per alarm:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="n"&gt;notificationIconResId&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;R&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;drawable&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ic_notification&lt;/span&gt;
&lt;span class="n"&gt;notificationIconColor&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Color&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Yellow&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Badge count (iOS only)
&lt;/h3&gt;

&lt;p&gt;Use this to update or clear the app icon badge:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="nc"&gt;IosNotificationConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;badge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Set badge&lt;/span&gt;
&lt;span class="nc"&gt;IosNotificationConfiguration&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;badge&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// Clear badge&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Push Notifications
&lt;/h2&gt;

&lt;p&gt;On Android and iOS, Alarmee supports FCM and APNs through &lt;code&gt;MobileAlarmeeService.push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Right now, Alarmee will automatically display a notification when a push message with &lt;code&gt;title&lt;/code&gt; and &lt;code&gt;body&lt;/code&gt; is received. More custom handling is coming soon.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try Alarmee
&lt;/h2&gt;

&lt;p&gt;If you're building a Kotlin Multiplatform app and want to handle notifications without writing platform-specific mess, give Alarmee a shot.&lt;/p&gt;

&lt;p&gt;It already powers real apps like &lt;a href="https://www.bloomeo.app" rel="noopener noreferrer"&gt;Bloomeo&lt;/a&gt; and is included by default in &lt;a href="https://www.kmpship.app" rel="noopener noreferrer"&gt;KMPShip&lt;/a&gt;, my KMP boilerplate.&lt;/p&gt;

&lt;p&gt;📚 GitHub: &lt;a href="https://github.com/Tweener/alarmee" rel="noopener noreferrer"&gt;github.com/Tweener/alarmee&lt;/a&gt;&lt;br&gt;
🌐 Website: &lt;a href="https://www.kmpship.app" rel="noopener noreferrer"&gt;kmpship.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you find it helpful, star the repo or drop your feedback in the comments.&lt;/p&gt;

</description>
      <category>kotlin</category>
      <category>kmp</category>
      <category>notifications</category>
      <category>kotlinmultiplatform</category>
    </item>
    <item>
      <title>Build Android &amp; iOS Apps Faster with KMPShip: A Kotlin Multiplatform Boilerplate for Indie Devs</title>
      <dc:creator>Vivien Mahé</dc:creator>
      <pubDate>Wed, 18 Jun 2025 09:38:38 +0000</pubDate>
      <link>https://dev.to/vivien_mahe/build-android-ios-apps-faster-with-kmpship-a-kotlin-multiplatform-boilerplate-for-indie-devs-2ogh</link>
      <guid>https://dev.to/vivien_mahe/build-android-ios-apps-faster-with-kmpship-a-kotlin-multiplatform-boilerplate-for-indie-devs-2ogh</guid>
      <description>&lt;p&gt;Over the past few years, Kotlin Multiplatform has grown into a powerful solution for building cross-platform apps. But if you’ve ever tried starting a new KMP project, you know how much setup it takes: authentication flows, payments, CI/CD, store publishing, in-app reviews, remote config… The list goes on.&lt;/p&gt;

&lt;p&gt;After repeating the same setup across multiple projects, I finally decided to build a boilerplate that solves all of this. It’s called &lt;strong&gt;&lt;a href="https://www.kmpship.app/" rel="noopener noreferrer"&gt;KMPShip&lt;/a&gt;&lt;/strong&gt;, and it’s now available.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0p596ex9flkhjycgf6k.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0p596ex9flkhjycgf6k.png" alt="https://www.kmpship.app/" width="800" height="387"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built KMPShip
&lt;/h2&gt;

&lt;p&gt;As an indie developer, my time is limited. Every time I kicked off a new project, I found myself spending days (sometimes weeks) integrating Firebase Auth, configuring payments with RevenueCat, setting up CI/CD for App Store and Google Play, or configuring push notifications.&lt;/p&gt;

&lt;p&gt;Eventually, it hit me: “Why not create a production-ready boilerplate I can reuse, and that other devs can use too?” That’s how &lt;strong&gt;KMPShip&lt;/strong&gt; was born.&lt;/p&gt;

&lt;p&gt;I even used it to create my own app, &lt;strong&gt;&lt;a href="https://bloomeo.app/" rel="noopener noreferrer"&gt;Bloomeo&lt;/a&gt;&lt;/strong&gt;, which is live on the &lt;a href="https://apps.apple.com/us/app/bloomeo-save-retire-early/id6657986537" rel="noopener noreferrer"&gt;App Store&lt;/a&gt; and &lt;a href="https://play.google.com/store/apps/details?id=com.tweener.bloomeo" rel="noopener noreferrer"&gt;Google Play&lt;/a&gt;. Building with KMPShip allowed me to ship faster and focus on product features instead of wiring up the same integrations again.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Included in KMPShip?
&lt;/h2&gt;

&lt;p&gt;KMPShip is a &lt;strong&gt;Kotlin Multiplatform + Compose Multiplatform boilerplate&lt;/strong&gt; that helps you ship Android &amp;amp; iOS apps faster. It’s perfect for solo devs, indie makers, and startups.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ffqr8w7p9na58kq9gnu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4ffqr8w7p9na58kq9gnu.png" alt="Tech stack for KMPShip" width="800" height="723"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  🔐 Authentication
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Google, Apple, and Email/Password&lt;/li&gt;
&lt;li&gt;Built using &lt;strong&gt;&lt;a href="https://github.com/Tweener/passage/" rel="noopener noreferrer"&gt;Passage&lt;/a&gt;&lt;/strong&gt;, my KMP library for authentication via Firebase Auth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  💳 Payments
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;In-app purchases with &lt;a href="https://www.revenuecat.com/" rel="noopener noreferrer"&gt;RevenueCat&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Subscription support&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  🔔 Notifications
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Local and push notifications&lt;/li&gt;
&lt;li&gt;Powered by &lt;strong&gt;&lt;a href="https://github.com/Tweener/alarmee" rel="noopener noreferrer"&gt;Alarmee&lt;/a&gt;&lt;/strong&gt;, my KMP library for alarms and scheduling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  📝 In-App Reviews
&lt;/h3&gt;

&lt;p&gt;Trigger store-compliant reviews with a few lines of code&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Remote Config
&lt;/h3&gt;

&lt;p&gt;Firebase Remote Config support to dynamically tweak your app behavior (Feature Flags &amp;amp; App Configuration Parameters)&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 CI/CD Setup
&lt;/h3&gt;

&lt;p&gt;Preconfigured GitHub Actions to publish your app to the App Store via Fastlane and Google Play with a single release tag&lt;/p&gt;




&lt;h2&gt;
  
  
  Built on Clean Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;KMPShip&lt;/strong&gt; is designed with Clean Architecture principles in mind. The &lt;code&gt;shared&lt;/code&gt; module is organized into well-separated layers for &lt;code&gt;data&lt;/code&gt;, &lt;code&gt;domain&lt;/code&gt;, and &lt;code&gt;presentation&lt;/code&gt;, making it easier to scale and maintain your codebase over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Additional Highlights
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;KMPShip&lt;/strong&gt; also comes with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dependency injection using Koin&lt;/li&gt;
&lt;li&gt;Networking setup with Ktor&lt;/li&gt;
&lt;li&gt;Image loading with Coil&lt;/li&gt;
&lt;li&gt;A UI layer built with Compose Multiplatform and styled using &lt;strong&gt;&lt;a href="https://github.com/Tweener/czan/" rel="noopener noreferrer"&gt;Czan&lt;/a&gt;&lt;/strong&gt;, my open-source atomic design system&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Who Is KMPShip For?
&lt;/h2&gt;

&lt;p&gt;If you’re any of the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧑‍💻 A solo or indie dev tired of setting up projects from scratch&lt;/li&gt;
&lt;li&gt;🚀 A startup founder looking to launch your MVP fast&lt;/li&gt;
&lt;li&gt;🛠️ A developer wanting to explore Kotlin Multiplatform without the boilerplate pain
Then shared is made for you.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can build virtually any kind of mobile app with it: AI wrappers, personal finance tools, news apps, paid products — you name it.&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next?
&lt;/h2&gt;

&lt;p&gt;I’ve got tons of ideas in the pipeline: new features, integrations, and launchers to make development even faster. But more on that soon.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://www.kmpship.app/" rel="noopener noreferrer"&gt;Visit the website&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading, and happy shipping!&lt;/p&gt;

</description>
      <category>boilerplate</category>
      <category>mobile</category>
      <category>kotlin</category>
      <category>kotlinmultiplatform</category>
    </item>
  </channel>
</rss>
