# Why Not Compose: a cookbook that doubles as a sample app

> Why Not Compose collects Jetpack Compose animations, components and complete tutorials in one Kotlin app, so a developer can read the code for a screen, run the same build in the Google Play app, and lift the pattern into a real project.

**ImaginativeShohag/Why-Not-Compose** — A collection of animations, compositions, UIs using Jetpack Compose. You can say Jetpack Compose cookbook, showcase or play-ground if you want!

- Repository: https://github.com/ImaginativeShohag/Why-Not-Compose
- Website: https://play.google.com/store/apps/details?id=org.imaginativeworld.whynotcompose
- Stars: 732 · Forks: 46
- Language: Kotlin
- License: Apache-2.0
- Published: 2026-10-21 · Updated: 2026-10-21 · Language: en
- Canonical page: https://hysenlabs.com/projects/imaginativeshohag-why-not-compose

## A cookbook that ships as an installable Android app

Why Not Compose is a collection of animations, compositions and UIs built with Jetpack Compose, and the project invites you to think of it as a cookbook or a playground. The unusual part is that it is not only a source tree. The same code is published on Google Play under org.imaginativeworld.whynotcompose, so you can install the app and see the counter animation, the animated visibility sample or the tic-tac-toe board running on a device rather than reading about them. The API badge states API 21 and above, and the featured screens include a map view, an OTP code verification flow and a web view alongside the animation set. That combination is what makes the repository worth a look: the code is arranged so a developer can find the screen they need, read how it is built, and see the same thing working on hardware.

## MVVM, Hilt and Navigation wired in rather than bolted on

The application follows an MVVM pattern and uses the Navigation Component and Hilt, so the dependency graph and screen routing are already resolved for you. Everywhere dark mode support is built in, and the visual layer is Material 3 with a large set of ready to use compositions covering the standard surfaces: app bar, button, card, check box, drop down, grid, list item, lists, loading indicator, radio button, scaffold, snackbar, switch, text fields and swipe to dismiss, plus a swipe to refresh layout. The build is Gradle with the Kotlin DSL, so configuration lives in build.gradle.kts files and settings.gradle.kts rather than Groovy scripts. This matters for how you would borrow from it. Reading a single composable is easy; reading how a screen, a ViewModel, a navigation route and an injected repository fit together takes the module layout, which the repository root makes visible through separate directories.

## Tutorials that go from a counter to a CMS with caching

The tutorial list is graded by difficulty, which makes it usable as a learning path rather than a random pile of samples. At the beginner end there is a plain counter, a counter with a ViewModel, AnimatedVisibility, Lottie, permission handling and a reactive model. The intermediate tier adds selecting an image and cropping it for upload, capturing an image and cropping it, OneSignal and broadcast handling, deep links, navigation data passing and baseline profiles. The advanced tier covers data fetch with Paging, tic-tac-toe, ExoPlayer and a CMS with memory and storage caching, plus a barcode scanner built on Google code scanner and ML Kit. Deep links and ML Kit are the two entries that link out to external documentation, so they double as pointers to the official guidance rather than standing alone. The repository root mirrors this structure with directories for the base app, the cms module, common-ui-compose, exoplayer, popbackstack and tictactoe, so each tutorial has a home you can open.

## The animations and the screenshots that show the states

The animation gallery is where this project differs from a plain component dump. The overview shows animated text with bubbles, a story sequence, a running car and a clip of the Emudi app, each as an animated gif rather than a static preview, so you can see the transition behaviour instead of guessing at it from a still frame. Component screens use Compose preview images generated from the same code, which means the screenshots are not hand-drawn mocks. They show a loading indicator and a swipe-to-refresh animation alongside the static components, and the UI set adds a video for one screen. The practical point is that when you are deciding between two animation approaches, this repository lets you compare the motion, which a screenshot of the final frame does not tell you.

## CI that checks style, security and performance

The project treats its own pipeline as part of the sample. Continuous integration and delivery run ktlint for code style, CodeQL for security analysis, baseline profile generation and Fastlane to publish to Google Play. The ktlint badge sits at the top of the project overview, which tells you that style is enforced rather than left to reviewer taste, and the spotless directory in the repository root confirms a separate formatting setup. Baseline profile generation is worth noting because it appears both as a CI job and as its own intermediate tutorial, so the app is not merely configured for baseline profiles, it teaches them. The CI/CD workflow is also mirrored in the .github directory, which means you can copy the workflow files themselves rather than reconstructing them.

## Reading the TODO list tells you what is not finished

The README ends with an open task list, and it is more informative than a features section would be. Unchecked items include accompanist WebView support, a bottom sheet composition, fixing the custom LazyGridScope.items, a list with LazyGrid and paging with LazyGrid, updating to the new storage permission, creating a color ready for dark and light mode, an AlarmManager example, a month picker component, upgrading the OneSignal library and a new file browser using MediaStore. There is also a plan to migrate ExoPlayer to the media3 route and to update all LaunchedEffect usages for the rememberUpdatedState lambda issue. One entry simply asks for a colour ready for dark and light mode, which is a fair signal about how much of the polish is finished. Anyone copying from this project should read that list first, since several of these are exactly the pieces a real app needs and finds missing.

## Keeping dependency versions current before you copy anything

The project pins dependency versions in a versions.properties file and uses the refreshVersions plugin to keep them current. The project gives one command for updating them, a Gradle wrapper invocation from the project root.

```bash
./gradlew refreshVersions
```

Run it and the plugin fetches the newer version numbers, so the tree stops drifting behind current Android tooling. The repository also carries a Gemfile and Gemfile.lock, a lint.xml, an.editorconfig and a benchmarks directory, which together suggest that the project pays attention to lint, to Ruby tooling for the release side and to measurement. There is also a PRIVACY-POLICY.md, which fits an app distributed on Google Play. Before you copy from this code, run that refreshVersions command and read the diff it produces, because a tutorial pinned to a stale Compose version can behave differently from the one you copied a year later.

## Licence, activity and what the release history says

Why Not Compose is distributed under the Apache-2.0 licence, with the licence text in the LICENSE file at the repository root. That is a permissive licence with no copyleft obligation, so code taken from the tutorials can be moved into a commercial app without the licensing constraints that a GPL project would impose. On the cadence, the tagged releases tell a story of their own: v7.3.1 on 2025-01-16, v7.2.2 on 2024-12-30 and v7.2.0 on 2024-12-27, all clustered around the end of 2024 and the start of 2025. The last push to the repository was on 2026-07-23, which is later than those tags, so the working tree moved on after the last named release. In other words, what you find on the default branch is not necessarily what the newest published build contains, and that gap is worth accounting for when you pin a dependency on this project.

## Conclusion

Why Not Compose fits an Android developer who wants working Jetpack Compose code for a specific screen rather than a fragment to copy, and it fits teams that need a reference for MVVM with Hilt, Navigation Component and Material 3 set up in one place. It does not fit someone who wants a drop-in library, since this is an application project with app/, tictactoe/, cms/ and exoplayer/ modules rather than a published artifact, and it does not fit a project that has to run on anything below API 21 because the project badge states API 21 and above. Before you start from it, read the open task list at the end of the project overview, because items such as the accompanist WebView, Bottom Sheet composition and LazyGrid paging are still unchecked, and run ./gradlew refreshVersions first if you plan to depend on the pinned versions in versions.properties.

## FAQ

### What is Why Not Compose used for?

It is a collection of animations, compositions and UIs built with Jetpack Compose, which the project invites you to treat as a cookbook or playground. The same code is published as a Google Play app under org.imaginativeworld.whynotcompose so the screens can be seen running on a device.

### Which Jetpack Compose tutorials does the project include?

The list runs from a counter and a counter with a ViewModel through AnimatedVisibility, Lottie, permissions and a reactive model, to intermediate items such as image capture and crop, deep links and baseline profiles, and advanced ones covering Paging, tic-tac-toe, ExoPlayer, a CMS with caching and a barcode scanner.

### How do I keep the dependency versions in Why Not Compose up to date?

The project pins versions in versions.properties and uses the refreshVersions plugin. The documented command is ./gradlew refreshVersions for fetching version updates.

### What licence does Why Not Compose use and how current is it?

It is licensed under Apache-2.0, so code can be reused without copyleft obligations. The tagged releases are v7.3.1 on 2025-01-16, v7.2.2 on 2024-12-30 and v7.2.0 on 2024-12-27, and the last push was on 2026-07-23, so the default branch has moved on since the last named release.

## Sources

- [ImaginativeShohag/Why-Not-Compose on GitHub](https://github.com/ImaginativeShohag/Why-Not-Compose)
- [License: Apache-2.0](https://github.com/ImaginativeShohag/Why-Not-Compose/blob/main/LICENSE)
- [Project website](https://play.google.com/store/apps/details?id=org.imaginativeworld.whynotcompose)
- [README](https://github.com/ImaginativeShohag/Why-Not-Compose/blob/main/README.md)
- [Releases](https://github.com/ImaginativeShohag/Why-Not-Compose/releases)

---

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