Library / SDK
hi-manshu/charty avatar
hi-manshu/charty

Charty draws 35 chart types on Compose, from Android to WebAssembly

Weave data into enchanting Jetpack Compose graphs—no potions required! 📜🔮

1,290 stars59 forksKotlinLicense varies

At a glance

What is it?
Charty is a Kotlin charting library for Jetpack Compose that extends to Kotlin Multiplatform, so one codebase renders on Android, iOS, desktop, JavaScript and WebAssembly. Its differentiator is not the chart catalogue but the interaction layer, a draggable crosshair that can sync across charts, and its opt-in 3D artifact where every declaration is experimental.
Who is it for?
Charty fits a Kotlin team that wants one charting implementation for Android and, if needed, the other Compose Multiplatform targets, and that cares about interaction quality such as a synced crosshair and brush selection rather than just static plots.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 53 days ago.
What is it written in?
Mainly Kotlin, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 21, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One Compose API, five rendering targets

The headline claim is in the blockquote at the top of the README. Charty is a sleek, lightweight charting library for Jetpack Compose, and, uniquely, for Kotlin Multiplatform, with one codebase rendering charts on Android, iOS, Desktop and the Web. The feature list makes that concrete: five targets from one API, covering Android with minSdk 24, iOS, JVM desktop, JavaScript and WebAssembly.

The installation reflects that structure, because the dependency goes into a common source set rather than an Android one.

kotlin
commonMain.dependencies {
    implementation("com.himanshoe:charty:3.0.0")
}

The artifact is on Maven Central under the group com.himanshoe, and the version there, 3.0.0, is older than the 3.2.0 release listed in the repository's release history. That is the usual gap between what the README shows and what the latest tag contains, and it is worth checking which version you actually want, because the project ships quickly enough that the two are not in step.

The value of the multiplatform claim depends on what you are comparing it against. The alternative is a charting library per platform, with an Android one, a Swift one and a JavaScript one, each with its own API and its own bugs. The other alternative is drawing the charts yourself with Compose primitives, which means owning axes, ticks, labels, gestures and accessibility for every chart type. Charty sits between those two, and its users are teams with a Compose codebase that has to ship on more than one target, or a team that wants charts on a platform the Compose ecosystem has not reached yet.

The library is on Maven Central with a version badge, and the project has been featured in AndroidWeekly, which is a reasonable signal that it is used by people outside its author's own apps.

The playground runs all 35 charts with every option exposed

The best way to evaluate a charting library is to look at the output and the knobs, and the project has made both easy to reach. Every chart has a page with a picture, the code that produced it, and its full configuration. The playground runs all 35 of them in your browser, with every option exposed as a control you can turn.

The chart catalogue is broad. The README lists 35 chart types, and it names them: bar and its dozen variants, line, area, scatter, bubble, combo, pie, radar, gauges, candlestick, calendar and matrix heatmaps, Gantt, funnel, and projected 3D. A calendar heatmap and a Gantt chart are not trivial to build, and their presence is what separates a general-purpose library from a line chart with a few options.

The usage model is declarative Compose. A chart is a composable call with a data lambda, a colour, and a configuration object.

kotlin
LineChart(
    data = { listOf(LineData("Mon", 20f), LineData("Tue", 45f), LineData("Wed", 30f)) },
    color = ChartyColor.Solid(ChartyColors.Blue),
)

Note that the data is a lambda rather than a value. That is the detail that matters for the live data feature, where a rolling window slides as points arrive: the chart re-reads the data source when it recomposes, so a chart bound to a flow of updates does not need to be rebuilt from scratch.

The configuration object carries the same kind of detail, and the comment in the README example about the downsample threshold is a good one. The threshold of 800 is described as staying smooth over huge series, which tells you the library is prepared for series larger than a chart can show, and the interpolation mode is a first-class choice rather than something you patch in.

The 3D artifact is separate, experimental, and honest about the cost

Projected 3D charts are a separate artifact on its own version, and every declaration in it is marked @ChartyExperimental. The README points to the charty-3d documentation for the opt-in and, notably, for an honest account of what tilting a chart costs you.

kotlin
implementation("com.himanshoe:charty-3d:1.0.0")

The separate versioning is the important structural decision. The 3D code can move fast without forcing a major release of the main library, and the annotation means the compiler tells you at every call site that you are depending on something whose shape may change. That is a much better arrangement than a 3D preview buried in the main artifact, where every consumer inherits the churn.

The wording of the README is worth quoting in substance, because it is unusual. The documentation offers not just the opt-in instructions but an honest account of what tilting a chart costs you. For a 3D chart, the costs are predictable: a perspective projection has to be computed per frame, the interaction model stops being a simple drag on a plane, and the result still has to be drawn into a 2D surface. A library that documents that trade-off is one that has tried it.

For an adopter, the practical reading is that 3D belongs in the same category as any experimental API. If your use case needs it, budget for the annotation warnings and for the possibility that the API moves. If it does not, the 2D catalogue is the product, and it is a substantial one.

The crosshair is the feature that justifies the library

Most of what a charting library does, you can get from a plot. What is hard to build, and what Charty actually offers, is the interaction layer, and the README is specific about it.

There is a draggable crosshair, and it can sync across charts, which is the capability that turns a set of separate plots into a coordinated view where the same point on the time axis is highlighted everywhere. There are tooltips drawn as your own Composable, which means the tooltip is your code and can be styled and laid out however you want rather than being whatever the library draws. There are persistent markers, so a user can pin a point, zoom, pan, and brush selection for range queries.

kotlin
LineChart(
    data = { priceData },
    color = ChartyColor.Solid(ChartyColors.Blue),
    lineConfig = LineChartConfig(
        interpolation = LineInterpolation.SMOOTH,
        downsampleThreshold = 800,          // stays smooth over huge series
    ),
    crosshair = ChartCrosshair(),            // draggable guide line and label
)

The live data feature is the other half. It is described as a rolling window that slides as points arrive, with scrollback through history and a jump-to-latest pill, which is the standard vocabulary of a real-time monitoring chart rather than a static plot. Together, the crosshair and the live window describe a library aimed at dashboards and monitoring screens, and at trading-style interfaces where a chart is a control surface rather than an illustration.

This is also where the alternative bites. If you draw your chart with Compose's Canvas primitives, you own all of it, including the hard parts, and the cost is weeks of gesture and layout work per chart type. If you use a different library, you may get none of the cross-chart synchronisation, because the sync is usually the first thing left out when a library is built chart by chart.

One ChartyTheme resolves every chart's configuration

The theming story is a single object. There is one ChartyTheme carrying typography, colours, shapes and dimensions that every chart resolves its config against.

That sentence is the whole design, and it is a meaningful one. In a library where each chart type has its own colour constants and its own default padding, a theme is a convention, and the second screen you build will drift from the first. Here the theme is the source of the values, so a chart resolves its configuration against it rather than against its own defaults, which means a design change is one edit.

The colour API is worth a look because it shows how the theme is applied. A chart takes a color parameter, and the value used in the example is ChartyColor.Solid(ChartyColors.Blue). The type name, Solid, implies there are other strategies, which is the usual way to express a colour that varies per data point, per series or by some function of the value, rather than one flat colour for the whole chart.

Accessibility is handled at the level of the data rather than the pixels, which is the right level. The README lists per-point screen-reader traversal, so a screen reader can walk the individual points of a series rather than the chart being announced as a single image. That is a materially different thing from a chart with a content description, and it is the sort of detail that only gets built when the library is used by people who need it.

The documentation site carries a theming page under customization, and a per-chart configuration page for each of the 35 charts, so the configuration surface is documented rather than discovered.

Performance work is in the library, not in your app

Three items on the feature list are about not making the user wait, and they are the ones a charting library either has or does not.

LTTB downsampling for large series is first. The downsampling threshold of 800 in the configuration example is the knob, and the effect is that a chart with thousands of points renders the points that matter rather than every point in the series. Without that, a live chart updating every second with a long history will get slower as the window grows, and the chart is usually the thing that makes an app feel sluggish.

PNG export is second, and it is a common request that usually ends up with a team writing their own rendering path. Having it in the library means the exported image uses the same configuration as the on-screen chart.

An Android baseline profile shipped in the AAR is third, and it is the most Android-specific of the three. The repository has a baselineprofile/ directory, and the profile is a set of hints for the ART compiler about which code paths to compile ahead of time, which reduces the first-run cost of the code paths the app actually uses. Shipping it inside the AAR means the consuming app gets it without doing anything.

The remaining engineering scaffolding in the repository is what you would expect from a library that takes itself seriously. There is a benchmark/ directory, a release-verification/ directory, a composeApp/ and an iosApp/ for the sample applications, a docsite/ module, a scripts/ directory, and a build.gradle.kts with settings.gradle.kts and gradle.properties for the Gradle build. The release cadence supports the same picture, with v3.1.0 on 2026-08-14, v3.1.1 on 2026-08-28 and v3.2.0 on 2026-08-31.

Apache-2.0 in the README, undocumented in the repository metadata

There is a licensing wrinkle worth flagging. The repository metadata reports the licence as unknown, a custom licence that GitHub cannot classify, and there is no LICENSE file among the top-level entries. The README, on the other hand, prints the full Apache License, Version 2.0 text in a code block, with the copyright line reading Copyright 2025 The Charty Authors.

The README text is the actual grant, and it is the permissive one, so a reader who follows the README will be fine. But the metadata is what package scanners, license checkers and corporate policy tooling read, and a project that shows as unlicensed there will be flagged. That is a small amount of housekeeping for the maintainer to fix, and it is a concrete thing to raise rather than a reason to avoid the library.

This is a licensing fact rather than legal advice. Under the terms printed in the README, you may use, modify and redistribute the library, including in commercial applications, provided the licence and notice conditions are met.

The project is otherwise well run for a single-author library. The repository is not archived, the default branch is main, and the last push was on 2026-08-31, the same day as the v3.2.0 release. There is a CODE_OF_CONDUCT.md, a CONTRIBUTING.md, a DEVELOPER_README.md and a CHANGELOG.md, and the project accepts sponsorship through GitHub Sponsors and Buy Me a Coffee.

The documentation process is the part a contributor should know. The documentation site is generated from the markdown in docs/charty, so you edit the page rather than the HTML, and the whole site builds locally with a single Gradle command that fails on a dead link.

bash
./gradlew :docsite:assembleSite

A documentation build that fails on a broken link is a small thing that says a lot about how the project is maintained, and it means the 35 chart pages cannot silently drift out of sync with the code they describe.

Editorial conclusion

Charty fits a Kotlin team that wants one charting implementation for Android and, if needed, the other Compose Multiplatform targets, and that cares about interaction quality such as a synced crosshair and brush selection rather than just static plots. It does not fit a project that needs production-ready 3D charts, since that is a separate artifact where every declaration is marked experimental, and it does not fit a team unwilling to depend on a library that publishes its own API. Before adopting it, open the browser playground, check that the chart types you need carry the configuration you expect, and treat the 3D module as a prototype.

Frequently asked questions

How do I add Charty to a Kotlin Multiplatform project?

Add the dependency to the common source set with implementation("com.himanshoe:charty:3.0.0") inside commonMain.dependencies. The library targets Android with minSdk 24, iOS, JVM desktop, JavaScript and WebAssembly from that single API.

How many chart types does Charty provide and how can I try them?

The README lists 35 chart types, from bar and its dozen variants through line, area, scatter, bubble, combo, pie, radar, gauges, candlestick, calendar and matrix heatmaps, Gantt, funnel and projected 3D. The browser playground runs all 35 with every option exposed as a control.

Is the 3D chart support in Charty stable?

No. Projected 3D charts are a separate artifact, com.himanshoe:charty-3d:1.0.0, and every declaration in it is marked @ChartyExperimental. The documentation offers the opt-in along with an account of what tilting a chart costs you.

What interactions does Charty support?

A draggable crosshair that can sync across charts, tooltips drawn as your own Composable, persistent markers, zoom, pan and brush selection, plus a live data mode with a rolling window that slides as points arrive, scrollback through history and a jump-to-latest pill.

How is Charty licensed?

The README prints the Apache License, Version 2.0 in full, with the copyright line Copyright 2025 The Charty Authors, although the repository metadata reports the licence as unknown and there is no LICENSE file at the root.

Official sources

  1. hi-manshu/charty on GitHub
  2. Issues
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hi-manshu-charty.svg)](https://hysenlabs.com/projects/hi-manshu-charty)

Was this useful?