DEV Community

Cover image for Koffee - Beautiful Transient Toasts for Jetpack Compose
Don Okara
Don Okara

Posted on

Koffee - Beautiful Transient Toasts for Jetpack Compose

Before discovering snackbars, I begrudgingly used Toast.makeText() for system feedback. Moving to Material 3's Snackbar was a revelation: I could finally style my toasts, add call-to-action UI, and make feedback feel intentional.  

There was one catch: SnackbarHostState is scoped to a single Scaffold. Wrapping multiple screens with the same Scaffold is messy, and trying to show a toast across screens — for example, to indicate success or failure — is unnecessarily difficult.

Koffee provides a plug-and-play toast system. You can wrap your entire navigation (or just a single screen) and trigger toasts from anywhere — as long as the screen is attached to a ToastHostState.

2. Quick Start


🛠 Installation

📦 Now available on Maven Central

Koffee is now published to Maven Central. The last JitPack release will remain available but will no longer be updated.

Maven Central (Recommended)

// settings.gradle.kts
dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral() // ✅ Primary distribution
    }
}
Enter fullscreen mode Exit fullscreen mode
// module build.gradle.kts
dependencies {  
    implementation("io.github.donald-okara:koffee:<latest version>") // Replace with the latest version
}  
Enter fullscreen mode Exit fullscreen mode

Minimal Setup

Wrap your screen content with KoffeeBar using defaults:

KoffeeBar {
    MyScreenContent()
}
Enter fullscreen mode Exit fullscreen mode

Show a simple toast anywhere within a screen attached to a ToastHostState:

Button(
    onClick = {
        // Koffee.show can be called from ViewModels, Repositories, anywhere your screen has a ToastHostState
        Koffee.show(
            title = "Success toast",
            description = "This is a green notification"
        )
    }
) {
    Text("Hello fam")
}
Enter fullscreen mode Exit fullscreen mode

✨ And that’s it. This is what you should ideally have for your toasts

Optional Advanced Toast Control

Customize layout, animation, position, duration, and other properties:

val mySimpleConfig = remember {  
    KoffeeDefaults.config.copy(  
        layout = { GlowingToast(it) },  // Pass your preferred toast composable here: @Composable (ToastData) -> Unit
        dismissible = true,  
        maxVisibleToasts = 3,  
        position = ToastPosition.BottomCenter,  
        animationStyle = ToastAnimation.SlideUp,  
        durationResolver = ::customDurationResolver,  
    )  
}

KoffeeBar(
    config = mySimpleConfig,
) {
    MyScreenContent()
}

// Optionally if you are exiting a screen and want all toasts dismissed on navigation back
DisposableEffect(Unit) {  
    onDispose {  
        Koffee.dismissAll()  
    }  
}
Enter fullscreen mode Exit fullscreen mode

Use a toast with actions:

Koffee.show(
    title = "Success toast",
    description = "With actions",
    type = ToastType.Success,
    primaryAction = ToastAction(
        label = "Share",
        onClick = { println("Viewing info details") },
        dismissAfter = true
    ),
    secondaryAction = ToastAction(
        label = "Copy",
        onClick = { println("Copied!") },
        dismissAfter = true //This manages dismissing the toast so you wouldn't have to handle it yourself
    )
)
Enter fullscreen mode Exit fullscreen mode

ToastData Overview

  • ToastType: Info, Success, Warning, Error, Neutral

  • ToastDuration: Short, Medium, Long, Indefinite

  • ToastAction: Optional primary and secondary actions with onClick and dismissAfter

Full docs and API reference are here.

3. How It Works

Below is a high-level flow of how Koffee handles toasts across your app:

  • Step 1: Configure Koffee using KoffeeDefaults.config.copy(...).

  • Step 2: Wrap your app’s root (or a specific screen) with KoffeeBar.

  • Step 3: Trigger a toast from anywhere using Koffee.show(...).

  • Step 4: ToastManager handles the queue, animations, and timing.

  • Step 5: Toasts are rendered according to your layout, position, and config.

4. Out-of-the-Box Features

Koffee ships with a set of built-in capabilities so you can drop it into your app and get productive instantly:

🎨 Light & Dark Theme Support

Adapts seamlessly to your app’s Material theme — no extra setup needed.

🎯 Flexible Positioning

Render toasts at the top, center, or bottom of the screen with one line of configuration.

⏱ Auto-Dismiss

Each toast auto-hides after a configurable duration, with sensible defaults baked in.

🎬 Smooth Animations

Enter/exit transitions are optimized for fluidity, supporting multiple animation styles out of the box.

📚 Queue & Stacking

Handle multiple toasts gracefully — queued toasts wait their turn, while stacking modes let you display several at once.

🖼 Composable Content

Toasts aren’t limited to text — plug in icons, buttons, progress bars, or any Composable for richer experiences.

5. Comparison Table

Feature Native Toast API SnackbarHost Koffee
Compose-native ❌ No ✅ Yes ✅ Yes
Fully composable ❌ No ⚠️ Partial ✅ Yes
Stacking ❌ No ⚠️ Clunky ✅ Yes
Animation ❌ No ⚠️ Limited ✅ Yes
Customizable ❌ No ⚠️ Clunky ✅ Yes
Material 3 ready ❌ No ⚠️ Partial ✅ Yes

✨ Koffee gives you modern, composable, animated toasts that the Android SDK hardly offers.

6. Call to Action

  • Check out the repo
  • 🚀 Give your Compose app the toast system it deserves — try Koffee today.

💬 Got ideas? Suggest a feature

Top comments (1)

Collapse
 
jamey_h66 profile image
Jamey H

Nice posting!
Interested in talking to you, Could you share your email address?