<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Pravin Kunnure</title>
    <description>The latest articles on DEV Community by Pravin Kunnure (@pravin_kunnure_f4663a859a).</description>
    <link>https://dev.to/pravin_kunnure_f4663a859a</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3713897%2F0f67508f-43c2-4f84-ab3d-ae0715306891.jpg</url>
      <title>DEV Community: Pravin Kunnure</title>
      <link>https://dev.to/pravin_kunnure_f4663a859a</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pravin_kunnure_f4663a859a"/>
    <language>en</language>
    <item>
      <title>Engineering Resilient Flutter Apps That Survive Backend Changes</title>
      <dc:creator>Pravin Kunnure</dc:creator>
      <pubDate>Wed, 25 Feb 2026 04:29:18 +0000</pubDate>
      <link>https://dev.to/pravin_kunnure_f4663a859a/engineering-resilient-flutter-apps-that-survive-backend-changes-1p99</link>
      <guid>https://dev.to/pravin_kunnure_f4663a859a/engineering-resilient-flutter-apps-that-survive-backend-changes-1p99</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Designing mobile systems that remain stable as APIs evolve.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;*&lt;em&gt;Mobile apps don’t update instantly.&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Some users disable auto updates.&lt;br&gt;
Some stay on older versions for months.&lt;br&gt;
Some rarely update at all.&lt;/p&gt;

&lt;p&gt;Now imagine this.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Your backend team:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Renames a response field&lt;/p&gt;

&lt;p&gt;Changes a required parameter&lt;/p&gt;

&lt;p&gt;Modifies authentication logic&lt;/p&gt;

&lt;p&gt;Suddenly, thousands of users are using a broken app — and you can’t fix it immediately.&lt;/p&gt;

&lt;p&gt;Because mobile apps are long-lived clients.&lt;/p&gt;

&lt;p&gt;This is where resilient system design matters.&lt;/p&gt;

&lt;p&gt;The Core Problem&lt;/p&gt;

&lt;p&gt;Web applications are simple.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You deploy → everyone gets the new version.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Mobile applications are different.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You deploy → some users update.&lt;br&gt;
Others don’t.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;*&lt;em&gt;Which means:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Your backend must evolve without breaking older mobile versions.&lt;/p&gt;

&lt;p&gt;If it doesn’t, you end up shipping emergency hotfix releases.&lt;/p&gt;

&lt;p&gt;Mature engineering teams avoid this situation entirely.&lt;/p&gt;

&lt;p&gt;How Big Companies Think About This&lt;/p&gt;

&lt;p&gt;Companies like Netflix and Uber assume one thing:&lt;/p&gt;

&lt;p&gt;Old mobile app versions will exist in production for months.&lt;/p&gt;

&lt;p&gt;They design APIs with backward compatibility as a rule — not an afterthought.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;They don’t ask:&lt;br&gt;
*&lt;/em&gt;“Will users update quickly?”&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;They assume:&lt;br&gt;
*&lt;/em&gt;“They won’t.”&lt;/p&gt;

&lt;p&gt;That mindset changes everything.&lt;/p&gt;

&lt;p&gt;The Architecture Pattern That Prevents Breakage&lt;/p&gt;

&lt;p&gt;Here’s a simplified architecture used in resilient mobile systems:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Flutter App&lt;br&gt;
     ↓&lt;br&gt;
API Gateway&lt;br&gt;
     ↓&lt;br&gt;
Compatibility Layer&lt;br&gt;
     ↓&lt;br&gt;
Core Services&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The key idea?&lt;/p&gt;

&lt;p&gt;The backend adapts — not the mobile app.&lt;/p&gt;

&lt;p&gt;Instead of forcing an app update, the server maintains compatibility.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Principle 1: Add, Don’t Mutate&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
*&lt;em&gt;Safe API evolution rule:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
✅ Add optional fields&lt;br&gt;
✅ Add new endpoints&lt;br&gt;
✅ Extend responses&lt;/p&gt;

&lt;p&gt;❌ Don’t remove required fields&lt;br&gt;
❌ Don’t rename response keys casually&lt;br&gt;
❌ Don’t change response types&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Example:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
*&lt;em&gt;Old response:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
{&lt;br&gt;
  "user_name": "Pravin"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Instead of renaming it directly, evolve safely:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
{&lt;br&gt;
  "user_name": "Pravin",&lt;br&gt;
  "username": "Pravin"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Old apps continue working.&lt;/p&gt;

&lt;p&gt;No emergency release required.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Principle 2: Version Your APIs&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Instead of modifying existing routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/api/v1/profile
/api/v2/profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Old app → stays on v1&lt;br&gt;
New app → migrates to v2&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You sunset v1 only after adoption is high enough.&lt;/p&gt;

&lt;p&gt;This isolates breaking changes safely.&lt;/p&gt;

&lt;p&gt;Principle 3: Send App Version in Every Request&lt;/p&gt;

&lt;p&gt;Every Flutter app request should include headers like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;X-App-Version: 1.3.0&lt;br&gt;
X-Platform: android&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;*&lt;em&gt;Now backend can:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Serve compatible responses&lt;/p&gt;

&lt;p&gt;Monitor outdated versions&lt;/p&gt;

&lt;p&gt;Decide when to deprecate&lt;/p&gt;

&lt;p&gt;Roll out changes gradually&lt;/p&gt;

&lt;p&gt;This gives you control instead of chaos.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Principle 4: Use Feature Flags Instead of Hardcoding Logic&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Instead of hardcoding new features inside Flutter, let backend control behavior.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Example:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
{&lt;br&gt;
  "enable_new_dashboard": false,&lt;br&gt;
  "max_items": 5&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Now the app adapts dynamically.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;You can:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Disable features remotely&lt;/p&gt;

&lt;p&gt;Roll out gradually&lt;/p&gt;

&lt;p&gt;Avoid urgent releases&lt;/p&gt;

&lt;p&gt;Run experiments safely&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Principle 5: Defensive Parsing in Flutter&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Flutter should never assume APIs are perfect.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Instead of:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
final username = json['username'];&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Use:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
final username = json['username'] ?? json['user_name'] ?? '';&lt;/p&gt;

&lt;p&gt;Small defensive decisions prevent large production crashes.&lt;/p&gt;

&lt;p&gt;When You Still Need a New Release&lt;/p&gt;

&lt;p&gt;Let’s be realistic.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;You must release a new version when:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Authentication flow changes&lt;/p&gt;

&lt;p&gt;UI structure changes&lt;/p&gt;

&lt;p&gt;Security patches are required&lt;/p&gt;

&lt;p&gt;Native SDK updates are required&lt;/p&gt;

&lt;p&gt;Some changes are unavoidable.&lt;/p&gt;

&lt;p&gt;But resilient architecture ensures those releases are planned — not panic-driven.&lt;/p&gt;

&lt;p&gt;The Real Engineering Mindset&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Junior mindset:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
“Backend changed. Release new app.”&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Senior mindset:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
“Design the system so backend evolution doesn’t break clients.”&lt;/p&gt;

&lt;p&gt;Resilience isn’t about avoiding releases forever.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;It’s about:&lt;br&gt;
*&lt;/em&gt;&lt;br&gt;
Eliminating emergency hotfixes&lt;/p&gt;

&lt;p&gt;Supporting long-lived clients&lt;/p&gt;

&lt;p&gt;Designing APIs with discipline&lt;/p&gt;

&lt;p&gt;Respecting backward compatibility&lt;/p&gt;

&lt;p&gt;That’s what separates feature development from system engineering.&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Flutter apps don’t break because Flutter is fragile.&lt;/p&gt;

&lt;p&gt;They break because backend evolution is careless.&lt;/p&gt;

&lt;p&gt;If you understand both mobile and backend systems, you can design applications that survive change — gracefully.&lt;/p&gt;

&lt;p&gt;And in real-world production systems, that’s what truly matters.**&lt;/p&gt;

&lt;p&gt;`&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
{% embed  %}&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br&gt;
`&lt;br&gt;
**&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
    </item>
    <item>
      <title>Flutter Clean Architecture Explained Simply</title>
      <dc:creator>Pravin Kunnure</dc:creator>
      <pubDate>Tue, 24 Feb 2026 04:04:37 +0000</pubDate>
      <link>https://dev.to/pravin_kunnure_f4663a859a/flutter-clean-architecture-explained-simply-49b7</link>
      <guid>https://dev.to/pravin_kunnure_f4663a859a/flutter-clean-architecture-explained-simply-49b7</guid>
      <description>&lt;p&gt;Most Flutter apps start simple.&lt;/p&gt;

&lt;p&gt;A few screens.&lt;br&gt;
Some API calls.&lt;br&gt;
A bit of state management.&lt;/p&gt;

&lt;p&gt;Then features grow.&lt;/p&gt;

&lt;p&gt;And suddenly:&lt;/p&gt;

&lt;p&gt;Business logic is inside widgets&lt;/p&gt;

&lt;p&gt;API calls are everywhere&lt;/p&gt;

&lt;p&gt;Models are mixed with UI&lt;/p&gt;

&lt;p&gt;Refactoring becomes painful&lt;/p&gt;

&lt;p&gt;That’s where Clean Architecture helps.&lt;/p&gt;

&lt;p&gt;Let’s break it down in the simplest way possible.&lt;/p&gt;

&lt;p&gt;What Is Clean Architecture (In Simple Words)?&lt;/p&gt;

&lt;p&gt;Clean Architecture is about one thing:&lt;/p&gt;

&lt;p&gt;Separate your app into layers so each layer has one responsibility.&lt;/p&gt;

&lt;p&gt;It helps you:&lt;/p&gt;

&lt;p&gt;Write scalable code&lt;/p&gt;

&lt;p&gt;Test business logic easily&lt;/p&gt;

&lt;p&gt;Change backend without touching UI&lt;/p&gt;

&lt;p&gt;Avoid messy projects&lt;/p&gt;

&lt;p&gt;The 3 Main Layers (Simplified for Flutter)&lt;/p&gt;

&lt;p&gt;Forget complicated diagrams.&lt;br&gt;
For Flutter, think of just 3 layers:&lt;/p&gt;

&lt;p&gt;Presentation  →  Domain  →  Data&lt;/p&gt;

&lt;p&gt;Let’s understand each one.&lt;/p&gt;

&lt;p&gt;1️⃣ Presentation Layer (UI Layer)&lt;/p&gt;

&lt;p&gt;This is your Flutter world:&lt;/p&gt;

&lt;p&gt;Screens&lt;/p&gt;

&lt;p&gt;Widgets&lt;/p&gt;

&lt;p&gt;State management (Bloc / Riverpod / Provider)&lt;/p&gt;

&lt;p&gt;ViewModels&lt;/p&gt;

&lt;p&gt;What it does:&lt;/p&gt;

&lt;p&gt;Displays data&lt;/p&gt;

&lt;p&gt;Takes user input&lt;/p&gt;

&lt;p&gt;Calls use cases&lt;/p&gt;

&lt;p&gt;What it should NOT do:&lt;/p&gt;

&lt;p&gt;Call APIs directly&lt;/p&gt;

&lt;p&gt;Contain business rules&lt;/p&gt;

&lt;p&gt;Talk to database logic&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;context.read().login(email, password);&lt;/p&gt;

&lt;p&gt;UI doesn’t know how login works internally.&lt;br&gt;
 It just triggers it.&lt;/p&gt;

&lt;p&gt;2️⃣ Domain Layer (Business Logic)&lt;/p&gt;

&lt;p&gt;This is the heart of your app.&lt;/p&gt;

&lt;p&gt;It contains:&lt;/p&gt;

&lt;p&gt;Entities&lt;/p&gt;

&lt;p&gt;UseCases&lt;/p&gt;

&lt;p&gt;Repository interfaces&lt;/p&gt;

&lt;p&gt;This layer:&lt;/p&gt;

&lt;p&gt;Has NO Flutter imports&lt;/p&gt;

&lt;p&gt;Has NO API logic&lt;/p&gt;

&lt;p&gt;Has NO database logic&lt;/p&gt;

&lt;p&gt;It only contains pure business rules.&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;class LoginUseCase {&lt;br&gt;
  final AuthRepository repository;&lt;/p&gt;

&lt;p&gt;LoginUseCase(this.repository);&lt;/p&gt;

&lt;p&gt;Future call(String email, String password) {&lt;br&gt;
    return repository.login(email, password);&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;Notice:&lt;/p&gt;

&lt;p&gt;It depends on an abstract repository&lt;/p&gt;

&lt;p&gt;It doesn’t know where data comes from&lt;/p&gt;

&lt;p&gt;This makes it testable and clean.&lt;/p&gt;

&lt;p&gt;3️⃣ Data Layer (API &amp;amp; Database)&lt;/p&gt;

&lt;p&gt;This layer:&lt;/p&gt;

&lt;p&gt;Implements repositories&lt;/p&gt;

&lt;p&gt;Calls APIs&lt;/p&gt;

&lt;p&gt;Handles local storage&lt;/p&gt;

&lt;p&gt;Maps JSON to models&lt;/p&gt;

&lt;p&gt;Example:&lt;/p&gt;

&lt;p&gt;class AuthRepositoryImpl implements AuthRepository {&lt;br&gt;
  final AuthRemoteDataSource remote;&lt;/p&gt;

&lt;p&gt;AuthRepositoryImpl(this.remote);&lt;/p&gt;

&lt;p&gt;&lt;a class="mentioned-user" href="https://dev.to/override"&gt;@override&lt;/a&gt;&lt;br&gt;
  Future login(String email, String password) {&lt;br&gt;
    return remote.login(email, password);&lt;br&gt;
  }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;This is where Dio/http lives.&lt;/p&gt;

&lt;p&gt;Why This Structure Is Powerful&lt;/p&gt;

&lt;p&gt;✅ Easy to Test&lt;/p&gt;

&lt;p&gt;You can test UseCases without UI.&lt;/p&gt;

&lt;p&gt;✅ Backend Can Change Easily&lt;/p&gt;

&lt;p&gt;Switch from REST → GraphQL?&lt;br&gt;
 Only data layer changes.&lt;/p&gt;

&lt;p&gt;✅ Large Teams Work Better&lt;/p&gt;

&lt;p&gt;UI team works on presentation.&lt;br&gt;
 Backend integration team works on data layer.&lt;/p&gt;

&lt;p&gt;✅ Code Becomes Predictable&lt;/p&gt;

&lt;p&gt;Every feature follows the same structure.&lt;/p&gt;

&lt;p&gt;Suggested Folder Structure&lt;/p&gt;

&lt;p&gt;lib/&lt;br&gt;
 ├── features/&lt;br&gt;
 │    ├── auth/&lt;br&gt;
 │    │    ├── presentation/&lt;br&gt;
 │    │    ├── domain/&lt;br&gt;
 │    │    ├── data/&lt;/p&gt;

&lt;p&gt;Each feature is self-contained.&lt;/p&gt;

&lt;p&gt;This scales very well.&lt;/p&gt;

&lt;p&gt;Common Mistakes Developers Make&lt;/p&gt;

&lt;p&gt;❌ Putting API calls inside widgets&lt;br&gt;
 ❌ Mixing models between layers&lt;br&gt;
 ❌ Skipping repository interfaces&lt;br&gt;
 ❌ Using Clean Architecture for tiny apps (overengineering)&lt;/p&gt;

&lt;p&gt;When Should You Use Clean Architecture?&lt;/p&gt;

&lt;p&gt;Use it when:&lt;/p&gt;

&lt;p&gt;App will grow&lt;/p&gt;

&lt;p&gt;Multiple developers are working&lt;/p&gt;

&lt;p&gt;You want maintainable code&lt;/p&gt;

&lt;p&gt;You care about long-term scalability&lt;/p&gt;

&lt;p&gt;Avoid it for:&lt;/p&gt;

&lt;p&gt;Small MVPs&lt;/p&gt;

&lt;p&gt;Very short-term projects&lt;/p&gt;

&lt;p&gt;Final Thoughts&lt;/p&gt;

&lt;p&gt;Clean Architecture is not about writing more code.&lt;/p&gt;

&lt;p&gt;It’s about writing organized code.&lt;/p&gt;

&lt;p&gt;You don’t need 20 folders.&lt;br&gt;
 You just need:&lt;/p&gt;

&lt;p&gt;Clear boundaries&lt;/p&gt;

&lt;p&gt;Proper separation&lt;/p&gt;

&lt;p&gt;Discipline&lt;/p&gt;

&lt;p&gt;And once your app grows, you’ll be glad you structured it properly from day one.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>architecture</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>LIVO Next-Level Flutter State Management</title>
      <dc:creator>Pravin Kunnure</dc:creator>
      <pubDate>Mon, 23 Feb 2026 10:47:51 +0000</pubDate>
      <link>https://dev.to/pravin_kunnure_f4663a859a/livo-next-level-flutter-state-management-2mk2</link>
      <guid>https://dev.to/pravin_kunnure_f4663a859a/livo-next-level-flutter-state-management-2mk2</guid>
      <description>&lt;p&gt;Flutter is great, but managing state can quickly become messy. You’ve probably used setState for small projects or Provider, Riverpod, or BLoC for bigger apps—but each comes with trade-offs.&lt;/p&gt;

&lt;p&gt;⚠️**** Note: This story was originally about reactive_orm, which is now deprecated. Its evolution is now called LIVO. LIVO continues its reactive object-relationship state management approach with improved naming, documentation, and long-term support.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;. What is &lt;a href="https://pub.dev/packages/livo" rel="noopener noreferrer"&gt;LIVO&lt;/a&gt;?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enter &lt;a href="https://pub.dev/packages/livo" rel="noopener noreferrer"&gt;LIVO&lt;/a&gt;: a lightweight, reactive ORM-style state management library for Flutter.&lt;/p&gt;

&lt;p&gt;It lets your UI react automatically when model properties change — no streams, ChangeNotifier, or boilerplate required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;. With LIVO, you get:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object-wise and field-wise reactivity&lt;/li&gt;
&lt;li&gt;Nested and shared models&lt;/li&gt;
&lt;li&gt;Many → One and Many ↔ Many relationships&lt;/li&gt;
&lt;li&gt;Minimal boilerplate, plain Dart models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;. LIVO in action:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Object-wise: Update any field and rebuild the entire widget&lt;/li&gt;
&lt;li&gt;Field-wise: Only rebuild widgets for selected fields&lt;/li&gt;
&lt;li&gt;Many → One: Multiple models feeding a single observer&lt;/li&gt;
&lt;li&gt;Many ↔ Many: Shared models reflected across multiple parents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;. Getting Started:&lt;/strong&gt;&lt;br&gt;
Add LIVO to your project:&lt;br&gt;
dependencies:&lt;br&gt;
 &lt;em&gt;livo: &lt;/em&gt;&lt;/p&gt;

&lt;p&gt;1️⃣ Creating a Reactive Model&lt;/p&gt;

&lt;p&gt;_import 'package:livo/livo.dart';&lt;/p&gt;

&lt;p&gt;class Task extends ReactiveModel {&lt;br&gt;
 String _title;&lt;br&gt;
 bool _completed = false;&lt;br&gt;
 String _status = "Idle";&lt;/p&gt;

&lt;p&gt;Task({required String title}) : _title = title;&lt;/p&gt;

&lt;p&gt;String get title =&amp;gt; _title;&lt;br&gt;
 set title(String value) {&lt;br&gt;
 if (_title != value) {&lt;br&gt;
 _title = value;&lt;br&gt;
 notifyListeners(#title); // ✅ Symbol-based&lt;br&gt;
 }&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;bool get completed =&amp;gt; _completed;&lt;br&gt;
 set completed(bool value) {&lt;br&gt;
 if (_completed != value) {&lt;br&gt;
 _completed = value;&lt;br&gt;
 notifyListeners(#completed);&lt;br&gt;
 }&lt;br&gt;
 }&lt;/p&gt;

&lt;p&gt;String get status =&amp;gt; &lt;em&gt;status;&lt;br&gt;
 set status(String value) {&lt;br&gt;
 if (_status != value) {&lt;br&gt;
 _status = value;&lt;br&gt;
 notifyListeners(#status);&lt;br&gt;
 }&lt;br&gt;
 }&lt;br&gt;
}&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;✅ This is just plain Dart. &lt;a href="https://pub.dev/packages/livo" rel="noopener noreferrer"&gt;LIVO&lt;/a&gt; will handle notifying widgets when fields change.&lt;/p&gt;

&lt;p&gt;2️⃣ Object-wise Reactivity&lt;/p&gt;

&lt;p&gt;_final objectWise = Task(title: "Object-wise Reactivity");&lt;/p&gt;

&lt;p&gt;ReactiveBuilder(&lt;br&gt;
 model: objectWise,&lt;br&gt;
 builder: (task) {&lt;br&gt;
 return ListTile(&lt;br&gt;
 title: Text(task.title),&lt;br&gt;
 subtitle: Text(task.status),&lt;br&gt;
 trailing: Checkbox(&lt;br&gt;
 value: task.completed,&lt;br&gt;
 onChanged: (v) =&amp;gt; task.completed = v!,&lt;br&gt;
 ),&lt;br&gt;
 );&lt;br&gt;
 },&lt;br&gt;
);_&lt;/p&gt;

&lt;p&gt;Here, checking the checkbox triggers a rebuild of the entire widget.&lt;/p&gt;

&lt;p&gt;3️⃣ Field-wise Reactivity (Optimized)&lt;/p&gt;

&lt;p&gt;Sometimes, you only want specific fields to trigger a rebuild:&lt;/p&gt;

&lt;p&gt;_final fieldWise = Task(title: "Field-wise Reactivity");&lt;/p&gt;

&lt;p&gt;ReactiveBuilder(&lt;br&gt;
 model: fieldWise,&lt;br&gt;
 fields: [#completed, #status],&lt;br&gt;
 builder: (task) {&lt;br&gt;
 return ListTile(&lt;br&gt;
 title: Text(task.title),&lt;br&gt;
 subtitle: Text(task.status),&lt;br&gt;
 trailing: Checkbox(&lt;br&gt;
 value: task.completed,&lt;br&gt;
 onChanged: (v) =&amp;gt; task.completed = v!,&lt;br&gt;
 ),&lt;br&gt;
 );&lt;br&gt;
 },&lt;br&gt;
)&lt;br&gt;
_&lt;br&gt;
✅ Only changes to completed or status rebuild the widget. Other fields are ignored.&lt;/p&gt;

&lt;p&gt;4️⃣ Many → One (Aggregation)&lt;/p&gt;

&lt;p&gt;Combine multiple models into a single reactive observer:&lt;/p&gt;

&lt;p&gt;_class Dashboard extends ReactiveModel {&lt;br&gt;
 final List sources;&lt;/p&gt;

&lt;p&gt;Dashboard(this.sources) {&lt;br&gt;
 for (final task in sources) {&lt;br&gt;
 addNested(task); // listen to many&lt;br&gt;
 }&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;final manyA = Task(title: "Task A");&lt;br&gt;
final manyB = Task(title: "Task B");&lt;br&gt;
final dashboard = Dashboard([manyA, manyB]);&lt;/p&gt;

&lt;p&gt;ReactiveBuilder(&lt;br&gt;
 model: dashboard,&lt;br&gt;
 builder: (&lt;em&gt;) =&amp;gt; Column(&lt;br&gt;
 children: [&lt;br&gt;
 Text("A: ${manyA.completed}"),&lt;br&gt;
 Text("B: ${manyB.completed}"),&lt;br&gt;
 ],&lt;br&gt;
 ),&lt;br&gt;
);&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Updating manyA or manyB automatically rebuilds the dashboard widget.&lt;/p&gt;

&lt;p&gt;5️⃣ Many ↔ Many (Shared Models)&lt;/p&gt;

&lt;p&gt;Models can be shared across multiple parents, keeping the UI in sync everywhere:&lt;/p&gt;

&lt;p&gt;_class Group extends ReactiveModel {&lt;br&gt;
 final String name;&lt;br&gt;
 final List tasks;&lt;/p&gt;

&lt;p&gt;Group({required this.name, required this.tasks}) {&lt;br&gt;
 for (final task in tasks) addNested(task);&lt;br&gt;
 }&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;final group1 = Group(name: "Group 1", tasks: [objectWise, fieldWise]);&lt;br&gt;
final group2 = Group(name: "Group 2", tasks: [fieldWise, manyA]);&lt;/p&gt;

&lt;p&gt;ReactiveBuilder(&lt;br&gt;
 model: group1,&lt;br&gt;
 builder: (g) =&amp;gt; Column(&lt;br&gt;
 children: g.tasks.map((t) =&amp;gt; Text("• ${t.title} → ${t.completed}")).toList(),&lt;br&gt;
 ),&lt;br&gt;
);&lt;br&gt;
_&lt;br&gt;
✅ Updating a task reflects automatically across all groups that include it.&lt;br&gt;
🔹 How LIVO Works&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Models extend ReactiveModel&lt;/li&gt;
&lt;li&gt;Field setters call notifyListeners(#field) whenever a value changes&lt;/li&gt;
&lt;li&gt;ReactiveBuilder widgets listen to either the whole object or   specific fields&lt;/li&gt;
&lt;li&gt;Nested models propagate changes upward automatically&lt;/li&gt;
&lt;li&gt;No streams. No manual wiring. Everything updates safely and efficiently.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔹 Why LIVO&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clean Dart models with minimal boilerplate&lt;/li&gt;
&lt;li&gt;Fine-grained reactivity for optimized performance&lt;/li&gt;
&lt;li&gt;ORM-style mental model for easier app design&lt;/li&gt;
&lt;li&gt;Works seamlessly for single fields, nested models, or shared models&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;🔗 Links&lt;/p&gt;

&lt;p&gt;Pub Package: &lt;a href="https://pub.dev/packages/livo" rel="noopener noreferrer"&gt;LIVO&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/PravinKunnure/livo" rel="noopener noreferrer"&gt;GitHub Repository&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;💡 Tip for Readers&lt;br&gt;
 Start small: use object-wise for quick prototyping. As your app grows, switch to field-wise or nested models for efficiency.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://pub.dev/packages/livo" rel="noopener noreferrer"&gt;LIVO&lt;/a&gt; makes Flutter state management intuitive and fun — without sacrificing performance.&lt;/p&gt;

</description>
      <category>flutter</category>
      <category>dart</category>
      <category>opensource</category>
      <category>statemanagement</category>
    </item>
  </channel>
</rss>
