{"id":15731331,"url":"https://github.com/chrisvxd/react-from-json-fork","last_synced_at":"2026-02-19T15:02:45.730Z","repository":{"id":42098753,"uuid":"226173516","full_name":"chrisvxd/react-from-json-fork","owner":"chrisvxd","description":"Declare your React component tree in JSON","archived":false,"fork":false,"pushed_at":"2022-12-09T00:56:23.000Z","size":1168,"stargazers_count":4,"open_issues_count":39,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-05-07T13:05:57.711Z","etag":null,"topics":["ast","headless","headlesscms","json","react"],"latest_commit_sha":null,"homepage":null,"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/chrisvxd.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-12-05T19:24:53.000Z","updated_at":"2023-06-29T04:57:06.000Z","dependencies_parsed_at":"2023-01-25T10:31:23.377Z","dependency_job_id":null,"html_url":"https://github.com/chrisvxd/react-from-json-fork","commit_stats":null,"previous_names":[],"tags_count":8,"template":false,"template_full_name":null,"purl":"pkg:github/chrisvxd/react-from-json-fork","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisvxd%2Freact-from-json-fork","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisvxd%2Freact-from-json-fork/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisvxd%2Freact-from-json-fork/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisvxd%2Freact-from-json-fork/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chrisvxd","download_url":"https://codeload.github.com/chrisvxd/react-from-json-fork/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chrisvxd%2Freact-from-json-fork/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29619143,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-19T13:04:20.082Z","status":"ssl_error","status_checked_at":"2026-02-19T13:03:33.775Z","response_time":117,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["ast","headless","headlesscms","json","react"],"created_at":"2024-10-04T00:01:34.818Z","updated_at":"2026-02-19T15:02:45.710Z","avatar_url":"https://github.com/chrisvxd.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-from-json\n\n\u003e Declare your React component tree in JSON\n\n[![NPM](https://img.shields.io/npm/v/react-from-json.svg)](https://www.npmjs.com/package/react-from-json) [![JavaScript Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://standardjs.com)\n\n[Example](http://hydrateio.github.io/react-from-json/)\n\n## Intro\n\n`react-from-json` lets you render React\n\n```jsx\n\u003cBurger chain=\"Wahlburger\"\u003e\n  \u003cPatty variant=\"impossible\" /\u003e\n\u003c/Burger\u003e\n```\n\nfrom JSON\n\n```json\n{\n  \"type\": \"Burger\",\n  \"props\": {\n    \"chain\": \"Wahlburger\",\n    \"children\": {\n      \"type\": \"Patty\",\n      \"props\": {\n        \"variant\": \"impossible\"\n      }\n    }\n  }\n}\n```\n\nIt also supports non-recursive structures.\n\n## Install\n\n```bash\nnpm install --save react-from-json\n```\n\n## Usage\n\n```jsx\nimport React from \"react\";\nimport ReactFromJSON from \"react-from-json\";\n\nconst entry = {\n  type: \"Burger\",\n  props: {\n    chain: \"Wahlburger\",\n    children: {\n      type: \"Patty\",\n      props: {\n        variant: \"Impossible\"\n      }\n    }\n  }\n};\n\nconst mapping = {\n  Burger: ({ chain, children }) =\u003e (\n    \u003cdiv\u003e\n      \u003ch1\u003e{chain}\u003c/h1\u003e\n      \u003cdiv\u003e{children}\u003c/div\u003e\n    \u003c/div\u003e\n  ),\n  Patty: ({ variant }) =\u003e \u003cspan\u003e{variant}\u003c/span\u003e\n};\n\nconst Example = () =\u003e {\n  return \u003cReactFromJSON entry={entry} mapping={mapping} /\u003e;\n};\n```\n\n### Props passed to your components\n\nProps passed to your mapped components include\n\n- `propKey` - name of the prop that rendered your component\n- `propIndex` - index of your component if using [flat trees](#flat-trees)\n- `_type` - the `type` value for your component\n- `...props` - the resolved value of your `props` object, with relevant child nodes rendered as components\n\n### Other JSON shapes\n\nIf your data doesn't follow the `type` | `props` shape, `react-from-json` makes it easy to map your data on the fly using the `mapProp` prop.\n\n```jsx\nimport React from \"react\";\nimport ReactFromJSON from \"react-from-json\";\nimport mapping from \"./mapping\";\n\nconst entryWithDifferentShape = {\n  _type: \"Burger\",\n  chain: \"Wahlburger\",\n  children: {\n    _type: \"Patty\",\n    variant: \"Impossible\"\n  }\n};\n\nconst mapProp = prop =\u003e {\n  if (prop._type) {\n    const { _type, ...props } = prop;\n\n    return {\n      type: _type,\n      props\n    };\n  }\n\n  return prop;\n};\n\nconst Example = () =\u003e {\n  return (\n    \u003cReactFromJSON\n      entry={entryWithDifferentShape}\n      mapping={mapping}\n      mapProp={mapProp}\n    /\u003e\n  );\n};\n```\n\n### Flat trees\n\n`react-from-json` also supports flat, non-recursive structures via the special `\u003cComponentLookup /\u003e` component. This is useful when working with typed systems like GraphQL, and you need to avoid unions.\n\n#### The `\u003cComponentLookup /\u003e` component\n\n`\u003cComponentLookup /\u003e` simply maps to another component defined in a `components` object. If you were using it in React, you would use it like:\n\n```jsx\n\u003cComponentLookup componentType=\"Button\" componentIndex={0} /\u003e\n```\n\nwhich would look up the `Button` component at index `0` in the `components` object, resolving to:\n\n```jsx\n\u003cButton id={0}\u003eHello, World!\u003c/Button\u003e\n```\n\nFor `react-from-json` we use JSON, so we would write this:\n\n```json\n{\n  \"type\": \"ComponentLookup\",\n  \"props\": {\n    \"componentType\": \"Button\",\n    \"componentIndex\": 0\n  }\n}\n```\n\n\u003e The `id` here is set by the `componentIndex`, since we didn't specify one in the JSON. See \u003ca href=\"#a-note-on-ids\"\u003ethis comment on IDs\u003c/a\u003e for more information.\n\n#### Example\n\nHere's the same example as above, instead using a `\u003cComponentLookup /\u003e` for `entry.props.patty`, and providing a separate `components` object.\n\n```jsx\nimport React from \"react\";\nimport ReactFromJSON from \"react-from-json\";\n\nconst entry = {\n  type: \"Burger\",\n  props: {\n    chain: \"Wahlburger\",\n    patty: {\n      type: \"ComponentLookup\",\n      props: {\n        componentIndex: 0,\n        componentType: \"Patty\"\n      }\n    }\n  }\n};\n\nconst mapping = {\n  Burger: ({ chain, patty }) =\u003e (\n    \u003cdiv\u003e\n      \u003ch1\u003e{chain}\u003c/h1\u003e\n      \u003cdiv\u003e{patty}\u003c/div\u003e\n    \u003c/div\u003e\n  ),\n  Patty: ({ variant }) =\u003e \u003cspan\u003e{variant}\u003c/span\u003e\n};\n\nconst components = {\n  Patty: [\n    {\n      type: \"Patty\",\n      props: {\n        variant: \"Impossible\"\n      }\n    }\n  ]\n};\n\nconst Example = () =\u003e {\n  return (\n    \u003cReactFromJSON entry={entry} mapping={mapping} components={components} /\u003e\n  );\n};\n```\n\n### A note on ids\n\n`react-from-json` will map `id` from the root of your component JSON to the React component's `id` prop. Likewise, if you specify `id` under `props`, it will use this. If you use the `\u003cComponentLookup /\u003e` component, `react-from-json` will use the array index as `id` unless another `id` is specified. **Your `id` will always take priority.**\n\n### With TypeScript\n\n`react-from-json` supports generic types for use with TypeScript.\n\n```tsx\nimport { entry, mapping, components } from \"./aboveExample\";\nimport ReactFromJSON from \"react-from-json\";\n\ninterface Components {\n  Patty: object[];\n}\n\ninterface Mapping {\n  Burger: React.ReactNode;\n  Patty: React.ReactNode;\n}\n\nclass BurgerReactFromJSON extends ReactFromJSON\u003cMapping, Components\u003e {\n  render(): JSX.Element {\n    return super.render();\n  }\n}\n\nconst Example = () =\u003e {\n  return (\n    \u003cBurgerReactFromJSON\n      entry={entry}\n      mapping={mapping}\n      components={components}\n    /\u003e\n  );\n};\n```\n\n## License\n\nMIT © [hydrateio](https://github.com/hydrateio)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisvxd%2Freact-from-json-fork","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchrisvxd%2Freact-from-json-fork","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchrisvxd%2Freact-from-json-fork/lists"}