{"id":26062278,"url":"https://github.com/mcjazzyfunky/archived-preactive","last_synced_at":"2026-05-13T23:38:41.248Z","repository":{"id":39284266,"uuid":"229132780","full_name":"mcjazzyfunky/archived-preactive","owner":"mcjazzyfunky","description":"An alternative API for programming components and hook function with Preact","archived":false,"fork":false,"pushed_at":"2022-12-11T17:52:35.000Z","size":1093,"stargazers_count":1,"open_issues_count":21,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-11T06:05:26.715Z","etag":null,"topics":["hooks","preact","preact-components"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"unlicense","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mcjazzyfunky.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-19T20:23:42.000Z","updated_at":"2023-07-24T18:52:32.000Z","dependencies_parsed_at":"2022-09-01T08:52:09.019Z","dependency_job_id":null,"html_url":"https://github.com/mcjazzyfunky/archived-preactive","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mcjazzyfunky/archived-preactive","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcjazzyfunky%2Farchived-preactive","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcjazzyfunky%2Farchived-preactive/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcjazzyfunky%2Farchived-preactive/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcjazzyfunky%2Farchived-preactive/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mcjazzyfunky","download_url":"https://codeload.github.com/mcjazzyfunky/archived-preactive/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mcjazzyfunky%2Farchived-preactive/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33004763,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-13T13:14:54.681Z","status":"ssl_error","status_checked_at":"2026-05-13T13:14:51.610Z","response_time":115,"last_error":"SSL_read: 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":["hooks","preact","preact-components"],"created_at":"2025-03-08T15:55:15.485Z","updated_at":"2026-05-13T23:38:41.224Z","avatar_url":"https://github.com/mcjazzyfunky.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Preactive \n\nA R\u0026D project to evaluate an alternative API for developing\ncomponents and hook functions with Preact.\u003cbr\u003e\nThe main advantages of the new API are:\n\n- 0% magic\n- Does not make any trouble for the garbage collector\n- No rules of hooks\n- No special linter necessary\n- 100% accurately typeable - in the function type signature\n  of hook functions or function that generate hook functions etc.,\n  it will always be visible what we are dealing with.\n\n### Installation\n\n```\ngit clone https://github.com/mcjazzyfunky/preactive.git\ncd preactive\nnpm install\n```\n\n### Running demos\n\n```\nnpm run storybook\n```\n\n## Examples\n\n### Stateless components (variant 1)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statelessComponent } from 'preactive'\n\nconst HelloWorld = statelessComponent('HelloWorld', props =\u003e {\n  return (\n    \u003cdiv\u003e\n      {props.salutation || 'Hello'}, {props.name || 'world'}\n    \u003c/div\u003e\n  )\n})\n```\n\n### Stateless components (variant 2)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statelessComponent } from 'preactive'\n\nconst HelloWorld = statelessComponent('HelloWorld', ({\n  salutation = 'Hello',\n  name = 'world'\n}) =\u003e {\n  return (\n    \u003cdiv\u003e\n      {props.salutation}, {props.name}\n    \u003c/div\u003e\n  )\n})\n```\n### Stateless components (variant 3)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statelessComponent } from 'preactive'\n\nconst HelloWorld = statelessComponent({\n  displayName: 'HelloWorld',\n\n  defaultProps: {\n    salutation: 'Hello',\n    name: 'world'\n  }\n}, props =\u003e {\n  return (\n    \u003cdiv\u003e\n      {props.salutation}, {props.name}\n    \u003c/div\u003e\n  )\n})\n```\n\n### Stateless components (variant 4)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statelessComponent } from 'preactive'\n\nconst HelloWorld = statelessComponent({\n  displayName: 'HelloWorld',\n\n  defaultProps: {\n    salutation: 'Hello',\n    name: 'world'\n  },\n\n  render: renderHelloWorld\n}\n\nfunction renderHelloWorld(props) {\n  return (\n    \u003cdiv\u003e\n      {props.salutation}, {props.name}\n    \u003c/div\u003e\n  )\n}\n```\n\n### Stateful components (variant 1)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statefulComponent, useValue } from 'preactive'\n\nconst Counter = statefulComponent('Counter', (c, props) =\u003e {\n  const\n    [count, setCount] = useValue(c, props.initialValue || 0),\n    onIncrement = () =\u003e setCount(it =\u003e it + 1)\n\n  return () =\u003e\n    \u003cdiv\u003e\n      \u003clabel\u003e{props.label || 'Counter'}: \u003c/label\u003e\n      \u003cbutton onClick={onIncrement}\u003e{count.value}\u003c/button\u003e\n    \u003c/div\u003e\n})\n\nrender(\u003cCounter/\u003e, document.getElementById('app'))\n```\n\n### Stateful components (variant 2)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statefulComponent, useValue } from 'preactive'\n\nconst Counter = statefulComponent({\n  displayName: 'Counter',\n  memoize: true,\n  \n  defaultProps: {\n    initialValue: 0,\n    label: 'Counter'\n  }\n}, (c, props) =\u003e {\n  const\n    [count, setCount] = useValue(c, props.initialValue),\n    onIncrement = () =\u003e setCount(it =\u003e it + 1)\n\n  return () =\u003e\n    \u003cdiv\u003e\n      \u003clabel\u003e{props.label}: \u003c/label\u003e\n      \u003cbutton onClick={onIncrement}\u003e{count.value}\u003c/button\u003e\n    \u003c/div\u003e\n})\n\nrender(\u003cCounter/\u003e, document.getElementById('app'))\n```\n\n### Stateful components (variant 3)\n\n```jsx\nimport { h, render } from 'preact'\nimport { statefulComponent, useValue } from 'preactive'\n\nconst Counter = statefulComponent({\n  displayName: 'Counter',\n  memoize: true,\n  \n  defaultProps: {\n    initialValue: 0,\n    label: 'Counter'\n  },\n\n  init: initCounter\n})\n\nfunction initCounter(c, props) {\n  const\n    [count, setCount] = useValue(c, props.initialValue),\n    onIncrement = () =\u003e setCount(it =\u003e it + 1)\n\n  return () =\u003e\n    \u003cdiv\u003e\n      \u003clabel\u003e{props.label}: \u003c/label\u003e\n      \u003cbutton onClick={onIncrement}\u003e{count.value}\u003c/button\u003e\n    \u003c/div\u003e\n})\n\nrender(\u003cCounter/\u003e, document.getElementById('app'))\n```\n\nIn the above examples the `c` is a so called component controller\n(some kind of representation for the component instance).\nThe type of the component controller is currently the following\n(please be aware that \"normal\" developers will never have to use these\nmethods directly they will only be used internally by some basic\nhook and utility functions):\n\n```typescript\ntype Ctrl = {\n  isMounted(): boolean,\n  update(): void,\n  getContextValue\u003cT\u003e(Context\u003cT\u003e): T,\n  afterMount(subscriber: Subscriber): void,\n  beforeUpdate(subscriber: Subscriber): void,\n  afterUpdate(subscriber: Subscriber): void,\n  beforeUnmount(subscriber: Subscriber): void,\n  runOnceBeforeUpdate(task: Task): void\n}\n\ntype Props = Record\u003cstring, any\u003e\ntype Subscriber = () =\u003e void\ntype Task = () =\u003e void\ntype Context\u003cT\u003e = Preact.Context\u003cT\u003e\n```\n\n## API\n\n### Component definition\n\n- `statelessComponent(displayName, render: props =\u003e vnode)`\n- `statelessComponent(meta, render: props =\u003e vnode)`\n- `statelessComponent(config)`\n- `statefulComponent(displayName, init: c =\u003e props =\u003e vnode)`\n- `statefulComponent(meta, init: c =\u003e props =\u003e vnode)`\n- `statefulComponent(config)`\n\n### Utility functions\n\n- `isMounted(c)`\n- `forceUpdate(c)`\n- `asRef(valueOrRef)`\n- `toRef(getter)`\n\n### Hooks\n\n- `useValue(c, initialValue)`\n- `useState(c, initialStateObject)`\n- `useContext(c, context)`\n- `useMemo(c, calculation, () =\u003e dependencies)`\n- `useEffect(c, action, () =\u003e dependencies)`\n- `useInterval(c, action, milliseconds)`\n\n## Project state\n\nThis R\u0026D project is still in a very early development state\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcjazzyfunky%2Farchived-preactive","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmcjazzyfunky%2Farchived-preactive","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmcjazzyfunky%2Farchived-preactive/lists"}