{"id":49453753,"url":"https://github.com/LucaColonnello/focuz","last_synced_at":"2026-06-18T22:01:05.213Z","repository":{"id":57239664,"uuid":"76777091","full_name":"LucaColonnello/focuz","owner":"LucaColonnello","description":"React on the fly view builder","archived":false,"fork":false,"pushed_at":"2017-01-24T22:37:35.000Z","size":24,"stargazers_count":8,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2026-03-22T11:46:03.572Z","etag":null,"topics":["builder","json","react","react-elements","view-creator"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/LucaColonnello.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":"2016-12-18T10:45:39.000Z","updated_at":"2019-08-16T22:30:58.000Z","dependencies_parsed_at":"2022-08-29T21:23:18.587Z","dependency_job_id":null,"html_url":"https://github.com/LucaColonnello/focuz","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/LucaColonnello/focuz","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaColonnello%2Ffocuz","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaColonnello%2Ffocuz/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaColonnello%2Ffocuz/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaColonnello%2Ffocuz/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/LucaColonnello","download_url":"https://codeload.github.com/LucaColonnello/focuz/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/LucaColonnello%2Ffocuz/sbom","scorecard":{"id":86066,"data":{"date":"2025-08-11","repo":{"name":"github.com/LucaColonnello/focuz","commit":"ef3cf0be1c165bf5daa03685157c6b2b9c222f34"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Code-Review","score":0,"reason":"Found 0/6 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: GNU General Public License v3.0: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 7 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-15T06:57:58.688Z","repository_id":57239664,"created_at":"2025-08-15T06:57:58.688Z","updated_at":"2025-08-15T06:57:58.688Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34508867,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"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":["builder","json","react","react-elements","view-creator"],"created_at":"2026-04-30T04:01:03.704Z","updated_at":"2026-06-18T22:01:05.207Z","avatar_url":"https://github.com/LucaColonnello.png","language":"JavaScript","funding_links":[],"categories":["📦 Legacy \u0026 Inactive Projects"],"sub_categories":[],"readme":"# Project Focuz\n[![CircleCI](https://circleci.com/gh/LucaColonnello/focuz.svg?style=svg)](https://circleci.com/gh/LucaColonnello/focuz)\n\nProject Focuz is a React on the fly view builder which let you create react elements using a json object that describes how many components you want, their props and children.\n\nUse this view builder to create your views, let you focus on the atomic parts like UI components or complex modules.\n\nThis view builder is renderer agnostic, so it can be used with `ReactDOM` and `ReactNative` as well.\n\n**Create your components and tell the view builder how to mix them to create your views.**\n\n*And that's all!*\n\n\n## What this can be used for\n\nLet's have a list of examples:\n\n- **Page creation**: You can make an entire page mixing all the components you've created in a JSON object and pass it down to the view builder. (The aim of this: **The JSON object can obviously come out from a web service**)\n\n- **Content creation**: You can make content using the view builder and all the components you've created to easily create content avoiding changes in any of your components every time you need to change the content. (The aim of this: **Let editors create contents the way they want to, with more then a WYSIWYG editor**)\n\n- **Your ideas**: Fancy to experiment? Create your way and let me know! (Remember: **The more your business logic is outside the render, the more you earn from it**)\n\n\n**This is not meant to be a component builder.\nYou are not supposed to use it to create atomic components.\nNative elements are not supported from this view builder**\n\n\n## How to use it\n\n**1) Install it:**\n\n`npm install focuz`\n\nor\n\n`yarn add focuz`\n\n**2) Try it**\n\nThis is a simple setup.\n\n```js\nimport ReactDOM from 'react-dom';\n\n// import the lib\nimport createViewBuilder, {\n  createFocuzElement,\n} from 'focuz';\n\n// suppose you have a component folder\n// that exports all the components you've created\nimport {\n  Container,\n  Header,\n  MarkdownText,     // markdown is cool, let's use ReactMarkdown component\n  Quote,\n} from './components';\n\n// provide types object\n// the bunch of components the view builder can use\nconst types = {\n  Container,\n  Header,\n  MarkdownText,\n  Quote,\n};\n\n// and then create the view builder\nconst viewBuilder = createViewBuilder(types);\n\n\n// create the node description,\n// the object that describes what you want to render\n\n// can be done everywhere, also into a web service\n// or can be stored into a database\nconst nodeDescription = createFocuzElement(\n  // type\n  'Container',\n\n  // props\n  {\n    className: 'article',\n  },\n\n  // children\n  [\n    createFocuzElement(\n      'Header',\n      {\n        text: 'My article title',\n      },\n    ),\n    createFocuzElement(\n      'Quote',\n      {\n        text: 'My article description.',\n      },\n    ),\n    createFocuzElement(\n      'MarkdownText',\n      {\n        text: '*My article content with markdown*',\n      },\n    ),\n  ],\n);\n\n// nodeDescription is a simple json object\n// createFocuzElement creates an object with a\n// _isFocuz attribute for validation\nconsole.log(nodeDescription);\n```\n\nThen you can use it with ReactDOM render.\n\n```js\nconst content = viewBuilder(nodeDescription);\nReactDOM.render(\n  content,\n  document.getElementById('my-container')\n);\n```\n\nOr into another component. The view builder is simply returning a React element (not a class).\n\n```js\nconst Content = ({ nodeDescription }) =\u003e {\n  const content = viewBuilder(nodeDescription);\n  return (\n    \u003cdiv\u003e\n      {content}\n    \u003c/div\u003e\n  );\n};\n\nReactDOM.render(\n  \u003cContent contentDescription={contentDescription} /\u003e,\n  document.getElementById('my-container')\n);\n```\n\n\n## Change nodes with modifiers\n\nYou can change each node before the view builder create the React element using *modifiers*.\n\n**A modifier is a function that has the responsibility to change nodes before the builder parse them.**\n\n### Example of modifier:\n\n```js\nfunction layoutModifier(/* options */) {\n  return (node, ComponentType) =\u003e {\n    // check if the properties we work with exists\n    // otherwise return the node itself\n    // e.g.: if the style doesn't exists in propTypes,\n    // it means that the component doesn't handle style passed from outside\n    if (!node.props.layout || !ComponentType.propTypes.style) {\n      return node;\n    }\n\n    // get the layout property and clone props taking off the layout\n    // to avoid React to receive properties the Component doesn't care of\n    const layout = node.props.layout;\n    const props = {\n      ...node.props,\n      style: {},\n    };\n    delete props.layout;\n\n    // add some layout style\n    if (layout.margin) {\n      props.style.margin = layout.margin;\n    }\n\n    if (layout.padding) {\n      props.style.padding = layout.padding;\n    }\n\n    // something else in your imagination\n\n    // return the new node\n    return {\n      ...node,\n      props,\n    };\n  }\n}\n```\n\n## How to contribute\n\nTo contribute just create an issue and then reference it in a PR involving your changes.\nMake sure to reference the issue using this syntax in the description of the PR:\n\n`Connect to #issue`\n\n\n## Release instructions\n\nThe release process in currently a manual step that doesn't involve the CI.\nThis might be changed in the future. By now, just do the following once master branch can be published.\n\n```\nnpm -v [\u003cnewversion\u003e | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]\nnpm publish --tag [\u003ctag\u003e]\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLucaColonnello%2Ffocuz","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FLucaColonnello%2Ffocuz","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FLucaColonnello%2Ffocuz/lists"}