# MinimalistWeather: a Compose-first Android weather client on Clean Architecture

> ByronNote's MinimalistWeather is a Kotlin and Jetpack Compose Android weather app split into app, presentation, data and domain modules, with Open-Meteo behind the network boundary. The architecture is the point; the licence file is Apache 2.0 even though the repository metadata does not say so.

**ByronNote/MinimalistWeather** — 一款基于 Kotlin、Jetpack Compose 与 Clean Architecture 构建的现代 Android 天气应用，支持动态天气场景、全球城市搜索、空气质量、24 小时与 7 日预报，数据来自 Open-Meteo。

- Repository: https://github.com/ByronNote/MinimalistWeather
- Website: https://zhuanlan.zhihu.com/baron
- Stars: 2,444 · Forks: 558
- Language: Kotlin
- License: not declared
- Published: 2026-09-28 · Updated: 2026-09-28 · Language: en
- Canonical page: https://hysenlabs.com/projects/byronnote-minimalistweather

## What MinimalistWeather is for, and who it is actually written for

The README is direct about the origin: the project began as a demonstration of Android engineering architecture and common open source libraries. That framing matters more than the feature list. MinimalistWeather is a weather app, but its audience is Android developers who want to read a multi-module Clean Architecture codebase that is small enough to hold in your head.

The feature set is what you would expect from a serious weather client: current conditions with apparent temperature and a daily summary, a 24-hour trend, a 7-day forecast, AQI with primary pollutants, and a Compose scene layer that shifts with weather, day and night, cloud cover, wind and precipitation. City search combines a built-in global popular-city catalogue with Open-Meteo's geocoding endpoint, and DataStore holds the current city, the city list, refresh settings and a weather cache.

If you are evaluating it as an end-user product, note what is absent. The README describes no release channel, no published APK, and no crash reporting. The app is described as still under development. Treat it as a codebase to learn from or fork, not as a maintained consumer app with a support path.

## The module graph is the real design decision

The repository root holds four Gradle modules plus a benchmark module: app, presentation, data, domain and baselineprofile. The README's own dependency diagram is explicit: app depends on presentation, data and domain; presentation depends on domain; data depends on domain; baselineprofile points at app.

What that buys you is a domain layer that does not depend on the Android framework. Models, repository contracts, use cases and result types live in plain Kotlin and JVM code, which is why the README can offer ./gradlew :domain:test as a fast, device-free check. The data module owns the Open-Meteo network boundary, DTOs, parsers, mappers, DataStore and the repository implementations. Presentation holds Compose screens, ViewModels, UI state, events and effects, UI mappers and the weather visual engine.

The state model is unidirectional: ViewModels expose immutable StateFlow, and the UI emits events back. If you have worked on Compose apps where state leaks into composables and survives configuration changes in unpredictable ways, this is the part worth reading first. The trade-off is ceremony. A single screen's data path crosses a use case, a repository contract, a repository implementation, a DTO mapper and a UI mapper. For a weather app with roughly a dozen screens that is acceptable. Copy this structure into a five-screen app and you will spend more time wiring than building.

## Installing it and getting a debug build running

There is no download link in the README and no published artifact. The documented path is to open the repository root in Android Studio and let Gradle Sync finish, or to build from the command line. The stated prerequisites are Android Studio compatible with AGP 9.2.0, JDK 17, Android SDK 37, and a device or emulator running Android 6.0 (API 23) or higher.

The README gives this command for a debug build:

```bash
./gradlew assembleDebug
```

The APK lands at app/build/outputs/apk/debug/app-debug.apk. Install it on a connected device or emulator with adb install, then launch it. On first run the app needs location permission (coarse or precise) if you want the current-location flow; the README states that city search and forecasts work without it, and that no API key is required because all three Open-Meteo endpoints are open.

Before trusting a local build, run the full verification task the README lists:

```bash
./gradlew test lint assembleDebug
```

During development you can narrow that to a single module, for example ./gradlew :data:test to exercise the Open-Meteo parsing and repository layer without touching the UI. The README also notes that Baseline Profile generation, ./gradlew :app:generateBaselineProfile, requires a connected test device.

One practical warning: the toolchain versions in the README are aggressive. Kotlin 2.3.21, Gradle 9.4.1, AGP 9.2.0 and KSP are pinned in gradle/libs.versions.toml. If your installed Android Studio predates that AGP line, sync will fail before any source file is compiled, and the fix is a toolchain upgrade rather than a code change.

## Where the design gets in your way

The clearest limitation is the one the README states outright: the project is still under development. There are no retrieved releases, so there is no version to pin, no changelog to diff against, and no upgrade path other than tracking the master branch. If you fork it, you own the merge burden for every upstream change.

Data sourcing is a second constraint. Every weather value comes from Open-Meteo, and the README says the current implementation requires no API key. That is convenient and it is also a single point of dependency. There is no provider abstraction described that would let you swap in another forecast source without touching the data module, and no documented caching policy beyond the statement that weather cache lives in DataStore Preferences. If your requirement is a commercial weather feed with an SLA, this is the wrong starting point.

Location handling is deliberately thin. The README names Android LocationManager and Geocoder for the current-location flow. Geocoder behaviour varies by device and by whether a backend geocoding service is present, and the README does not describe a fallback when reverse geocoding returns nothing. The built-in popular-city catalogue plus Open-Meteo search covers that gap for manual selection, but the automatic path is the fragile one.

Finally, the repository carries historical baggage. The README states that the active app no longer uses the old MVP, RxJava, Retrofit, ORMLite, ButterKnife, FastJson or Stetho stack, and that the old framework diagram is kept only as historical material. If you search the repository for those names you may still find references, and you should confirm which module you are reading before copying anything.

## How it compares with a plain single-module Compose weather app

The obvious alternative is not another weather app. It is building the same thing as one Gradle module with Compose, a ViewModel and a Retrofit or Ktor client, and no domain layer at all. That approach is faster to start and easier to debug, because there is no mapper chain between the JSON response and the composable.

The difference is testability and replacement cost. In MinimalistWeather, the domain module is pure Kotlin, so use cases and result types can be tested on the JVM with no emulator, which is what ./gradlew :domain:test exists for. In a single-module app, the same logic usually sits inside a ViewModel that references Android classes, and testing it means Robolectric or an instrumented test. The second difference is substitution: swapping Open-Meteo for another provider touches the data module only, because presentation talks to repository contracts in domain. In a single-module app that swap tends to reach into the ViewModel and sometimes into the screen.

Neither approach is wrong. If the app is a weekend project or a prototype for a design idea, the module split is overhead you will feel every time you add a screen. If the app is expected to outlive its first data provider, or if more than one person will work on it, the boundaries pay for themselves. MinimalistWeather sits firmly on the second side, and its README's framing as an architecture demonstration is honest about that.

## Maintenance, upgrades and what the licence actually says

The repository is not archived, and the last push was on 2026-08-16. That is recent enough that the codebase reflects current Android tooling, but there is no release history to lean on. Upgrade cost therefore concentrates in gradle/libs.versions.toml, which the README describes as the single place where dependencies, plugins, SDK and app versions are declared. That is good hygiene: a version bump is a one-file change plus a full ./gradlew test lint assembleDebug run.

The risk is version coupling. Kotlin 2.3.21, Gradle 9.4.1, AGP 9.2.0 and KSP move together, and Compose compiler versions track Kotlin. Jumping one without the others is the usual failure. The README's own caution about Macrobenchmark results is worth repeating in this context: startup performance figures are sensitive to device state, so the README advises collecting them repeatedly on a fixed-state physical device before comparing. Treat the Baseline Profile and Startup Profile setup as a measurement harness, not as a guarantee.

On licensing: the repository metadata does not report a licence, but the README's licence section carries the full Apache License 2.0 text with a copyright line dated 2017 to Byron. Apache 2.0 permits commercial and closed-source use, requires preservation of the notice and the licence text, and includes a patent grant. The copyright year in the notice is 2017 while the code has since been rewritten, which is a detail to keep intact rather than edit. This is a description of what the file says, not legal advice; if your organisation has a policy on third-party notices, run the repository through it.

## Conclusion

Adopt MinimalistWeather if you want a working Android weather client whose module boundaries you can read in an afternoon, or if you are assembling a Compose app with Hilt, DataStore and WorkManager and want a reference that already wires them together. Do not adopt it if you need a published Play Store product, a documented release history, or a project with a support channel; there are no releases in the repository and no issue-triage or response commitment stated anywhere. Before you build on it, open gradle/libs.versions.toml and confirm every pinned version resolves against your Android Studio and JDK 17 setup, then run ./gradlew test lint assembleDebug on a clean checkout, because AGP 9.2.0 and Gradle 9.4.1 are the versions the README names and older toolchains will fail at sync rather than at compile.

## FAQ

### Does MinimalistWeather need an API key for its weather data?

No. The README states that the current implementation requires no API key, because city search, forecasts and air quality all come from Open-Meteo endpoints. Location access still needs the user to grant coarse or precise permission.

### Which Android version and tools does MinimalistWeather require to build?

The README lists Android Studio compatible with AGP 9.2.0, JDK 17, Android SDK 37, and a device or emulator on Android 6.0 (API 23) or higher. It also pins Kotlin 2.3.21, Gradle 9.4.1 and KSP in gradle/libs.versions.toml.

### How do I run the tests for MinimalistWeather without a device?

The README gives per-module commands such as ./gradlew :domain:test, ./gradlew :data:test and ./gradlew :presentation:test. The domain module is pure Kotlin and JVM, so its tests do not need an emulator; Baseline Profile generation does require a connected device.

### Does MinimalistWeather store my city and weather data locally?

Yes. The README states that the current city, recent cities, added cities, refresh interval and weather cache are persisted with DataStore Preferences, with a SharedPreferences migration path.

## Sources

- [ByronNote/MinimalistWeather on GitHub](https://github.com/ByronNote/MinimalistWeather)
- [Issues](https://github.com/ByronNote/MinimalistWeather/issues)
- [Project website](https://zhuanlan.zhihu.com/baron)
- [README](https://github.com/ByronNote/MinimalistWeather/blob/master/README.md)

---

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