Library / SDK
Kashif-E/Kamera avatar
Kashif-E/Kamera

Kamera: one camera API for Compose Multiplatform

A camera library for Compose Multiplatform

581 stars55 forksKotlinApache-2.0

At a glance

What is it?
Kamera is a Kotlin camera library for Compose Multiplatform that covers Android, iOS and JVM desktop with a single API, and it splits the optional pieces, image saving, QR scanning, OCR, video recording and the image analyzer, into separate Maven artifacts. The 1.x line was rewritten around a Compose first state model, and the 1.2 release is the current one.
Who is it for?
Adopt Kamera if you are building a Compose Multiplatform application and want the camera, the QR scanner and the OCR to live in shared code rather than in a platform specific wrapper per target. Do not adopt it if you only ship Android, where the platform camera APIs and the standard Compose integration are already there, and do not assume the plugin set is interchangeable with anything else, since the artifact names and the group id are specific to this project.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 50 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 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A camera that does not change shape per platform

Kamera is described as a modern camera library for Compose Multiplatform supporting Android, iOS and Desktop with a unified API, and it is built on Compose Multiplatform rather than on a native view system, which is the decision that makes the unification possible.

The repository topics name the underlying platform work: camerax for Android and avfoundation for iOS, alongside compose-multiplatform and compose-ui. The two platforms have very different camera stacks, and CameraX on Android is a library that itself wraps Camera2 and CameraX behaviours while AVFoundation on iOS is a different model entirely. Wrapping both behind one Compose API is the entire value of the project.

The feature list is a camera API plus a set of controls. Cross-platform for Android, iOS and JVM Desktop. Compose first with a native Compose Multiplatform API. Flexible configuration covering aspect ratios, zoom, focus, flash and lens selection between ultra-wide and telephoto, with a hardware capability query so the app can ask what the device actually has. Video recording with pause and resume, configurable quality and a maximum duration. Advanced control for camera selection on Android and iOS.

One entry stands out for performance reasons: optimized capture, direct file saving with takePictureToFile(), which avoids the intermediate buffer that a typical takePicture call would allocate.

The audience is a team writing shared Compose code across more than one target, and the platform list in the topics is a fair summary of where it comes from.

The optional pieces are separate Maven artifacts

The plugin system is the second structural idea, and it explains the dependency block in the README. The core library is one artifact, and each optional capability is its own artifact, so a project pays only for what it uses.

The Gradle coordinates are worth writing down, because the module names do not match the feature names in an obvious way. The core is io.github.kashif-mehmood-km:camerak, and the plugins are image_saver_plugin, qr_scanner_plugin, ocr_plugin, video_recorder_plugin and analyzer_plugin, all under the same group id.

The full set looks like this in a build.gradle.kts:

kotlin
dependencies {
    // Core library
    implementation("io.github.kashif-mehmood-km:camerak:1.2")

    // Optional plugins
    implementation("io.github.kashif-mehmood-km:image_saver_plugin:1.2")
    implementation("io.github.kashif-mehmood-km:qr_scanner_plugin:1.2")
    implementation("io.github.kashif-mehmood-km:ocr_plugin:1.2")
    implementation("io.github.kashif-mehmood-km:video_recorder_plugin:1.2")
    implementation("io.github.kashif-mehmood-km:analyzer_plugin:1.2")
}

Note that every artifact carries the same version number, 1.2. That is a deliberate coupling: the plugins talk to the core through a state holder, so a plugin built against a different core version is a runtime problem rather than a compile time one. In a project with five plugins, that means the version has to move as a unit.

The plugin list in the feature section is the same set expressed as capabilities: modular QR and barcode scanning, OCR, image saving, video recording and the image analyzer. The analyzer is the one worth understanding, since it is the hook for running your own vision model on the camera feed, and the quick start shows it attached alongside the others.

The 1.x rewrite is a state machine you render against

The most important structural fact about this library is in the quick start heading, which calls the new API the Compose first API and dates it to version 0.2.0 and later. The library now uses reactive state management with StateFlow, and the application renders a state object rather than driving the camera imperatively.

The state is a sealed class with three variants, and the shape is what your UI code switches on:

kotlin
sealed class CameraKState {
    data object Initializing : CameraKState()
    data class Ready(val controller: CameraController, val uiState: CameraUIState) : CameraKState()
    data class Error(val exception: Exception, val message: String, val isRetryable: Bo

The Ready variant carries two things, a controller and a UI state object, and the controller is what you call to take a picture. The Error variant carries the exception, a message and a flag saying whether the failure can be retried, which is the kind of detail that is either there or absent, and it is there.

The state holder itself is created by a composable function, and the signature is short enough to be the contract of the library:

kotlin
@Composable
expect fun rememberCameraKState(
    config: CameraConfiguration = CameraConfiguration(),
    setupPlugins: suspend (CameraKStateHolder) -> Unit = {},
): State<CameraKState>

Two things in that signature matter. The config parameter takes the whole configuration in one place, including the lens, the flash mode and the aspect ratio. The setupPlugins lambda is where plugins are attached, and it is marked expect, which is the multiplatform mechanism: the function has a separate implementation per target, and each platform decides how the camera is actually started and how the state is fed.

Version catalog support, and the per platform permissions

The README covers a version catalog route as well as the direct dependency block, and the catalog form is the tidier of the two for a multiplatform project because the version is declared once.

toml
[versions]
camerak = "1.2"

[libraries]
camerak = { module = "io.github.kashif-mehmood-km:camerak", version.ref = "camerak" }
camerak-image-saver = { module = "io.github.kashif-mehmood-km:image_saver_plugin", version.ref = "camerak" }
camerak-qr-scanner = { module = "io.github.kashif-mehmood-km:qr_scanner_plugin", version.ref = "camerak" }
camerak-ocr = { module = "io.github.kashif-mehmood-km:ocr_plugin", version.ref = "camerak" }
camerak-analyzer = { module = "io.github.kashif-mehmood-km:analyzer_plugin", version.ref = "camerak" }
camerak-video-recorder = { module = "io.github.kashif-mehmood-km:video_recorder_plugin", version.ref = "camerak" }

Then the build file refers to the aliases, and the naming maps back to the same artifacts.

The permissions are the part that catches people out, because they are per platform and they are not optional in the general case. On Android you add the camera permission, the write external storage permission and the record audio permission, the last one marked as required for video recording with audio:

xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" /> <!-- Required for video recording with audio -->

On iOS the same three capabilities are declared as usage descriptions in Info.plist, for the camera, for adding to the photo library and for the microphone, each with a human readable string that the platform shows in the permission prompt. Those strings are what a user reads when the app asks for access, and the README's placeholders make it clear that you have to write your own.

A 1.x line with three releases since June 2026

The maintenance picture is recent and the API is still settling. The release tags are 1.2 on 2026-08-07, 1.1 on 2026-06-30 and 1.0 on 2026-06-19, and the last push to the repository was on 2026-09-03, so the project is being worked on and the 1.x line has only existed for a couple of months.

That timing explains the shape of the README. The quick start section is labelled as the new Compose first API for version 0.2.0 and later, which means the pre-1.0 call style is no longer the documented path, and any tutorial you find for this library that predates 1.0 describes an interface that has since been replaced.

The project is published on Maven Central under the io.github.kashif-mehmood-km group, and the README carries badges for the Maven Central version, the GitHub release, two Kotlin Weekly mentions and the licence, which suggests the library has been picked up by the Kotlin community news. The homepage is a documentation site at kashif-e.github.io/Kamera, and the repository has an mkdocs.yml and a docs directory, so the documentation is generated rather than living only in the README.

The licence is Apache-2.0, with the file at the repository root, which is a permissive choice with the patent grant, and the repository also carries a CODE_OF_CONDUCT.md, a CONTRIBUTING.md, a CHANGELOG.md and a CLAUDE.md, plus a Sample project and an iosApp directory.

The repository layout is worth reading as a description of the design. There is a cameraK directory, a commonMain directory, and then one directory per plugin, ImageSaverPlugin, analyzerPlugin, ocrPlugin, qrScannerPlugin and videoRecorderPlugin, with a convention-plugins directory for the Gradle setup and a Sample project that exercises the whole thing.

Editorial conclusion

Adopt Kamera if you are building a Compose Multiplatform application and want the camera, the QR scanner and the OCR to live in shared code rather than in a platform specific wrapper per target. Do not adopt it if you only ship Android, where the platform camera APIs and the standard Compose integration are already there, and do not assume the plugin set is interchangeable with anything else, since the artifact names and the group id are specific to this project. Verify first that the version you use matches the artifacts you depend on, since the core and every plugin are versioned together at 1.2, that the permissions you declare match what you use, and that the state model you are prepared to write against, a State of CameraKState with Initializing, Ready and Error variants, is the one you want, because the Compose first API landed in 0.2.0 and the older call style is gone.

Frequently asked questions

What is Kamera?

Kamera is a camera library for Compose Multiplatform written in Kotlin, covering Android, iOS and JVM desktop with a unified API. It uses CameraX on Android and AVFoundation on iOS underneath a Compose first state model.

How do I add Kamera to a Gradle project?

Add the core dependency implementation("io.github.kashif-mehmood-km:camerak:1.2") to your build.gradle.kts, plus whichever plugin artifacts you need, such as qr_scanner_plugin, ocr_plugin, image_saver_plugin, video_recorder_plugin or analyzer_plugin. A version catalog form with libs.versions.toml is also documented.

What permissions does Kamera need?

On Android you add the CAMERA, WRITE_EXTERNAL_STORAGE and RECORD_AUDIO permissions to AndroidManifest.xml, the last being required for video recording with audio. On iOS you add NSCameraUsageDescription, NSPhotoLibraryAddUsageDescription and NSMicrophoneUsageDescription entries to Info.plist.

How does the Kamera state model work?

rememberCameraKState returns a State of CameraKState, a sealed class with an Initializing variant, a Ready variant carrying a controller and a UI state, and an Error variant carrying the exception, a message and a retryable flag. Plugins are attached through the setupPlugins lambda, which receives a CameraKStateHolder.

Official sources

  1. Kashif-E/Kamera on GitHub
  2. License: Apache-2.0
  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/kashif-e-kamera.svg)](https://hysenlabs.com/projects/kashif-e-kamera)

Was this useful?