Open-source project
miaowmiaow/fragmject avatar
miaowmiaow/fragmject

fragmject: a Kotlin and Jetpack Compose learning app built on the official Android way

fragmject is a learning project prepared for Kotlin and Jetpack Compose. | fragmject Kotlin Compose App fragmject Android Developer .

1,465 stars253 forksKotlinApache-2.0

At a glance

What is it?
fragmject is a sample Android app written for people learning Kotlin and Jetpack Compose. Its README argues that complex open source projects are bad first teachers, so it implements things by hand instead of pulling in libraries.
Who is it for?
Adopt fragmject if you are learning Kotlin and Compose and want a complete multi-module app that is deliberately under-abstracted, with Navigation 3 and WindowSizeClass code you can read end to end. Do not adopt it as a production dependency or as a source of up-to-date library versions: the last push was on 2021-08-15, so the README's stack (Kotlin 2.4.x, Navigation 3, Room 3) and the code in the repository may not line up, and the README does not document an upgrade path.
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 6 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 September 27, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What fragmject is for, and who it is not for

The README opens with a complaint about learning Kotlin: books and videos explain individual language features, but leave you without a complete project to work through. Open source apps are the other extreme. Their business logic is complicated and their code is wrapped layer upon layer, which the README says makes them a poor place to start. fragmject exists as the middle option, described as "a learning project prepared for Kotlin and Jetpack Compose" and "an introductory project for beginners."

The intended reader is an Android developer who already knows some Kotlin and wants to see how an app is assembled. The README lists prerequisites rather than assuming them: Kotlin, ViewModel, coroutines, Room and Compose, each linked to the corresponding Android Developer page. If you have never written a ViewModel or a coroutine, this repository will not teach you those in isolation.

The scope is deliberately narrow. The README states there is no complicated business logic and no extra abstraction, and that the code follows the official Android Developer style. The app is built against the WanAndroid open API, credited in the README, so the domain is articles, users and settings rather than anything proprietary. That is the right size for a first complete project: enough screens to show navigation and state, not so many that you lose the thread.

The architecture: core, feature and app modules with MVVM and MVI mixed

The README describes a multi-module layout split into core, feature and app, with MVVM and MVI mixed as the architectural pattern. The top level of the repository matches that description: alongside app/, build-logic/, gradle/ and settings.gradle.kts, there are core/ and feature/ directories. The app module is the shell. Its source tree contains a single Activity, WanActivity.kt, plus WanApplication.kt as the Hilt entry point and WanNavGraph.kt for navigation.

Navigation is the most interesting part of the design. The README says the project uses Navigation 3 with NavBackStack and NavDisplay, and describes type-safe navigation. WanNavGraph.kt is where the Expanded window size intercepts a NavKey and hands it to a DetailPane instead of pushing a full screen. That is a real architectural decision, not a library call: the navigation graph has to know about window size, which is why the file is named in the README's list of relevant files.

The supporting pieces are conventional. Hilt for dependency injection, Room for the database, Retrofit with OkHttp for network calls. The build uses Gradle Kotlin DSL with a Version Catalog and Convention Plugins, which is why build-logic/ and gradle/libs.versions.toml sit at the top level. If you have only ever worked in a single-module app, the convention plugin setup is likely to be the part that takes longest to understand, and the README does not walk through it.

Installing fragmject and getting a first build running

There is no published package to depend on. The README points you at the repository, and the download section links an APK file under app/free/release/ for people who only want to try the app. To read and change the code, open the project in Android Studio.

The README's development environment section is short and blunt: update Android Studio first, and it notes you may need a proxy to download it. It also says you can configure AGP and Compose yourself to adapt the project, and links gradle/libs.versions.toml as the place to look. That file is the single source of truth for versions in this project, so it is the first thing to open after you have the source. The README does not list a clone command or a Gradle invocation, so there is nothing to copy here beyond the file path itself.

The first real thing to read is not a screen but the window size dispatch. The README gives this example of how layouts are selected:

kotlin
val windowSizeClass = LocalWindowSizeClass.current
when (windowSizeClass.widthSizeClass) {
    WindowWidthSizeClass.Compact -> CompactLayout()
    WindowWidthSizeClass.Medium  -> MediumLayout()
    WindowWidthSizeClass.Expanded -> ExpandedLayout()
}

LocalWindowSizeClass.kt lives in core/designsystem and injects the value through a CompositionLocal with convenience extensions. Trace that file, then WanNavGraph.kt, then MainScreen.kt in feature/wan/impl, and you have followed the whole responsive path.

The README also documents SharedFlowBus, the hand-written message bus, with its four entry points:

kotlin
SharedFlowBus.with(objectKey: Class<T>).tryEmit(value: T)
SharedFlowBus.withSticky(objectKey: Class<T>).tryEmit(value: T)
SharedFlowBus.on(objectKey: Class<T>).observe(owner){ it ->
    println(it)
}

with and withSticky emit, on and onSticky subscribe, and each takes a Class key. The README describes the whole bus as roughly 30 lines, which makes it a short read once you have the app building.

WindowSizeClass: three layouts and a list-detail pane

The README documents the responsive behaviour as a table. Below 600dp the app is Compact and uses a NavigationBar at the bottom, with details pushed full screen. Between 600 and 840dp it is Medium, with a NavigationDrawerItem plus Surface on the left, and details still pushed full screen. At 840dp and above it is Expanded, with a PermanentNavigationDrawer and details rendered in a right-hand panel next to the list.

The Expanded case is the one worth studying. The README's diagram shows a list taking 50 percent and a DetailPane taking the other 50 percent, where the pane can render WebScreen, UserScreen, SettingScreen or others. That is the List-Detail pattern implemented through navigation interception rather than through a separate tablet layout file. For a learner, the value is seeing how one navigation graph can produce two different interaction models without duplicating screens.

The trade-off is coupling. Intercepting a NavKey in WanNavGraph.kt means the navigation layer has to consult window size, so navigation is no longer purely a function of the destination. That is a deliberate choice and a reasonable one for this pattern, but it is the kind of thing that gets harder to reason about as the number of destinations grows. The README presents the mechanism without discussing that cost.

Why the project implements things instead of depending on libraries

This is the most opinionated section of the README, and it is worth taking seriously even if you disagree. The author states that in daily work they recommend Hilt, Paging and similar libraries, because they raise efficiency and reduce bugs. Then they argue beginners should not lean on third-party libraries early, for two reasons: libraries are easy to use but their internals are complex, so reading the source can discourage a learner, and beginners mistake a library's capability for their own, so their ability drops sharply once the library is gone.

The project therefore implements as much as it can itself. The README admits the result may not be elegant, but says it will teach you more. The list of hand-built pieces is long: an image picker, an image editor, a calendar control, a wheel picker, full-screen immersive mode, screen recording, and a message bus.

There is also a bytecode instrumentation component. The repository has a library-plugin directory with its own source and resources, and the README links articles on using ASM to print method execution time, to do automatic event tracking, and to replace target fields or methods for privacy compliance. That is a substantial topic sitting inside a beginner project, and it is the clearest example of the no-shortcuts philosophy: instead of calling an analytics SDK, the project shows you the instrumentation.

The maintenance problem: a 2021 push against a 2026 Android toolchain

The last push to the default branch was on 2021-08-15, and the most recent release is v1.1.0 from the same date. Nothing in the repository indicates later activity. For an Android project, that gap matters more than it would for a library in a stable language, because the build toolchain moves: AGP, Kotlin, Compose and Android Studio all version together, and a project pinned to 2021 versions will not open cleanly in a current Studio without work.

There is a second, sharper problem. The README describes a stack of Kotlin 2.4.x, Navigation 3 with NavBackStack and NavDisplay, Room 3, Material 3 and WindowSizeClass. Those are not 2021-era components, and the README also links a v1.3.0 tag for people who do not want Compose. The README and the last push date describe different states of the project, and the README does not explain the discrepancy. Treat the README as a description of intent and the repository contents as the thing you will actually build.

Practically, this means fragmject is a reading project, not a base to fork. If you want a maintained starting point for a new app, a template that tracks current AGP and Compose releases will save you the upgrade. If you want to understand how a multi-module Compose app is put together, the code is still there and the module boundaries still make sense. The licence is Apache-2.0, which permits commercial use and modification, but the README does not document an upgrade path or a supported version matrix, so there is no stated compatibility commitment to rely on.

Where fragmject is the wrong tool

The README is explicit that this is a learning project, and that framing rules out several uses. It is the wrong choice if you need a production foundation: the author states the code may not be elegant, and the last push was on 2021-08-15, so you would inherit both the style and the version debt.

It is also wrong if you want to learn a specific library. The project's stated method is to avoid libraries, so if your goal is to learn Paging or to see idiomatic use of a large third-party SDK, this repository deliberately does not show you that. The README even says the author recommends those libraries at work. That is an honest position, but it means fragmject cannot be your only reference if your job involves a conventional library-heavy codebase.

A third mismatch is experience level. The prerequisite list assumes Kotlin, ViewModel, coroutines, Room and Compose. A reader without those will find the multi-module setup and the convention plugins harder than the Compose code itself. And if you are already comfortable with Compose and modularisation, the value drops quickly: the hand-rolled controls and the SharedFlowBus are more interesting as teaching material than as code you would copy. A reader in that position is better served by reading the linked articles on bytecode instrumentation and WebView optimisation than by working through the app.

What to verify before you invest time

Start with gradle/libs.versions.toml. It is the file the README itself points to when it says you can configure AGP and Compose to adapt the project, and it tells you in one screen whether the pinned versions are buildable with your toolchain. If they are not, decide before you start whether you are willing to do that upgrade, because it is the first task, not a later one.

Next, confirm the README's claims against the tree. The README names LocalWindowSizeClass.kt under core/designsystem, WanNavGraph.kt under app/src/main/java/com/example/fragment/project, and MainScreen.kt under feature/wan/impl. Open those three and check that the Expanded-mode interception described in the README is actually implemented. If the README describes a newer state than the code, that is the discrepancy to resolve before you trust the rest of the documentation.

Finally, decide what you are there for. If it is the responsive layout, the three files above are the whole path and you can ignore the rest. If it is the bytecode instrumentation, go straight to library-plugin and the linked ASM articles. If it is a base for a real app, look elsewhere; the Apache-2.0 licence lets you reuse the code, but the README makes no promise that it will still compile against the Android toolchain you are using.

Editorial conclusion

Adopt fragmject if you are learning Kotlin and Compose and want a complete multi-module app that is deliberately under-abstracted, with Navigation 3 and WindowSizeClass code you can read end to end. Do not adopt it as a production dependency or as a source of up-to-date library versions: the last push was on 2021-08-15, so the README's stack (Kotlin 2.4.x, Navigation 3, Room 3) and the code in the repository may not line up, and the README does not document an upgrade path. Before you spend time on it, open gradle/libs.versions.toml on the master branch and check that the versions it pins match what your Android Studio and AGP can actually build.

Frequently asked questions

What is fragmject used for?

It is a learning project for Kotlin and Jetpack Compose, described in the README as an introductory project for beginners. It implements a complete app against the WanAndroid open API so that learners can see a full multi-module Compose codebase rather than isolated language examples.

Does fragmject depend on many third-party libraries?

No, and that is deliberate. The README says the project implements as much as possible itself, on the argument that beginners who lean on third-party libraries get a weak foundation, and it admits the result may be less elegant. It does use Hilt, Room and Retrofit.

When was fragmject last updated?

The last push to the default branch was on 2021-08-15, and the most recent release is v1.1.0 from the same date. The repository is not archived, but there is no activity recorded after that date.

What do I need to know before starting fragmject?

The README lists Kotlin, ViewModel, coroutines, Room and Compose as prerequisites, each linked to the corresponding Android Developer page. It also says to update Android Studio first and notes you may need a proxy to download it.

Official sources

  1. Official README
  2. Project repository
  3. Release notes
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/miaowmiaow-fragmject.svg)](https://hysenlabs.com/projects/miaowmiaow-fragmject)