CStories is a component cataloging solution for Compose Multiplatform.
Designed for teams building and maintaining a design system, CStories lets you centralize UI demonstrations in a dedicated catalog, inspired by the workflow popularized by Storybook, while respecting the constraints specific to the Kotlin Multiplatform ecosystem.
The approach behind CStories is simple: components stay independent, and demonstrations are written in dedicated
stories. The catalog is then automatically generated from these stories and can run as a desktop app (jvm) or in the
browser (wasmJs), depending on the targets declared by the consumer module.
CStories gives Compose Multiplatform developers a simple framework to:
- build a navigable catalog of components
- isolate components in dedicated stories
- organize demonstrations by collection, group, and name
- speed up iteration on UI components
- lay a clean foundation for the visual documentation of a design system
The core principle of the solution is the following:
- design system components are never annotated directly as stories
- each story is a composable dedicated to demonstrating a component
- that story remains a plain Compose function, annotated with
@CStory
This separation keeps the design system readable, allows multiple demonstrations for the same component, and stays compatible with Kotlin/Wasm.
At this stage, CStories is published to mavenLocal() only.
From this repository, run:
./gradlew publishAllToMavenLocalThis command publishes the required artifacts as well as the Gradle plugin to your local Maven repository.
In the settings.gradle.kts of the project that will use CStories:
pluginManagement {
repositories {
mavenLocal()
gradlePluginPortal()
mavenCentral()
google()
}
}
dependencyResolutionManagement {
repositories {
mavenLocal()
mavenCentral()
google()
}
}This configuration is required both to resolve the plugin and to resolve the dependencies published by CStories.
In the module that will host the stories:
plugins {
kotlin("multiplatform") version "2.2.0"
id("org.jetbrains.compose") version "1.8.2"
id("org.jetbrains.kotlin.plugin.compose") version "2.2.0"
id("io.cstories.gradle") version "0.1.0-SNAPSHOT"
}
kotlin {
jvm()
}For a first use, the recommended path is to start with the jvm() target, in order to run the catalog as a desktop
application.
./gradlew runCStoriesDesktopIf the module also declares a wasmJs target, the catalog can also be launched in the browser:
./gradlew runCStoriesWasmA story is a composable dedicated to demonstrating a component in the catalog.
Example:
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@Composable
fun PrimaryButton(
text: String,
onClick: () -> Unit,
) {
Button(onClick = onClick) {
Text(text)
}
}Add a separate composable function, annotated with @CStory:
import androidx.compose.runtime.Composable
import io.cstories.annotations.CStory
@CStory(
collection = "DesignSystem",
group = "Buttons",
name = "Primary"
)
@Composable
fun PrimaryButtonStory() {
PrimaryButton(
text = "Hello CStories",
onClick = {},
)
}The @CStory parameters determine the navigation structure:
collection: root level of the cataloggroup: logical grouping of storiesname: story label displayed in the interface
With this example, the story will appear in a structure such as:
DesignSystem / Buttons / Primary
Launch the catalog:
./gradlew runCStoriesDesktopThe story should then appear in the navigation and let you view the component in an isolated context.
More advanced use cases are covered in the full documentation site (available in English and French): https://www.cstories.dev, notably for:
- multi-module architectures
- advanced usage of
wasmJs - component reference generation
- component-associated documentation
- catalog theme customization
- exporting the catalog for the web
