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?