# compose-richtext: Markdown and rich text composables for Compose Multiplatform

> compose-richtext is a Kotlin collection of Compose libraries for Markdown rendering and rich text formatting, split into a commonmark module, a markdown module and three UI layers. The README calls the whole thing experimental and the roadmap unclear, and iOS is a stated gap.

**halilozercan/compose-richtext** — A collection of Compose libraries for advanced text formatting and alternative display types.

- Repository: https://github.com/halilozercan/compose-richtext
- Website: https://halilibo.com/compose-richtext
- Stars: 992 · Forks: 129
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/halilozercan-compose-richtext

## The repository is five libraries, not one artifact

compose-richtext is a Kotlin monorepo containing a set of separate Compose libraries rather than a single published module. The top-level directory listing shows the shape clearly: richtext-commonmark, richtext-markdown, richtext-ui, richtext-ui-material and richtext-ui-material3 sit alongside buildSrc, gradle, docs, an android-sample and a desktop-sample, plus the standard build.gradle.kts, settings.gradle.kts and gradle.properties files.

That layout is the first design decision a user has to understand, because it determines which coordinate you add to your build. The base richtext-ui module is the layer the other UI modules build on, and the two Material modules exist in parallel rather than in sequence. Choosing between richtext-ui-material and richtext-ui-material3 is a choice of design system, not of version.

A collection of separate libraries is also why the artifacts are versioned independently and published to Maven Central under the com.halilibo.compose-richtext group, with the badge pointing at a per-module coordinate rather than a single project page. Anyone evaluating this needs to decide which of those modules their app actually needs, and the README does not spell out the dependency graph between them.

## The README opens with a warning, and that is the honest summary

The most informative paragraph in the README is the warning at the top. The library and all its modules are described as very experimental, with the roadmap unclear, and the README adds that a fork option is available as always.

That sentence should be the starting point for any evaluation. An alpha-stage library with an unclear roadmap is fine for an internal prototype, an open source app that can absorb a breaking change, or a team willing to maintain its own fork. It is a poor choice for a product with a release train, a support obligation and a dependency audit.

The version history supports the same reading. The most recent release is 1.0.0-alpha05 on 2026-06-08, preceded by 1.0.0-alpha03 in July 2025 and 1.0.0-alpha02 in December 2024. An alpha05 label ten months after the previous alpha is not a fast-moving dependency, and the gaps between those three dates are the kind of detail that belongs in a risk assessment rather than a feature list.

The fork mention matters in practice. If your product depends on this library, you should be deciding now whether you would maintain a fork, because the project itself is pointing you toward that option.

## RichText is a container composable, not a text style

The usage model shown in the README is a container that holds a sequence of block-level composables. RichText takes a modifier and a content lambda, and inside it you place headings, plain text, a horizontal rule, a block quote and a Markdown composable:

```kotlin
@Composable fun App() {
  RichText(Modifier.background(color = Color.LightGray)) {
    Heading(0, "Title")
    Text("Summary paragraph.")

    HorizontalRule()

    BlockQuote {
      Text("A wise person once said…")
    }
  }
}
```

The API shape is what a reader needs to understand here. This is not a modifier you attach to a Text composable. It is a scope that lays out a document, and each child composable contributes a block. That is a different mental model from the usual single-widget text APIs, and it is the model that lets a document mix a heading, a paragraph, a rule and a quote in one place.

The Heading call takes a level as its first argument, so heading depth is part of the call rather than inferred from the text style. A Markdown composable is also available for inline markdown content, which is the piece you would use for a formatted string that comes from a database or an editor rather than being written out in the layout as separate blocks.

## Commonmark and markdown are separate layers, and the README does not map them

Two of the modules are named around Markdown processing, richtext-commonmark and richtext-markdown, and the README gives no description of how they divide the work. The repository layout is the only evidence, and it is suggestive rather than conclusive: a commonmark module and a markdown module, plus a separate UI layer that renders blocks.

A reasonable reading is that parsing and rendering are separate concerns, with commonmark handling the CommonMark-style parsing side and markdown providing the Markdown-facing layer, while richtext-ui owns the block rendering model that Heading, Text, HorizontalRule and BlockQuote plug into. Treat that as a hypothesis to verify against the module documentation rather than as a documented contract, because the README does not state the dependency direction between them.

This is the largest documentation gap in the project. A user choosing between the modules needs to know which coordinate carries the parser, which carries the composables, and which one to depend on for a plain Markdown string. The documentation site at halilibo.com/compose-richtext is where the README points for that detail, and the docs directory in the repository is generated from the source via gen_dokka_docs.sh with mkdocs.yml driving the site, so the reference material does exist in the project even if it is not in the README.

## Two Material modules means a design system decision up front

The UI side of the collection is split into three modules: richtext-ui, richtext-ui-material and richtext-ui-material3. The two Material modules are the point of friction in an adoption decision, because a Compose application is built on one Material generation and a library that ships both is asking you to pick.

The difference in approach matters more than it first appears. Material 2 is the older, Android-centric design system, and Material 3 is its replacement with a different theming model. A document rendered by a Material 2 module will not inherit Material 3 color schemes and typography the way a native Material 3 component would. So picking the wrong module does not merely change a visual detail, it changes how the rendered text picks up your app theme.

The samples directory gives a hint at the intended pairing. There is an android-sample and a desktop-sample, which tells you the project is exercised on both the Android and JVM desktop targets, and that the desktop path is a first-class use case rather than an afterthought of an Android library.

## Compose Multiplatform compatibility stops short of iOS

The README states the boundary in one line: all modules are Compose Multiplatform compatible but lack iOS support. That sentence is the whole multiplatform story, and it is narrower than a team with an iOS app in the same product will want.

Compose Multiplatform lets a project share UI code across Android, desktop and other targets, and a library built for it can be consumed from a shared module. The practical reading of this project is that the same rich text composables can serve an Android app and a desktop app, which the two sample modules support, while a Kotlin Multiplatform app that also targets iOS has no equivalent path into this library.

The Kotlin Multiplatform angle is worth separating from the Compose Multiplatform one, because they are frequently conflated. The README only makes the Compose claim, and the primary language is listed as Kotlin with Android, compose, jetpack-compose and kotlin as the topic tags. Nothing in the project indicates an iOS artifact, an Xcode integration or an .ios target, so treat iOS as out of scope rather than as a gap that might be filled later.

## Apache-2.0 with a file header convention for contributors

The licence is Apache License 2.0, stated in the project metadata and reproduced in full in the README, with copyright attributed to Halil Ozercan. That grant is permissive: it allows use in commercial and closed-source products, requires that the licence and copyright notices travel with copies, and includes an express patent grant from the contributors.

For a dependency, the practical obligations are the notice retention and the absence of warranty, plus the responsibility of not using the project names or trademarks of the contributors in a way that implies endorsement. For a fork, the same terms continue to apply to the fork, and the Apache-2.0 notice has to stay in the files you keep from the original.

The project also keeps a CHANGELOG.md at the root and a conventional build setup with buildSrc and a Gradle wrapper, so an upstream change to the public API will be visible in the changelog before it reaches you as a new alpha tag. Reading that changelog is the cheapest way to judge how often a dependency like this breaks your build, and it is where the difference between 1.0.0-alpha03 and 1.0.0-alpha05 is recorded.

## Conclusion

compose-richtext fits an Android or desktop team that needs Markdown or rich text in Compose and is willing to own an experimental dependency, and it does not fit a team that needs iOS targets in the same build, since the README states the modules are Compose Multiplatform compatible but lack iOS support. Verify three things before you depend on it: that the richtext-ui-material and richtext-ui-material3 modules cover the components you actually use, that the 1.0.0-alpha05 coordinate resolves from Maven Central for your Kotlin and Compose versions, and that the fork option the README mentions is one you would genuinely take. The project is Apache-2.0 licensed, and the last push was on 2026-06-08.

## FAQ

### Which compose-richtext module should I add to my Gradle build?

The repository publishes separate modules, richtext-commonmark, richtext-markdown, richtext-ui, richtext-ui-material and richtext-ui-material3, and the README does not document the dependency graph between them. Pick the Material module that matches the design system your app already uses, since Material 2 and Material 3 are shipped in parallel rather than in sequence.

### Does compose-richtext support iOS?

No. The README states that all modules are Compose Multiplatform compatible but lack iOS support, and the repository ships an android-sample and a desktop-sample.

### How do I render a heading, a quote and a horizontal rule in compose-richtext?

You place them as child composables inside the RichText container, which takes a modifier and a content lambda. The README's example uses Heading with a level argument, Text, HorizontalRule and BlockQuote, plus a Markdown composable for inline markdown.

### Is compose-richtext stable enough to depend on in a production app?

The README warns that the library and all its modules are very experimental and that the roadmap is unclear, and the latest release is 1.0.0-alpha05. It also points out that a fork option is available.

### Where is the compose-richtext documentation?

The README points to halilibo.com/compose-richtext. The repository also contains a docs directory, an mkdocs.yml file and gen_dokka_docs.sh, which indicates the site is generated from the source with Dokka.

## Sources

- [halilozercan/compose-richtext on GitHub](https://github.com/halilozercan/compose-richtext)
- [License: Apache-2.0](https://github.com/halilozercan/compose-richtext/blob/main/LICENSE)
- [Project website](https://halilibo.com/compose-richtext)
- [README](https://github.com/halilozercan/compose-richtext/blob/main/README.md)
- [Releases](https://github.com/halilozercan/compose-richtext/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/halilozercan-compose-richtext
