{"id":14978443,"url":"https://github.com/goosewobbler/zutron","last_synced_at":"2025-03-15T19:12:44.269Z","repository":{"id":231885849,"uuid":"776766412","full_name":"goosewobbler/zutron","owner":"goosewobbler","description":"Streamlined Electron State Management","archived":false,"fork":false,"pushed_at":"2025-02-17T16:12:04.000Z","size":379650,"stargazers_count":42,"open_issues_count":4,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-02-24T06:03:08.353Z","etag":null,"topics":["electron","electronjs","state-management","zustand"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/goosewobbler.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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}},"created_at":"2024-03-24T12:39:54.000Z","updated_at":"2025-02-23T13:32:00.000Z","dependencies_parsed_at":"2024-11-20T18:19:05.312Z","dependency_job_id":"69f3f2dc-8d18-41a7-aae3-1750c597fada","html_url":"https://github.com/goosewobbler/zutron","commit_stats":{"total_commits":202,"total_committers":4,"mean_commits":50.5,"dds":"0.12871287128712872","last_synced_commit":"ad388ff5bf30c4b5aaf6b54f890cd8b6be728881"},"previous_names":["goosewobbler/zutron"],"tags_count":23,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goosewobbler%2Fzutron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goosewobbler%2Fzutron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goosewobbler%2Fzutron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/goosewobbler%2Fzutron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/goosewobbler","download_url":"https://codeload.github.com/goosewobbler/zutron/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":241616700,"owners_count":19991543,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["electron","electronjs","state-management","zustand"],"created_at":"2024-09-24T13:57:38.396Z","updated_at":"2025-03-15T19:12:44.245Z","avatar_url":"https://github.com/goosewobbler.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ⚠️ DEPRECATED\n\nThis project is no longer maintained. Please use [@zubridge/electron](https://github.com/goosewobbler/zubridge) instead, which is the direct successor to Zutron.\n\n## Migration\n\nMigrating to `@zubridge/electron` is straightforward as the API has not changed:\n\n```bash\npnpm uninstall zutron\npnpm install @zubridge/electron\n```\n\nThen update your imports from `zutron` to `@zubridge/electron`.\n\n---\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./resources/zutron-readme-hero-dark.png\"/\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./resources/zutron-readme-hero-light.png\"/\u003e\n  \u003cimg alt=\"reduxtron hero image\" src=\"./resources/zutron-readme-hero-light.png\"/\u003e\n\u003c/picture\u003e\n\n_streamlined electron state management_\n\n\u003ca href=\"https://www.npmjs.com/package/zutron\" alt=\"NPM Version\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/v/zutron\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://www.npmjs.com/package/zutron\" alt=\"NPM Downloads\"\u003e\n  \u003cimg src=\"https://img.shields.io/npm/dw/zutron\" /\u003e\u003c/a\u003e\n\n### Why\n\n\u003e tldr: I want to use Zustand in my Electron app, seamlessly\n\n[Zustand](https://github.com/pmndrs/zustand) is a great state management library. As with other state libraries [such as Redux](https://redux.js.org/tutorials/fundamentals/part-4-store#redux-store), it is [recommended](https://zustand.docs.pmnd.rs/guides/flux-inspired-practice#recommended-patterns) that a single store is used in your app.\n\nFor Electron apps this is an awkward problem as you need access to the store in both the main and renderer processes.\n\nZutron enables a single store workflow with Zustand in Electron apps, effectively simplifying the use of Zustand in this context by abstracting away the necessary IPC and dispatch management.\n\n### Features\n\n- Use Zustand everywhere in your Electron app\n- Single store workflow across the IPC boundary\n- Works with the latest [Electron security recommendations](https://www.electronjs.org/docs/latest/tutorial/security#checklist-security-recommendations)\n- Supports `BrowserWindow`, `BrowserView` and `WebContentsView`\n- Integrates with windows and views created at runtime\n- Compatible with the main Zustand usage patterns\n- Handles thunks, inline actions or Redux-style action objects\n\n### How It Works\n\nBehind the scenes, Zutron creates an additional Zustand store in each renderer process. These stores are synchronized in one direction with your application store in the main process.\n\n\u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"./resources/zutron-app-architecture-dark.png\"/\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"./resources/zutron-app-architecture-light.png\"/\u003e\n  \u003cimg alt=\"reduxtron hero image\" src=\"./resources/zutron-app-architecture-light.png\"/\u003e\n\u003c/picture\u003e\n\nActions from the renderer process(es) are dispatched across IPC to the main process store, which handles them and updates the application state accordingly. Internally, the Zutron renderer process store(s) receive these state updates over IPC and update themselves accordingly.\n\n#### Accessing Your Application Store\n\n- Renderer process\n  - Application state can be accessed via the Zutron `useStore` hook\n  - Actions \u0026 thunks can be dispatched via the Zutron `useDispatch` hook\n- Main process\n  - Application state can be accessed directly in the [same way you normally use a vanilla Zustand store](https://github.com/pmndrs/zustand/blob/5d92ad2767e6a13d94331b5b62a44c069df2dfc6/readme.md#using-zustand-without-react):\n    - Either using the Zustand vanilla API utilities: `getState`, `setState`, `subscribe`, `getInitialState`\n    - Or via the Zustand `useStore` hook\n  - Actions \u0026 thunks can be dispatched via the Zutron `dispatch` helper\n\n### Getting Started\n\nSee the [docs](./docs/getting-started.md).\n\nThere are minimal example applications featuring three different Zustand usage patterns:\n\n- [Redux-style reducers](./apps/example-reducers)\n- [Separate handlers](./apps/example-separate-handlers)\n- [Store-based handlers](./apps/example-store-handlers)\n\n### Inspiration / Prior Art\n\nThis project would not exist without Reduxtron, shout out to vitordino for creating it!\n\n- [vitordino/reduxtron](https://github.com/vitordino/reduxtron)\n\n  - Redux store in the main process, optionally synced to Zustand in the renderer\n  - Zutron is based on Reduxtron\n  - Great for Redux users, not an option if you want to use Zustand everywhere\n\n- [klarna/electron-redux](https://github.com/klarna/electron-redux)\n  - Bi-directional sync between one Redux store in the main process, and another in the renderer\n  - No longer maintained\n  - I created [a fork](https://github.com/goosewobbler/electron-redux) to enable support for [electron \u003e= 14](https://github.com/klarna/electron-redux/issues/317), however I won't be spending any more time on this approach\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoosewobbler%2Fzutron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgoosewobbler%2Fzutron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgoosewobbler%2Fzutron/lists"}