{"id":25590668,"url":"https://github.com/majlindavdylaj/lindi","last_synced_at":"2026-05-08T07:35:01.920Z","repository":{"id":274624860,"uuid":"923549018","full_name":"majlindavdylaj/lindi","owner":"majlindavdylaj","description":"Lindi is a lightweight and reactive state management library for Flutter that simplifies building applications with dynamic UI updates.","archived":false,"fork":false,"pushed_at":"2025-11-04T15:24:03.000Z","size":329,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-11T07:03:30.261Z","etag":null,"topics":["dart","dartlang","flutter","flutter-package","library","lindi","state-management"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/lindi","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/majlindavdylaj.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":null,"patreon":"koddev","open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"custom":null}},"created_at":"2025-01-28T12:58:54.000Z","updated_at":"2025-11-04T15:24:08.000Z","dependencies_parsed_at":null,"dependency_job_id":"c3b72fe4-c2ce-4daa-975c-789dbc872de1","html_url":"https://github.com/majlindavdylaj/lindi","commit_stats":null,"previous_names":["majlindavdylaj/lindi"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/majlindavdylaj/lindi","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majlindavdylaj%2Flindi","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majlindavdylaj%2Flindi/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majlindavdylaj%2Flindi/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majlindavdylaj%2Flindi/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/majlindavdylaj","download_url":"https://codeload.github.com/majlindavdylaj/lindi/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/majlindavdylaj%2Flindi/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32201871,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-23T20:19:26.138Z","status":"ssl_error","status_checked_at":"2026-04-23T20:19:23.520Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dart","dartlang","flutter","flutter-package","library","lindi","state-management"],"created_at":"2025-02-21T09:22:52.047Z","updated_at":"2026-05-08T07:35:01.874Z","avatar_url":"https://github.com/majlindavdylaj.png","language":"C++","funding_links":["https://patreon.com/koddev"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\t\u003ca href=\"https://pub.dartlang.org/packages/lindi\"\u003e\u003cimg src=\"https://img.shields.io/pub/v/lindi?color=blue\" alt=\"Pub dev\"\u003e\u003c/a\u003e\n\t\u003ca href=\"https://github.com/majlindavdylaj/lindi/actions\"\u003e\u003cimg src=\"https://github.com/majlindavdylaj/lindi/workflows/Build/badge.svg\" alt=\"Build Status\"\u003e\u003c/a\u003e\n\t\u003ca href=\"https://discord.gg/CYMhKYht\"\u003e\u003cimg src=\"https://img.shields.io/discord/1347558525962027009?logo=discord\u0026color=blue\" alt=\"Discord\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\n# Lindi\n\nLindi is a lightweight and reactive state management library for Flutter that simplifies building applications with dynamic UI updates. It enables developers to manage state using `LindiViewModel` and provides powerful widgets like `LindiBuilder` to listen and react to changes in state.\n\n## Features\n\n- Easy state management with `LindiViewModel`.\n- Reactivity using `LindiBuilder` for single and multiple states.\n- Global dependency injection.\n- Lightweight, intuitive, and easy to integrate.\n\n---\n\n## Installation\n\nAdd Lindi to your Flutter project by including it in your `pubspec.yaml`:\n\n```yaml\ndependencies:\n  lindi: latest_version\n```\n\nThen run:\n\n```bash\nflutter pub get\n```\n\n---\n\n## Getting Started\n\n### Setup `Lindi`\n\n```dart\nFuture\u003cvoid\u003e main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await Lindi.init();\n  runApp(App());\n}\n```\n\n### 1. Define a `LindiViewModel`\n\nCreate a class that extends `LindiViewModel` to manage your state:\n\n```dart\nclass CounterLindiViewModel extends LindiViewModel {\n  int counter = 0;\n\n  void increment() {\n    counter++;\n    notify();\n  }\n\n  void decrement() {\n    counter--;\n    notify();\n  }\n}\n```\n\nCreate a class that extends `LindiViewModel\u003cD, E\u003e` to manage your state:\n\n```dart\nclass ApiLindiViewModel extends LindiViewModel\u003cString, String\u003e {\n\n  void fetchData() async {\n    setLoading();\n    await Future.delayed(Duration(seconds: 4));\n    setData('Fetched');\n    await Future.delayed(Duration(seconds: 3));\n    setError('Timeout!');\n  }\n}\n```\n\nCreate a class that extends `LindiStorageViewModel\u003cD, E\u003e` to save your state in storage:\n\n```dart\nclass StorageViewModel extends LindiStorageViewModel\u003cint?, String\u003e {\n  void increment() {\n    setData((data ?? 0) + 1);\n  }\n\n  void decrement() {\n    setData((data ?? 0) - 1);\n  }\n\n  @override\n  int? fromJson(Map\u003cString, dynamic\u003e json) {\n    return json['data'];\n  }\n\n  @override\n  Map\u003cString, dynamic\u003e toJson(int? d) {\n    return {\"data\": d};\n  }\n}\n```\n\n- `ApiLindiViewModel` inherits from `LindiViewModel\u003cString, String\u003e`, where:\n  - `\u003cD\u003e` represents the data type (in this case, API response data as `String`).\n  - `\u003cE\u003e` represents the error type (in this case, error as `String`).\n\n### 2. Register Your `LindiViewModel`\n\nUse injector to make the `LindiViewModel` accessible globally:\n\n```dart\nLindi.inject([CounterLindiViewModel(), ApiLindiViewModel()]);\n```\n\n### 3. Use `LindiBuilder`\n\nReact to changes in a single `LindiViewModel` with `LindiBuilder`:\n\n```dart\nclass CounterScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    final counterViewModel = Lindi.get\u003cCounterLindiViewModel\u003e();\n\n    return Scaffold(\n      body: Center(\n        child: LindiBuilder(\n          viewModels: [counterViewModel],\n          builder: (context) {\n            return Text(\n              'Counter: ${counterViewModel.counter}',\n              style: const TextStyle(fontSize: 24),\n            );\n          },\n        ),\n      ),\n      floatingActionButton: FloatingActionButton(\n        onPressed: counterViewModel.increment,\n        child: const Icon(Icons.add),\n      ),\n    );\n  }\n}\n```\n\nReact to changes in a single `LindiViewModel\u003cD, E\u003e` with `LindiBuilder`:\n\n```dart\nclass ApiScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    final apiViewModel = Lindi.get\u003cApiLindiViewModel\u003e();\n\n    return Scaffold(\n      body: Center(\n        child: LindiBuilder(\n          viewModels: [apiViewModel],\n          builder: (context) {\n            if(apiViewModel.isLoading){\n              return CircularProgressIndicator();\n            }\n            if(apiViewModel.hasError){\n              return Text(apiViewModel.error!);\n            }\n            return Text(apiViewModel.data!);\n          },\n        ),\n      ),\n    );\n  }\n}\n```\n\n### 4. Use `LindiBuilder`\n\nListen to multiple `LindiViewModel` instances simultaneously:\n\n```dart\nclass ThemeLindiViewModel extends LindiViewModel {\n  bool isDarkMode = false;\n\n  void toggleTheme() {\n    isDarkMode = !isDarkMode;\n    notify();\n  }\n}\n\nclass MultiExampleScreen extends StatelessWidget {\n  @override\n  Widget build(BuildContext context) {\n    final counterViewModel = Lindi.get\u003cCounterLindiViewModel\u003e();\n    final themeViewModel = Lindi.get\u003cThemeLindiViewModel\u003e();\n\n    return Scaffold(\n      body: LindiBuilder(\n        viewModels: [counterViewModel, themeViewModel],\n        listener: (context, viewModel) {\n          if (viewModel is ThemeLindiViewModel) {\n            if(themeViewModel.isDarkMode){\n              debugPrint('Theme changed to dark mode');\n            } else {\n              debugPrint('Theme changed to light mode');\n            }\n          }\n        },\n        builder: (context) {\n          return Center(\n            child: Column(\n              mainAxisAlignment: MainAxisAlignment.center,\n              children: [\n                Text(\n                  'Counter: ${counterViewModel.counter}',\n                  style: const TextStyle(fontSize: 24),\n                ),\n                const SizedBox(height: 20),\n                ElevatedButton(\n                  onPressed: counterViewModel.increment,\n                  child: const Text('Increment Counter'),\n                ),\n                const SizedBox(height: 40),\n                Text(\n                  'Current Theme: ${themeViewModel.isDarkMode ? \"Dark\" : \"Light\"}',\n                  style: const TextStyle(fontSize: 18),\n                ),\n                const SizedBox(height: 20),\n                IconButton(\n                  icon: Icon(\n                    themeViewModel.isDarkMode ? Icons.dark_mode : Icons.light_mode,\n                  ),\n                  onPressed: themeViewModel.toggleTheme,\n                ),\n              ],\n            ),\n          );\n        },\n      ),\n    );\n  }\n}\n```\n\n---\n\n## API Reference\n\n### `LindiViewModel`\n\n- Extend this class to define your state management logic.\n- Call `notify()` to update listeners when state changes.\n- Call `setLoading()` to mark the LindiViewModel as loading and reset any previous error.\n- Call `setData(D data)` to update the LindiViewModel with new data and stops loading.\n- Call `setError(E error)` to store an error.\n\n### `LindiBuilder`\n\n- Parameters:\n  - `viewModels`: A list of `LindiViewModel` objects to listen to.\n  - `listener`: A callback function that listens when the `viewModel` updates.\n  - `builder`: A function that rebuilds the UI with the updated state.\n\n### `Lindi`\n\n- Methods:\n  - `inject(List\u003cLindiViewModel\u003e instances)`: Inject a list of `LindiViewModel` instances.\n  - `T get\u003cT extends LindiViewModel\u003e()`: Retrieves an injected `LindiViewModel` instance.\n\n---\n\n## Example Project\n\nFor a complete example, check out the [example folder](https://github.com/majlindavdylaj/lindi/tree/main/example) in the repository.\n\n---\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n---\n\n## Contributing\n\nWe welcome contributions! Feel free to submit issues or pull requests to improve Lindi.\n\n---\n\nHappy coding with **Lindi**! 🚀\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmajlindavdylaj%2Flindi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmajlindavdylaj%2Flindi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmajlindavdylaj%2Flindi/lists"}