{"id":15412435,"url":"https://github.com/robertknight/ureact","last_synced_at":"2025-05-01T10:26:59.200Z","repository":{"id":66375332,"uuid":"325287474","full_name":"robertknight/ureact","owner":"robertknight","description":"A small implementation of the modern React API for educational purposes.","archived":false,"fork":false,"pushed_at":"2021-10-17T07:57:39.000Z","size":381,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-09T15:45:06.103Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/robertknight.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":"2020-12-29T12:58:04.000Z","updated_at":"2023-01-12T06:04:52.000Z","dependencies_parsed_at":"2023-02-22T02:30:21.321Z","dependency_job_id":null,"html_url":"https://github.com/robertknight/ureact","commit_stats":{"total_commits":133,"total_committers":1,"mean_commits":133.0,"dds":0.0,"last_synced_commit":"db450ca82eafd8d795008b1d34292d62127eba49"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertknight%2Fureact","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertknight%2Fureact/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertknight%2Fureact/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/robertknight%2Fureact/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/robertknight","download_url":"https://codeload.github.com/robertknight/ureact/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251858849,"owners_count":21655455,"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":[],"created_at":"2024-10-01T16:53:06.581Z","updated_at":"2025-05-01T10:26:59.160Z","avatar_url":"https://github.com/robertknight.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# ureact\n\nureact is an implementation of the modern [React](https://reactjs.org/) APIs\nfor building UI components in web applications. Its goals are to be small,\nsimple and self-contained. It may be of interest if you want to get a sense of how\nthe core modern React APIs can be implemented.\n\nureact also includes an implementation of the [Enzyme](https://github.com/enzymejs/enzyme)\ntesting library.\n\nThis was created as a personal project. If you are looking for a small React\nimplementation that is actively maintained and suitable for use in production,\ncheck out [Preact](https://preactjs.com).\n\n## Supported features\n\nureact supports the core, modern React APIs for use in the browser. This includes:\n\n- [Function components](https://reactjs.org/docs/components-and-props.html)\n- The default and new (React 17+) [methods of transforming JSX](https://reactjs.org/blog/2020/09/22/introducing-the-new-jsx-transform.html)\n- [Hooks](https://reactjs.org/docs/hooks-intro.html) for adding state and effects\n  to components.\n- Important utilities such as [`Fragment`](https://reactjs.org/docs/fragments.html) and [`memo`](https://reactjs.org/docs/react-api.html#reactmemo)\n- The modern [Context](https://reactjs.org/docs/context.html) API\n- The [`act`](https://reactjs.org/docs/testing-recipes.html#act) test utility\n\nIt intentionally does not support:\n\n- Class components with lifecycle methods\n- The [concurrent mode](https://reactjs.org/docs/concurrent-mode-intro.html) APIs\n  such as `Suspense`\n- The [legacy context API](https://reactjs.org/docs/legacy-context.html#gatsby-focus-wrapper)\n- [Synthetic events](https://reactjs.org/docs/events.html). Event handlers get\n  native DOM events instead\n- Testing APIs other than `act`\n- Rendering to non-DOM targets. There is no equivalent of React Native or\n  React ART for example.\n\nThere is currently no server-side rendering / render-to-string support. This\nmight change in future.\n\n## Supported browsers\n\nureact is intended to work on modern (~2017 and later) browsers. It does not support\nIE 11 or similar vintage browsers. It also works with JSDOM in a test environment.\n\n## API differences from React\n\nAside from React APIs which ureact intentionally does not support, there are\nsome other API differences:\n\n- ureact does not have a default export. In React functions can be imported using\n  either:\n\n  ```js\n  import React from \"react\";\n\n  React.createElement(...)\n  ```\n\n  Or:\n\n  ```js\n  import { createElement } from \"react\";\n  createElement(...)\n  ```\n\n  The second style is preferred in modern React code and is the only style\n  supported by ureact.\n\n  If using a build tool such as Babel or TypeScript, it must be configured\n  to translate JSX into calls to `createElement` rather than `React.createElement`.\n\n- Event handlers receive native DOM events rather than synthetic events. In most\n  instances this does not require changes to event handler code since React's\n  `SyntheticEvent` has the same API as native events and mainly exists to\n  normalize historical differences across browsers.\n\n- Since class components are not supported, the API for adding [error boundaries](https://reactjs.org/docs/error-boundaries.html)\n  is different. ureact exports an `ErrorBoundary` helper component which is used\n  like so:\n\n  ```js\n  import { createElement, ErrorBoundary, useState } from \"ureact\";\n\n  function App() {\n    const [error, setError] = useState(null);\n\n    return error ? (\n      \"Something went wrong\"\n    ) : (\n      \u003cErrorBoundary handler={setError}\u003e…\u003c/ErrorBoundary\u003e\n    );\n  }\n  ```\n\n  The `ErrorBoundary` component could be implemented in React with:\n\n  ```js\n  import { Component } from \"react\";\n\n  export class ErrorBoundary extends Component {\n    componentDidCatch(error) {\n      this.props.handler(error);\n    }\n\n    render({ children }) {\n      return children;\n    }\n  }\n  ```\n\n- The rules for determining how to apply a prop to a DOM element are determined\n  differently. In the vast majority of cases the end result is the same, but\n  ureact uses a generic set of rules rather than rules for specific DOM properties:\n\n  1. If the prop is `style` it sets inline styles\n  2. If the prop is `dangerouslySetInnerHTML` it sets `innerHTML`\n  3. If the prop name starts with \"on\", it adds an event handler. The prop name\n     after the \"on\" prefix is used as the event name. If the DOM element has an\n     `oneventname` property then the event name is lower-cased (eg. `onClick`\n     maps to the `click` event rather than the `Click` event)\n  4. If a DOM element has a writable or settable property whose name matches the\n     prop, then that DOM property is set\n  5. Otherwise the prop sets the attribute whose name matches the prop\n\n  The above list is similar to how Preact works.\n\n  The advantage of using these generic rules is that it applies equally well\n  to custom element types and new properties added in future as existing DOM\n  properties, providing that these elements/properties follow existing conventions.\n\n## Implementation notes\n\nAs well as being based entirely around the modern React APIs, a few implementation\ndetails are notable:\n\n- Everything is in one package with no dependencies\n- There is minimal global state. Every _root_, which is created when a ureact\n  component is rendered into a container DOM element by `render`, has its own local state.\n  This means that different ureact \"islands\" (eg. different tests in a test suite,\n  or different widgets on a page) are unlikely to interfere with one another,\n  even if they use different versions of ureact.\n- VNodes created by `createElement` are immutable. This could enable various\n  compile/runtime optimizations.\n- The test suite uses only the public APIs. This is intended to enable tests to\n  be run against other React API implementations to check for unexpected behavior\n  differences.\n- Strict type checking is used. This helped to catch many potential errors during\n  development.\n- ureact tries to minimize the number of rules for handling specific DOM or\n  CSS props. Instead the logic for deciding how to apply a prop to a DOM element\n  uses general heuristics.\n\n  This enables greater consistency across all DOM properties/attributes/events as\n  well as better generalization to custom element types and new DOM events, properties etc.\n  that are added in future. See `src/dom-props.ts` for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertknight%2Fureact","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frobertknight%2Fureact","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frobertknight%2Fureact/lists"}