{"id":23840298,"url":"https://github.com/oleystack/event","last_synced_at":"2025-09-07T16:33:31.823Z","repository":{"id":40387758,"uuid":"477123315","full_name":"oleystack/event","owner":"oleystack","description":"💫 Tiny and powerful hook-based event system for React","archived":false,"fork":false,"pushed_at":"2023-03-15T10:02:08.000Z","size":3343,"stargazers_count":26,"open_issues_count":3,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-16T05:27:06.547Z","etag":null,"topics":["event","events","hook","hooks","react","react-hooks","react-native","typescript","typescript-library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@bit-about/event","language":"TypeScript","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/oleystack.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["Gareneye"]}},"created_at":"2022-04-02T17:22:00.000Z","updated_at":"2024-04-11T12:38:18.000Z","dependencies_parsed_at":"2023-07-19T08:00:46.349Z","dependency_job_id":null,"html_url":"https://github.com/oleystack/event","commit_stats":null,"previous_names":["bit-about/event","oleyz/event","oleystack/event"],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/oleystack/event","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleystack%2Fevent","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleystack%2Fevent/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleystack%2Fevent/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleystack%2Fevent/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/oleystack","download_url":"https://codeload.github.com/oleystack/event/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/oleystack%2Fevent/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274064383,"owners_count":25216310,"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","status":"online","status_checked_at":"2025-09-07T02:00:09.463Z","response_time":67,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["event","events","hook","hooks","react","react-hooks","react-native","typescript","typescript-library"],"created_at":"2025-01-02T17:31:04.622Z","updated_at":"2025-09-07T16:33:31.447Z","avatar_url":"https://github.com/oleystack.png","language":"TypeScript","funding_links":["https://github.com/sponsors/Gareneye","https://github.com/sponsors/macoley"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n\u003cimg alt=\"BitAboutEvent 💫 Tiny and powerful hook-based event system for React. 100% Idiomatic React.\" src=\"https://user-images.githubusercontent.com/1496580/162749593-7b98f01b-8fed-4669-8617-a41b0fca004c.png\" /\u003e\n\u003cbr /\u003e\u003cbr /\u003e\n\u003ca href=\"https://www.npmjs.com/package/@bit-about/event\"\u003e\u003cimg alt=\"\" src=\"https://img.shields.io/npm/v/@bit-about/event.svg\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://bundlephobia.com/package/@bit-about/event\"\u003e\u003cimg alt=\"Bundle size\" src=\"https://img.shields.io/bundlephobia/minzip/@bit-about/event?label=size\" /\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/bit-about/event\"\u003e\u003cimg alt=\"\" src=\"https://img.shields.io/codecov/c/github/bit-about/event?token=ZBD02VKG6J\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## Install\n\n```bash\nnpm i @bit-about/event\n```\n\n## Migrations\n\u003cdetails\u003e\n  \u003csummary\u003ev1 -\u003e v2\u003c/summary\u003e\n  \n  \u003e Events dispatch approach has been changed. There are no longer functions executed using their names in string.\n  \u003e\n  \u003e ✖️ old one:\n  \u003e ```jsx\n  \u003e const dispatch = useEvent()\n  \u003e dispatch('onBobPress', 'hello') \n  \u003e ```\n  \u003e ✅ new one:\n  \u003e ```jsx\n  \u003e const { onBobPress } = useEvent()\n  \u003e onBobPress('hello')\n  \u003e ```\n\u003c/details\u003e\n\n\n\n## Features\n\n- 100% **Idiomatic React**\n- 100% Typescript with event types deduction\n- Listen or dispatch events from a hook...\n- ...or utilise static access\n- No centralized event provider\n- Tiny - only **0.6kB**\n- **Just works** ™\n\n### ➡️ [Check demo](https://bit-about.github.io/event/)\n\n## Usage\n\n1️⃣ Define *your events* by defining their payload middlewares\n```jsx\nimport { events } from '@bit-about/event'\n\nconst [EventProvider, useEvents] = events({\n  buttonClicked: (payload: string) =\u003e payload,\n  userLogged: () =\u003e {},\n  modalClosed: () =\u003e {},\n})\n```\n\n2️⃣ Wrap your components in EventProvider\n```jsx\nconst App = () =\u003e (\n  \u003cEventProvider\u003e\n    ...\n  \u003c/EventProvider\u003e\n)\n```\n\n🗣️ Dispatch your events in one place...\n\n```jsx\nconst Button = () =\u003e {\n  const { buttonClicked } = useEvents()\n  \n  return (\n    \u003cbutton onClick={() =\u003e buttonClicked('Hello')}\u003e\n      Call event\n    \u003c/button\u003e\n  )\n}\n```\n\n👂 ...and listen for them in another\n```jsx\nconst Component = () =\u003e {\n  const [message, setMessage] = React.useState('')\n\n  useEvents({\n    buttonClicked: (payload: string) =\u003e setMessage(payload)\n  })\n  \n  return \u003cp\u003e{message}\u003c/p\u003e // \"Hello\"\n}\n```\n\n## Static access\nThe third result element of `events()` is object providing access in static manner (without hook). \n\n```jsx\nconst [AppEventProvider, useAppEvents, { subscribe, dispatcher }] = events(...)\n```\n\nand then\n```jsx\n// 🗣️ Dispatch event\ndispatcher.buttonClicked('Hello Allice!')\n\n// 👂 Subscribe and listen on new events\nconst subscriber = subscribe({\n  buttonClicked: (payload: string) =\u003e console.log(payload)\n})\n  \n// remember to unsubscribe!\nsubscriber.unsubscribe()\n```\n\n## 👉 Re-render\nNeither listeners nor events dispatch your components render.\u003cbr /\u003e\nA component will only be rerendered if it's state is explicitly changed (in e.g. `React.useState`).\n\n```jsx\nconst Component = () =\u003e {\n  const [message, setMessage] = React.useState('')\n\n  useEvents({\n    aliceClicked: () =\u003e console.log('I DO NOT rerender this component!'),\n    bobClicked: () =\u003e setMessage('I DO rerender this component!')\n  })\n  \n  return \u003cp\u003e{message}\u003c/p\u003e\n}\n```\n\n## Event Middlewares\nEvents in `events()` are payload middlewares. They can transform payload into another.\n\n```jsx\nconst [EventProvider, useEvents] = events({\n  buttonClicked: (payload) =\u003e `Hello ${message}!`, // Transforms string payload to another\n  avatarClicked: () =\u003e `Bob!`,                     // Provides default payload\n})\n\nconst { buttonClicked, avatarClicked } = useEvents({\n  buttonClicked: (payload) =\u003e console.log(payload), // prints \"Hello Alice!\",\n  avatarClicked: (payload) =\u003e console.log(payload), // prints \"Bob!\"\n})\n\nbuttonClicked('Alice')\navatarClicked()\n```\n\n\u003e NOTE: \u003cbr /\u003e\n\u003e The library is full type-safe, so Typescript will inform you when you use wrong payload anywhere.\n\n## BitAboutEvent 💛 [BitAboutState](https://github.com/bit-about/state)\nAre you tired of sending logic to a related components?\u003cbr /\u003e\nMove your bussiness logic to hook-based state using `@bit-about/state` + `@bit-about/event`.\u003cbr /\u003e\n\nNow you've got **completely type-safe side-effects**. Isn't that cool?\n\n```tsx\nimport { state } from '@bit-about/state'\nimport { useEvents } from './auth-events' // Hook generated from events()\nimport User from '../models/user'\n\nconst [UserProvider, useUser] = state(\n  () =\u003e {\n    const [user, setUser] = React.useState\u003cUser | null\u003e(null)\n    \n    useEvents({\n      userLogged: (user: User) =\u003e setUser(user),\n      userLoggout: () =\u003e setUser(null)\n    })\n    \n    return user\n  }\n)\n```\n\n## Partners  \n\u003ca href=\"https://www.wayfdigital.com/\"\u003e\u003cimg alt=\"wayfdigital.com\" width=\"100\" height=\"100\" src=\"https://user-images.githubusercontent.com/1496580/161037415-0503f763-a60b-4d40-af9f-95d1304fa486.png\"/\u003e\u003c/a\u003e\n\n## Credits\n- [Constate](https://github.com/diegohaz/constate) - approach main inspiration\n- [use-context-selector](https://github.com/dai-shi/use-context-selector) \u0026 [FluentUI](https://github.com/microsoft/fluentui) - fancy rerender avoiding tricks and code main inspiration\n\n## License\nMIT © [Maciej Olejnik 🇵🇱](https://github.com/macoley)\n\n## Support me\n\n\u003ca href=\"https://github.com/sponsors/macoley\"\u003e\u003cimg alt=\"Support me!\" src=\"https://img.shields.io/badge/github.com-Support%20me!-green\"/\u003e\u003c/a\u003e\n\nIf you use my library and you like it...\u003cbr /\u003e\nit would be nice if you put the name `BitAboutEvent` in the work experience section of your resume.\u003cbr /\u003e\nThanks 🙇🏻! \n\n---\n\u003cp align=\"center\"\u003e🇺🇦 Slava Ukraini\u003c/p\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foleystack%2Fevent","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Foleystack%2Fevent","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Foleystack%2Fevent/lists"}