{"id":24295394,"url":"https://github.com/phmatray/ducky","last_synced_at":"2026-03-05T00:26:40.833Z","repository":{"id":270207020,"uuid":"822422607","full_name":"phmatray/Ducky","owner":"phmatray","description":"Ducky is a state management library designed for Blazor applications, inspired by the Redux pattern commonly used in JavaScript applications. It provides a predictable state container for .NET, ensuring that the application state is managed in a clear, consistent, and centralized manner.","archived":false,"fork":false,"pushed_at":"2026-02-27T14:49:35.000Z","size":7849,"stargazers_count":2,"open_issues_count":7,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-27T18:04:50.537Z","etag":null,"topics":["blazor","blazor-components","csharp","dotnet","dotnet-library","flux","ngrx","nuget","redux","state-management"],"latest_commit_sha":null,"homepage":"https://phmatray.github.io/Ducky/","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/phmatray.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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}},"created_at":"2024-07-01T06:04:57.000Z","updated_at":"2026-02-27T14:48:27.000Z","dependencies_parsed_at":"2025-04-17T17:06:00.746Z","dependency_job_id":"a5aaca90-8bef-4d3c-a844-61efe0aaed96","html_url":"https://github.com/phmatray/Ducky","commit_stats":null,"previous_names":["phmatray/ducky","phmatray/r3dux"],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/phmatray/Ducky","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phmatray%2FDucky","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phmatray%2FDucky/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phmatray%2FDucky/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phmatray%2FDucky/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/phmatray","download_url":"https://codeload.github.com/phmatray/Ducky/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/phmatray%2FDucky/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29973320,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-01T15:29:09.406Z","status":"ssl_error","status_checked_at":"2026-03-01T15:28:28.558Z","response_time":124,"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":["blazor","blazor-components","csharp","dotnet","dotnet-library","flux","ngrx","nuget","redux","state-management"],"created_at":"2025-01-16T18:49:30.371Z","updated_at":"2026-03-01T15:34:00.609Z","avatar_url":"https://github.com/phmatray.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Ducky 🦆\n\nA Predictable State Management Library for Blazor\n\n| ![Logo MasterCommander](https://raw.githubusercontent.com/phmatray/Ducky/main/logo.png) | Ducky is a state management library designed for Blazor applications, inspired by the Redux pattern commonly used in JavaScript applications. It provides a predictable state container for .NET, ensuring that the application state is managed in a clear, consistent, and centralized manner. |\n|-----------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n\n[![phmatray - Ducky](https://img.shields.io/static/v1?label=phmatray\u0026message=Ducky\u0026color=blue\u0026logo=github)](https://github.com/phmatray/Ducky \"Go to GitHub repo\")\n[![License: Apache-2.0](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n[![stars - Ducky](https://img.shields.io/github/stars/phmatray/Ducky?style=social)](https://github.com/phmatray/Ducky)\n[![forks - Ducky](https://img.shields.io/github/forks/phmatray/Ducky?style=social)](https://github.com/phmatray/Ducky)\n\n[![GitHub tag](https://img.shields.io/github/tag/phmatray/Ducky?include_prereleases=\u0026sort=semver\u0026color=blue)](https://github.com/phmatray/Ducky/releases/)\n[![issues - Ducky](https://img.shields.io/github/issues/phmatray/Ducky)](https://github.com/phmatray/Ducky/issues)\n[![GitHub pull requests](https://img.shields.io/github/issues-pr/phmatray/Ducky)](https://github.com/phmatray/Ducky/pulls)\n[![GitHub contributors](https://img.shields.io/github/contributors/phmatray/Ducky)](https://github.com/phmatray/Ducky/graphs/contributors)\n[![GitHub last commit](https://img.shields.io/github/last-commit/phmatray/Ducky)](https://github.com/phmatray/Ducky/commits/master)\n\n---\n\n## 📝 Table of Contents\n\n\u003c!-- TOC --\u003e\n* [Ducky 🦆](#ducky-)\n  * [📝 Table of Contents](#-table-of-contents)\n  * [📊 Stats](#-stats)\n  * [📝 Summary](#-summary)\n  * [📌 Features](#-features)\n    * [How Ducky Works](#how-ducky-works)\n    * [The Counter Example](#the-counter-example)\n  * [✨ Contributors](#-contributors)\n  * [❓ Issues and Feature Requests](#-issues-and-feature-requests)\n  * [✉️ Contact](#-contact)\n  * [📜 License](#-license)\n\u003c!-- TOC --\u003e\n\n## 📊 Stats\n\n![Alt](https://repobeats.axiom.co/api/embed/5c487f344d133cd5bb071285ba32b37a993cb6e0.svg \"Repobeats analytics image\")\n\n## 📝 Summary\n\nDucky simplifies state management in Blazor applications by providing a structured and predictable way to handle state changes, inspired by the Redux pattern. It promotes best practices such as immutability, single source of truth, and clear separation of concerns, making it easier to manage complex application states.\n\n## 🚀 How to Install\n\nTo install Ducky, you can use the following command:\n\n```bash\ndotnet add package Ducky\ndotnet add package Ducky.Blazor\n```\n\nAlternatively, you can install the packages using the NuGet Package Manager in Visual Studio.\n\n\n## 📌 Features\n\n1. **Predictable State Management**: By following the principles of Redux, Ducky ensures that the application state is predictable. Every state change is described by an action and handled by a reducer, which returns a new state.\n2. **Single Source of Truth**: The entire state of the application is stored in a single state tree, which makes debugging and state inspection easier.\n3. **Immutability**: Ducky enforces immutability in state changes. Instead of mutating the existing state, reducers return a new state object, ensuring the integrity of the state over time.\n4. **Actions and Reducers**: Actions describe the changes in the application, and reducers specify how the application's state changes in response to actions.\n5. **Middleware and Effects**: Middleware allows for intercepting actions before they reach the reducer, enabling tasks such as logging, analytics, and asynchronous operations. Effects handle side effects like data fetching and other asynchronous tasks.\n6. **Selectors**: Selectors are used to query the state in a performant manner. Memoized selectors help in reducing unnecessary recomputations, thus optimizing performance.\n7. **Integration with Blazor**: Ducky is tailored for Blazor applications, integrating seamlessly with Blazor's component-based architecture.\n\n### How Ducky Works\n\n1. **State**: The application's state is represented by a single immutable object.\n2. **Actions**: Actions are plain objects that describe what happened in the application.\n3. **Reducers**: Reducers are pure functions that take the current state and an action, and return a new state.\n4. **Dispatch**: The `dispatch` function sends an action to the store, which then forwards it to the reducer to compute the new state.\n5. **Selectors**: Selectors are functions that select a piece of the state. Memoized selectors cache the results of state queries to improve performance.\n\n### The Counter Example\n\nHere is a simple example of how Ducky might be used in a Blazor application to manage a counter's state:\n\n```csharp\nnamespace Demo.AppStore\n{\n    // State\n    public record CounterState\n    {\n        public int Count { get; init; }\n    }\n\n    // Actions\n    public record Increment(int Amount = 1);\n    public record Decrement(int Amount = 1);\n    public record Reset;\n\n    // Reducers\n    public record CounterReducers : SliceReducers\u003cCounterState\u003e\n    {\n        public CounterReducers()\n        {\n            On\u003cIncrement\u003e((state, action) =\u003e state with { Count = state.Count + action.Amount });\n            On\u003cDecrement\u003e((state, action) =\u003e state with { Count = state.Count - action.Amount });\n            On\u003cReset\u003e(_ =\u003e GetInitialState());\n        }\n\n        public override CounterState GetInitialState()\n        {\n            return new CounterState { Count = 0 };\n        }\n    }\n\n    // Component\n    @page \"/counter\"\n    @inherits DuckyComponent\u003cCounterState\u003e\n\n    \u003cdiv\u003e\n        \u003cp\u003eCurrent count: @State.Count\u003c/p\u003e\n        \u003cbutton @onclick=\"IncrementCount\"\u003eIncrement\u003c/button\u003e\n        \u003cbutton @onclick=\"DecrementCount\"\u003eDecrement\u003c/button\u003e\n        \u003cbutton @onclick=\"ResetCount\"\u003eReset\u003c/button\u003e\n    \u003c/div\u003e\n\n    @code {\n        private void IncrementCount() =\u003e Dispatch(new Increment());\n        private void DecrementCount() =\u003e Dispatch(new Decrement());\n        private void ResetCount() =\u003e Dispatch(new Reset());\n    }\n}\n```\n\n## ✨ Contributors\n\n[![Contributors](https://contrib.rocks/image?repo=phmatray/Ducky)](http://contrib.rocks)\n\n## ❓ Issues and Feature Requests\n\nFor reporting bugs or suggesting new features, kindly submit these as an issue to\nthe [Ducky Repository](https://github.com/phmatray/Ducky/issues). We value your contributions, but\nbefore submitting an issue, please ensure it is not a duplicate of an existing one.\n\n## ✉️ Contact\n\nYou can contact us by opening an issue on this repository.\n\n## 📜 License\n\nApache-2.0 License\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphmatray%2Fducky","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphmatray%2Fducky","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphmatray%2Fducky/lists"}