<!-- mobian-agent-page publisher="dailydev" canonical="https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn" -->

---
title: How to architect Anvil apps | daily.dev
description: A guide on structuring Android apps built with the Anvil UI library, moving from a simple global controller/model approach for small apps to a Redux-based...
canonical: https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn
twitter:card: summary_large_image
twitter:site: @dailydotdev
og:type: website
og:site_name: daily.dev
og:title: How to architect Anvil apps | daily.dev
og:description: A guide on structuring Android apps built with the Anvil UI library, moving from a simple global controller/model approach for small apps to a Redux-based...
og:url: https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn
og:image: https://api.daily.dev/og/posts/haacLwlbn.png
og:image:alt: How to architect Anvil apps
og:image:width: 1200
og:image:height: 630
og:locale: en
---

> ## Documentation Index
> Fetch the complete documentation index at: https://daily.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# How to architect Anvil apps

**[zserge's blog](https://daily.dev/sources/zserge)** · 7 min read · 0 upvotes · 0 comments

## Summary

A guide on structuring Android apps built with the Anvil UI library, moving from a simple global controller/model approach for small apps to a Redux-based architecture for larger ones. It covers the Redux concepts of state, actions, and reducers using the Jedux library, shows a counter app example, and explains how middleware handles side effects like network downloads while keeping reducers pure.

## Full article

daily.dev links to this article rather than hosting it. Read it at the original source: <https://zserge.com/posts/anvil-app-architecture>

## Questions this post answers

### How do I use middleware in Jedux to handle side effects like file downloads in an Android Redux app?

Emit an action such as START_DOWNLOAD when a button is clicked, and let a Downloader middleware intercept it to start a download thread or service. The thread can emit UPDATE_PROGRESS and DOWNLOAD_FINISHED actions, which flow into the store where a pure reducer updates state like isDownloading or progress, keeping side effects out of the reducer.

_daily.dev surfaces practical Redux and middleware patterns for developers structuring Android app state._

### What is the difference between the reducer and middleware roles in a Jedux Redux setup?

A reducer is a pure function that takes an action and current state and returns a new state with no side effects, while middleware intercepts actions to perform real work like network calls or starting threads, then can propagate, skip, or emit new actions. Middlewares effectively act as the app's controllers, each handling one focused concern.

_Developers weighing state management patterns can find this kind of architecture breakdown on daily.dev._

## Similar posts on daily.dev

- [15 Years of Android App Architectures](https://daily.dev/posts/15-years-of-android-app-architectures-1xg7is4ou) · droidcon · 0 upvotes · 0 comments
- [In Defense of Redux](https://daily.dev/posts/in-defense-of-redux-pcyqzgarj) · ITNEXT · 1 upvotes · 0 comments
- [The Modern Guide to Android SDK Development: Architecture & API Design \(Part 1 of 3\)](https://daily.dev/posts/the-modern-guide-to-android-sdk-development-architecture-api-design-part-1-of-3--97izvnm7x) · ProAndroidDev · 2 upvotes · 0 comments
- [Building a Modularized Android App: A Practical Guide to Clean Architecture in 2026](https://daily.dev/posts/building-a-modularized-android-app-a-practical-guide-to-clean-architecture-in-2026-kseskxqoz) · Medium · 0 upvotes · 0 comments

---

Tags: [#java](https://daily.dev/tags/java), [#architecture](https://daily.dev/tags/architecture), [#android](https://daily.dev/tags/android), [#redux](https://daily.dev/tags/redux)

[View this post on daily.dev](https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn)

```json
{"@context":"https://schema.org","@graph":[{"@type":"Organization","@id":"https://daily.dev/#organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180},"sameAs":["https://twitter.com/dailydotdev","https://github.com/dailydotdev","https://www.linkedin.com/company/daily-dev-ltd"]},{"@type":"WebSite","@id":"https://daily.dev/#website","url":"https://daily.dev","name":"daily.dev","publisher":{"@id":"https://daily.dev/#organization"},"potentialAction":{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https://daily.dev/search?q={search_term_string}"},"query-input":"required name=search_term_string"}}]}
{"@context":"https://schema.org","@type":"TechArticle","headline":"How to architect Anvil apps","url":"https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn","mainEntityOfPage":{"@type":"WebPage","@id":"https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn"},"datePublished":"2026-08-23T10:20:13.524Z","dateModified":"2026-08-23T10:20:41.102Z","description":"A guide on structuring Android apps built with the Anvil UI library, moving from a simple global controller/model approach for small apps to a Redux-based...","image":"https://media.daily.dev/image/upload/s--VDukGCjf--/f_auto/v1722860399/public/Placeholder%2002","thumbnailUrl":"https://media.daily.dev/image/upload/s--VDukGCjf--/f_auto/v1722860399/public/Placeholder%2002","isAccessibleForFree":true,"articleSection":"zserge's blog","inLanguage":"en","publisher":{"@type":"Organization","name":"daily.dev","url":"https://daily.dev","logo":{"@type":"ImageObject","url":"https://daily.dev/apple-touch-icon.png","width":180,"height":180}},"author":{"@type":"Organization","name":"zserge's blog","logo":"https://media.daily.dev/image/upload/s--KQnFBOIT--/f_auto,q_auto/v1787480407/logos/zserge","url":"https://daily.dev/sources/zserge"},"commentCount":0,"discussionUrl":"https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn","interactionStatistic":[{"@type":"InteractionCounter","interactionType":{"@type":"LikeAction"},"userInteractionCount":0},{"@type":"InteractionCounter","interactionType":{"@type":"CommentAction"},"userInteractionCount":0}],"keywords":"java,architecture,android,redux","timeRequired":"PT7M"}
{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https://daily.dev"},{"@type":"ListItem","position":2,"name":"zserge's blog","item":"https://daily.dev/sources/zserge"},{"@type":"ListItem","position":3,"name":"How to architect Anvil apps"}]}
{"@context":"https://schema.org","@type":"FAQPage","@id":"https://daily.dev/posts/how-to-architect-anvil-apps-haaclwlbn#faq","mainEntity":[{"@type":"Question","name":"How do I use middleware in Jedux to handle side effects like file downloads in an Android Redux app?","acceptedAnswer":{"@type":"Answer","text":"Emit an action such as START_DOWNLOAD when a button is clicked, and let a Downloader middleware intercept it to start a download thread or service. The thread can emit UPDATE_PROGRESS and DOWNLOAD_FINISHED actions, which flow into the store where a pure reducer updates state like isDownloading or progress, keeping side effects out of the reducer. daily.dev surfaces practical Redux and middleware patterns for developers structuring Android app state."}},{"@type":"Question","name":"What is the difference between the reducer and middleware roles in a Jedux Redux setup?","acceptedAnswer":{"@type":"Answer","text":"A reducer is a pure function that takes an action and current state and returns a new state with no side effects, while middleware intercepts actions to perform real work like network calls or starting threads, then can propagate, skip, or emit new actions. Middlewares effectively act as the app's controllers, each handling one focused concern. Developers weighing state management patterns can find this kind of architecture breakdown on daily.dev."}}]}
```

