{"id":51076853,"url":"https://github.com/z-js-framework/z-js","last_synced_at":"2026-06-23T15:00:53.938Z","repository":{"id":190605579,"uuid":"682987565","full_name":"Z-Js-Framework/z-js","owner":"Z-Js-Framework","description":"The literally low mental overhead js framework!","archived":false,"fork":false,"pushed_at":"2024-08-18T07:50:03.000Z","size":11307,"stargazers_count":211,"open_issues_count":4,"forks_count":9,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-10-21T22:36:45.022Z","etag":null,"topics":["framework","javascript","js","jsx","literals","reactjs"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/z-js-framework","language":"JavaScript","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/Z-Js-Framework.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.MD","contributing":null,"funding":null,"license":"LICENSE","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":"2023-08-25T10:28:27.000Z","updated_at":"2025-10-16T07:27:27.000Z","dependencies_parsed_at":"2023-08-25T13:47:42.724Z","dependency_job_id":"603da1ba-e4b8-414e-b1bd-6e6d5e92c12a","html_url":"https://github.com/Z-Js-Framework/z-js","commit_stats":null,"previous_names":["javascriptkampala/z-js","z-js-framework/z-js"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/Z-Js-Framework/z-js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Z-Js-Framework%2Fz-js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Z-Js-Framework%2Fz-js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Z-Js-Framework%2Fz-js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Z-Js-Framework%2Fz-js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Z-Js-Framework","download_url":"https://codeload.github.com/Z-Js-Framework/z-js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Z-Js-Framework%2Fz-js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34694786,"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-23T02:00:07.161Z","response_time":65,"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":["framework","javascript","js","jsx","literals","reactjs"],"created_at":"2026-06-23T15:00:31.371Z","updated_at":"2026-06-23T15:00:53.932Z","avatar_url":"https://github.com/Z-Js-Framework.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🔥 Z.Js Framework (v0.0.8)\n\n\u003cdiv align=\"left\"\u003e\n\n[![Status](https://img.shields.io/badge/status-active-success.svg)]()\n[![GitHub Issues](https://img.shields.io/github/issues/Z-Js-Framework/z-js.svg)](https://github.com/Z-Js-Framework/z-js/issues)\n[![GitHub Pull Requests](https://img.shields.io/github/issues-pr/Z-Js-Framework/z-js.svg)](https://github.com/Z-Js-Framework/z-js/pulls)\n[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://github.com/Z-Js-Framework/z-js/blob/main/LICENSE)\n![npm](https://img.shields.io/npm/dw/z-js-framework)\n![GitHub Repo stars](https://img.shields.io/github/stars/Z-Js-Framework/z-js?style=social)\n\n\u003c/div\u003e\n\n- The literally low mental overhead Js framework, that enhances html, css and javascript.\n\n\n## 🚀 Getting Started\n\nBefore we get you started in case you asking, why another framework? first see [why z js framework](./sidenotes.md#-why-another-framework-why-not-listen-up) otherwise if you good with the motive of this, then the easiest way to get started with Z.Js Framework is to use the [create-z-project](https://github.com/z-js-framework/create-z-project) using command below. It will create a starter project with recommended project structure and common pattern examples.\n\n``` bash\nnpx create-z-project your-project-name\n```\n\nafter that just follow instructions that follow on there. And don't forget to install this vscode extension for better experience, [Inline HTML](https://marketplace.visualstudio.com/items?itemName=pushqrdx.inline-html) otherwise this might be so ugly syntax wise though it will still be simply beautiful.\n\nAnd, also if you want, you can still just install z alone without any starters with command below\n\n```bash\nnpm install z-js-framework\n```\n\nor use a cdn link directly in your html file, put it in the head or body tag in index.html file of your project.\n\n```html\n\u003cscript src=\"https://cdn.jsdelivr.net/npm/z-js-framework@latest/dist/z.js\"\u003e\u003c/script\u003e\n```\n\nOr for the ninjas, grab the z.js script file from Z.Js github repo in dist directory and include it in your project.\n\nOne other thing once again, VS Code Extension, [Inline HTML](https://marketplace.visualstudio.com/items?itemName=pushqrdx.inline-html) (recommended)\n\nThis is not a must, but I must tell you that Z Js uses JavaScript template literals even for templating or crafting your UI, for example:\n\n```html\nimport { html } from 'z-js-framework'\n\nlet name = 'Kizz'\nlet greetElement = html`\u003ch1\u003eHello there, ${name}\u003c/h1\u003e`\n```\n\nNow, as you can see, it's pretty easy: just put your stuff in backticks, but we know the IDE won't highlight that as HTML but as a normal string, so for the best experience and auto completions to make it feel like real HTML, get this extension [Inline HTML](https://marketplace.visualstudio.com/items?itemName=pushqrdx.inline-html) as it will highlight them and give you some auto completions here and there, as we wait to work on our own Z.Js VS Code extension, you can use that extension and it will work just fine with Z.Js. If you want, just don't use it; it's still fine!\n\nOtherwise here is a quick view into the docs.\n\n## 🌟 Features\n\n- [Routing](#routing)\n- [Components And Styling](#components-and-styling)\n- [Global State](#global-state)\n- [Components State](#components-state)\n- [Navigation](#navigation)\n- [Reactivity](#️-reactivity)\n- [Hooks](#hooks)\n- [Rendering Lists](#lists)\n- [Fetching](#fetching)\n\nMore Features coming, see the [Roadmap](./sidenotes.md#roadmap-and-features-if-you-like-to-contribute)\n\n## ❤️ Demos?\n\n- [Z-chat](https://github.com/Hussseinkizz/z-chat) -- demo chat app made using z js framework and socket io\n- [Z-Tailwind-Demo](https://github.com/BakungaBronson/Z-Tailwind-Demo) -- demo app showing how to use tailwindcss with z js framework\n- [z-js-short-wave](https://github.com/KimmyDavis/z-js-short-wave) -- audio player app made using z js framework, enjoy the live demo [🎶 here](https://z-shot-wave.netlify.app/)\n- [Z Whack A Mole](https://github.com/Hussseinkizz/mini-game) -- 🎮 A just for fun little mini game made with z js, [live demo](https://z-mini-game.netlify.app/)\n- [Dev-Encyclopedia](https://github.com/Hussseinkizz/Dev-Encyclopedia) -- A just for demo purposes fork and z js implementation of [Dev-Encyclopedia](https://github.com/Buzzpy/Dev-Encyclopedia), [live demo](https://devpedia.netlify.app/)\n\nWe will be providing more examples, you can also submit your own examples in the [issues](https://github.com/Z-Js-Framework/z-js/issues) section. Am excited to see what you build for sure!\n\n## 🎯 Documentation\n\n\u003e ✅ Routing \u003ca name=\"routing\"\u003e\u003c/a\u003e\n\n``` js\n'use strict';\n\nimport { render } from 'z-js-framework';\nimport About from './pages/about.js';\nimport Home from './pages/home.js';\nimport Layout from './pages/layout.js';\nimport NotFound from './pages/notFound.js';\n\nconst root = document.querySelector('#root');\n\nconst routes = [\n  {\n    route: '/',\n    component: Home,\n  },\n  {\n    route: '/about',\n    component: About,\n  },\n  {\n    route: '/*',\n    component: NotFound,\n  },\n];\n\n// render the app\nrender(root, routes);\n```\n\nThen, have an index HTML file that can act as the entry point for your application in the browser. It can look like this: no magic, just a simple HTML file with a script tag pointing to your index.js file with a type module attribute to tell the browser that it's a module that can import other JS files; otherwise, in there, you can do normal stuff like add a style tag if you like, just make sure the there's an element with root id so that's where z will render the app as seen in the first step above.\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml lang=\"en\"\u003e\n\n\u003chead\u003e\n  \u003cmeta charset=\"UTF-8\"\u003e\n  \u003cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\"\u003e\n  \u003ctitle\u003eZ App\u003c/title\u003e\n  \u003cscript src=\"./index.js\" defer type=\"module\"\u003e\u003c/script\u003e\n  \u003clink rel=\"stylesheet\" href=\"style.css\"\u003e\n\u003c/head\u003e\n\n\u003cbody\u003e\n  \u003cdiv id=\"root\"\u003e--loading app--\u003c/div\u003e\n\u003c/body\u003e\n\n\u003c/html\u003e\n```\n\nNow, let's have a look at a Z Js component, a simple re-usable button component. It can be found in `example/components/button.js` and here is how it's implemented.\n\n\u003e ✅ Components \u0026 Styling \u003ca name=\"components-and-styling\"\u003e\u003c/a\u003e\n\n```js\nimport { css, html } from 'z-js-framework';\n\nexport const Button = (children, setCount) =\u003e {\n  const buttonClass = css`\n    background-color: tomato;\n    color: #fff;\n    display: flex;\n    gap: 1rem;\n    border-radius: 4px;\n    padding: 0.5rem 1rem;\n    transition: background-color 0.2s;\n    margin-top: 1rem;\n\n    \u0026:hover {\n      background-color: crimson;\n    }\n  `;\n\n  const clickButton = () =\u003e {\n    console.log('button clicked!');\n    setCount((currentCount) =\u003e currentCount + 1);\n  };\n\n  return html`\u003cbutton class=\"${buttonClass}\" onClick=\"${clickButton}\"\u003e\n    ${children}\n  \u003c/button\u003e`;\n};\n\n```\n\nOhh, so you are wondering what's happening? Don't freak, let me explain:\n\n1. First, we import `css` and `html` from z.js, `css` is a function that takes a CSS template literal and returns a class name that you can use on your class attribute. It automatically creates those styles you define on that class with css tag function and makes sure they are not recreated if they have not changed. It's like a builtin css-in-js solution. Just write CSS, z will handle the rest, and then similarly, the `html` is a function that takes a template literal and returns an HTML element out of it. You can use it to render your components, and it returns a normal dom element with all events bound, like onclick event in this example.\n2. Since these are just literals, we use `${__expression__}` syntax to interpolate the values; in this case, we are interpolating the value of `children` and `setCount`, which are the props passed to the component, and we are also interpolating the `clickButton` function which is the event handler for the button.\n3. We then export our Button function or component for re-usability; that's it.\n\nCongratulations! You have just created your first Z Js component. Now, let's use it on a page. Let's see how a home page with a button looks, along with some other concepts, state and routing.\n\n\u003e ✅ Global State Management \u003ca name=\"global-state\"\u003e\u003c/a\u003e\n\nHere is how you would manage complex state in your z applications, create a file say store.js and define and export your global states, these you can then import and use elsewhere in your app components, no need to wrap into any providers or contexts. It's that dead simple as illustrated below.\n\n```js\n\nimport { createStore } from 'z-js-framework';\n\nexport const countStore = createStore(100);\n\nexport const authStore = createStore(false);\n\n// there's a lot you can do, channel.getHistor() for example gets the store state history upto 10 previous versions\nconst { getValue, setValue, subScribe, channel } = createStore({\n  name: 'z-js-framework',\n  age: 1,\n});\n\n// access store state\nconsole.log(countStore.getValue()); // 100\n\n// run everytime state changes\nauthStore.subScribe((newState) =\u003e {\n  console.log('auth changed::', newState);\n});\n```\n\nthen in any component you can just do something like...\n\n```js\nimport {\n  html,\n  reactive,\n  useEffect,\n  useStore,\n  useRouter,\n} from 'z-js-framework';\nimport { authStore } from '../store.js';\n\nexport const AuthComponent = () =\u003e {\n  const [user, setUser] = useStore(authStore);\n\n  const router = useRouter();\n\n  useEffect(() =\u003e {\n    if (!user.value) {\n      router.goTo('/login');\n    }\n  }, []);\n\n  let UI = html`\n    \u003cdiv\u003e\n      \u003ch1\u003eHello, ${user.value.userName}\u003c/h1\u003e\n      \u003cbutton onclick=\"${() =\u003e setUser(null)}\"\u003eLogout\u003c/button\u003e\n    \u003c/div\u003e\n  `;\n\n  return reactive(UI);\n};\n```\n\nThe only thing to note here is we import useStore and pass in the store, it makes the state available to the component, and we can use it as a normal state variable within the component, and we can of course update it efficiently, all state updaets are granular and only affect their respective components. You can learn more about how state is handled and other interesting things you can do, z is powered by [State Radio](https://www.npmjs.com/package/state-radio) wrapped under hood for more simplicity but all state radio features can be accessed otherwise via the exposed state channels.\n\notherwise let's see in details how state works then on component level...\n\n\u003e ✅ Component Level State Management \u003ca name=\"components-state\"\u003e\u003c/a\u003e\n\n```js\nimport { css, html, useEffect, useState } from 'z-js-framework';\nimport { Button } from '../components/button.js';\n\nexport default function Home() {\n  // handle state\n  const [userName, setUserName] = useState('Z js Framework!');\n  const [count, setCount] = useState(0);\n\n  function handleInput(event) {\n    setUserName(event.target.value);\n  }\n\n  // define the markup\n  const home = html`\u003cdiv\u003e\n    \u003ch1\u003e${userName.value}\u003c/h1\u003e\n    \u003cp id=\"count\"\u003ecount: ${count.value}\u003c/p\u003e\n    \u003cinput\n      type=\"text\"\n      class=\"some-class\"\n      placeholder=\"just type something...\"\n      onChange=\"${handleInput}\" /\u003e\n    \u003c!-- Button Component Usage --\u003e\n    \u003cdiv class=\"flex-item\"\u003e${Button('+ Add One', setCount)}\u003c/div\u003e\n  \u003c/div\u003e`;\n\n  // react to state changes\n  useEffect(() =\u003e {\n    console.log('count changed::', count.current());\n    let countElement = home.querySelector('#count');\n    countElement.innerHTML = `count: ${count.current()}`;\n  }, [count]);\n\n  // return the home element\n  return home;\n}\n\n```\n\nWell, what's happening here? let's try to understand the code above.\n\n1. We again import different stuff from the Z Js framework. These are like hooks or utility functions, each doing a well-defined thing.\n\n2. We import the Button component from the components directory. We can also import other components from other directories; it's just a convention to keep all your components in a components directory. We already saw how such a component is made in previous steps!\n\n3. Since we already know about the HTML and CSS functions, let's look at the new ones here: useState and useEffect. These are much inspired by those of React, but make no mistake—they're quite different in how they work. This is not React!\n\n4. The useState returns the state object and a state setter, e.g. count and setCount. The state object has 2 properties that you can use for now: the value and current. The value is the current value of the state, the current is a function that returns the current value of the state, so you can use it to get the current value of the state, and the setter is a function that takes a new value and updates the state, so you can use it to update the state.\n\n    The state setter is useful when you want to update the state from a function or you want to update the state from a child component. While the current function on the state object is useful when you want to get the current value of the state from a child component or in a series of component and state lifecycle, basically in useffect use state.current() to access state's current value, not just state.value, you will be good.\n\n5. The useEffect is a function that takes a function and an array of state object dependencies. It's called when the dependencies change, and it's called after the component is rendered, so you can use it to react to state changes. You can also use it to fetch data from an API upon some change of state or do any other side effects, but make no mistake. Unlike react, this one only runs when the state changes. It's not run on render of component. It's like an event listener, which only happens when something happens, say, a change of state in this case.\n\n    Otherwise, if an empty state dependencies array is provided, the provided function is run only once and for all on component load. Otherwise, it would rerun this function every time any of the provided state-dependent objects change or never if they never change!\n\n6. Notice how we manually select the parts we want to update on state change from our home element and change its inner HTML. This is real DOM manipulation. The framework doesn't handle this for you as of now. You update what you want to update as you see fit, just like you would in vanilla JS. This is just a bit simplified, but not a replacement.\n\n7. Notice how we use state.current() inside the useEffect. This ensures we get the latest value of this state object; otherwise, state.value would be the old value of the state object, which would be the value of the state object at the time the component was rendered.\n\n8. State and state setters can be passed to child components as you see how setCount is being passed to the Button component.\n\n9. Unlike vanilla js literals here we can define our literals and attach events all at once, it's like jsx + template literals = jsx literals kind of, you see we attach the onChange handler on the input, and we do this by directly referencing the handleInput function, under the hood z js will create a real dom element out of this template and attach this as it should be, given in it's there in the component scope, or passed as an argument.\n\n10. All component or page functions in z return the created element, thats how we are able to reuse them and render them in the dom.\n\nAlmost that's all of Z as of now. Just one last thing, though...\nThis next part is how you link between pages.\n\n\u003e ✅ Navigation \u003ca name=\"navigation\"\u003e\u003c/a\u003e\n\n```js\nimport { html, useRouter } from 'z-js-framework';\n\nexport default function Layout() {\n  const { getParam } = useRouter();\n  let blogId = getParam('blogId');\n  console.log('param::', blogId);\n\n  return html`\n    \u003csection\u003e\n      \u003ch1\u003eLayout Page\u003c/h1\u003e\n      \u003cp\u003eThis is the about page.\u003c/p\u003e\n      \u003cdiv\u003e\n        \u003cz-link to=\"/\"\u003eHome\u003c/z-link\u003e\n        \u003cz-link to=\"/about\"\u003eAbout\u003c/z-link\u003e\n        \u003cz-link to=\"/about\" target=\"content\"\u003eLayout view\u003c/z-link\u003e\n        \u003ca href=\"https://www.google.com\"\u003eGoogle\u003c/a\u003e\n      \u003c/div\u003e\n      \u003cmain id=\"content\"\u003e-- dynamic content view --\u003c/main\u003e\n    \u003c/section\u003e\n  `;\n}\n\n```\n\nSo here we are doing a few things. Building on old concepts, we import the useRouter function from Z Js, and we use it to get the getParam function; this function takes a key as an argument and returns the value of the key in the URL. In this case, we are getting the blogId from the URL, we log it to the console, and then we return the template. We have a div with links to other pages and a main element with id content, and this is where we will render the dynamic content view.\n\n1. We use z-link to create links to other pages. It's a Z Js custom element that works with the router to route between pages. You pass the target attribute to it, which is the ID of the element in which you want to render the content. In this case, we are rendering the content in the main element with id content.\n2. Or the to attribute to it, which is the URL you want to route to. In this case we are routing to the about page or home page.\n3. Normal a anchor tag links work just fine, they will route to the URL you pass them as normal as they should.\n\n## ♻️ Reactivity\n\nAs with many modern frameworks, they are able to automatically re-render the app UI when the state changes, and they do this in kinda different ways, usually using the virtual dom to make sure only minimum changes are applied to the real dom. This is way better and more efficient than just saying element.innerHtml = newHtml, but then z is just real dom. We have no virtual dom, so you either have to do this step manually inside a useEffect or we reached out to some great library [Morphdom](https://github.com/patrick-steele-idem/morphdom) to enable us to do this in a smart way but with real dom, not virtual dom. You don't have to do anything on your end; you just wrap your component literal in a callback in our reactive function like below, and it will automatically reflect changes on state change. So cool, right? Here is an example:\n\n\u003e ✅ Reactivity \u003ca name=\"reactivity\"\u003e\u003c/a\u003e\n\n```js\nimport { html, reactive, useState } from 'z-js-framework';\n\nexport default function SomeComponent() {\n  const [userName, setUserName] = useState('Kizz');\n\n  const SomeElement = () =\u003e html`\n    \u003cdiv\u003e\n      \u003ch1\u003eUserName Is: ${userName}\u003c/h1\u003e\n      \u003cinput\n        type=\"text\"\n        value=\"${userName}\"\n        onChange=\"${(e) =\u003e setUserName(event.target.value)}\" /\u003e\n    \u003c/div\u003e`;\n\n  return reactive(SomeElement);\n}\n```\n\nUp above, the username will always change to a new value as the user types into the input.\n\n## 🗃️ Hooks And Utilities\n\n-- useSuspense: this hook helps you show a loading ui or fallback and then load the content when it's ready. useful when feteching data from an api or something.\nIt just takes in the promise or fetch function or any async one and a fallback element, and it will return the resolved value of the promise or the fallback element if the promise rejects. It can take retry, maxRetries and retryDelay as options, and it doesn't retry by default otherwise it retries 3 times by default when retry option is set to true.\n\n\u003e ✅ Hooks \u003ca name=\"hooks\"\u003e\u003c/a\u003e\n\n```js\nimport { html, useSuspense } from 'z-js-framework';\n\nconst fallback = html`\u003cp\u003eLoading... chill for now!\u003c/p\u003e`;\n\nexport default function Demo() {\n  const demoElement = html`\n    \u003cdiv\u003e\n      \u003ch1\u003eExample of a suspension...\u003c/h1\u003e\n      ${useSuspense(fetchContent, fallback)}\n    \u003c/div\u003e\n  `;\n\n  return demoElement;\n}\n\nfunction fetchContent() {\n  return new Promise((resolve, reject) =\u003e {\n    setTimeout(() =\u003e {\n      if (Math.random() \u003e 0.5) {\n        const content = html`\u003cp\u003eThis is the loaded content.\u003c/p\u003e`;\n        resolve(content);\n      } else {\n        reject('Failed to load content!!!');\n      }\n    }, 2000);\n  });\n}\n```\n\nThat shows loading, and then bingo shows the content.\n\n## 🌲 Rendering Lists\n\nZ Js has a few helpers to help you render lists or array of items. This is very useful when you working with a list of items or iterable data and you rendering them in a restrictive semantic element say a table or that you want to maintain the structure of the elements in dom exactly, i.e if elements a to be exactly direct children of the parent element, most frameworks provide helpers here such as the v-for in vue, etc. Here is how you can go about it in z.\n\n\u003e ✅ Rendering Lists \u003ca name=\"lists\"\u003e\u003c/a\u003e\n\n```js\nimport { html, useState, List, reactive } from 'z-js-framework';\nexport default function TodosPage() {\n  const [todos, setTodos] = useState([\n    {\n      id: 1,\n      task: 'something cool',\n      completed: true,\n    },\n    {\n      id: 2,\n      task: 'something again',\n      completed: false,\n    },\n  ]);\n   let UI = () =\u003e html`\n        \u003ctable class=\"todos-table\"\u003e\n          \u003ctbody ref=\"todoRef\"\u003e\n            ${List({\n              ref: 'todoRef',\n              items: todos,\n              render: ({ item: props }) =\u003e TodoItem({...props}),\n            })}\n          \u003c/tbody\u003e\n        \u003c/table\u003e`\n   return reactive(UI);\n}\n```\n\nAs you can see, the `List` utility takes in a few options, the ref is the ref of the parent element, items is the array of items to render, and render is the function that renders each item, it should return a single element and takes in each item in the items array as item which you can even alias as props.\n\n### 📥 Fetching\n\n\u003e ✅ Fetching Data \u003ca name=\"fetching\"\u003e\u003c/a\u003e\n\nZ Js is trying to be a responsible framework not letting you in a madness of extra tools to do common things and basic things that you need to do with almost every project, we instead make those as separate packages which we then have builtin so that you don't have to reach out to external libraries to achieve those common functionalities, sure there's when you must reach to external libraries but with z, not all the time, so here we have builtin fetch api wrapper with all advanced featurs you might need, use libs like axios for fetching at your own will but we got you covered, here is how you can do fetching in z applications.\n\n### GET Request\n\n``` js\nimport { GET } from 'z-js-framework';\n\nconst getPosts = async () =\u003e {\n   const { data, error, loading } = await GET('https://jsonplaceholder.typicode.com/posts');\n  if (data) {\n    console.log('Data:', data);\n  } else {\n    console.error('Error:', error.message);\n  }\n}\n```\n\n### POST Request\n\n``` js\nimport { POST } from 'z-js-framework';\n\nconst createPost = async () =\u003e {\n   const { data, error, loading } = await POST('https://jsonplaceholder.typicode.com/posts', {\n    body: {\n      title: 'dune',\n      body: 'a story about the dune verse!',\n      userId: 1,\n    }\n   });\n  if (data) {\n    console.log('Data:', data);\n  } else {\n    console.error('Error:', error.message);\n  }\n}\n```\n\n### PUT Request\n\n``` js\nimport { PUT } from 'z-js-framework';\n\nconst updatePost = async () =\u003e {\n   const { data, error, loading } = await PUT('https://jsonplaceholder.typicode.com/posts/1', {\n    body: {\n      title: 'dune latest',\n      body: 'a story about the dune verse has changed now the spices rule!',\n      userId: 1,\n    }\n   });\n  if (data) {\n    console.log('Data:', data);\n  } else {\n    console.error('Error:', error.message);\n  }\n}\n```\n\n### PATCH Request\n\n``` js\nimport { PATCH } from 'z-js-framework';\n\nconst modifyPost = async () =\u003e {\n   const { data, error, loading } = await PATCH('https://jsonplaceholder.typicode.com/posts/1', {\n    body: {\n      title: 'dune movie'\n    }\n   });\n  if (data) {\n    console.log('Data:', data);\n  } else {\n    console.error('Error:', error.message);\n  }\n}\n```\n\n### DELETE Request\n\n``` js\nimport { DELETE } from 'z-js-framework';\n\nconst deletePost = async () =\u003e {\n   const { error } = await DELETE('https://jsonplaceholder.typicode.com/posts/1');\n  if (!error) {\n    console.log('item deleted successfully!');\n  } else {\n    console.error('Error Deleting Item:', error.message);\n  }\n}\n```\n\n### Setting Global Configuration\n\n```js\nimport { setConfig, GET } from 'z-js-framework';\n\nsetConfig({\n  baseUrl: 'https://jsonplaceholder.typicode.com',\n  timeout: 5000,\n  withCredentials: false,\n  parseJson: true,\n});\n\nconst getPosts = async () =\u003e {\n   const { data, error, loading } = await GET('/posts');\n  if (data) {\n    console.log('Data:', data);\n  } else {\n    console.error('Error:', error.message);\n  }\n}\n```\n\nor set per request\n\n```js\nimport { GET } from 'z-js-framework';\n\nconst getPosts = async () =\u003e {\n   const { data, error, loading } = await GET('https://jsonplaceholder.typicode.com/posts', {\n    parseJson: false,\n     headers: {\n    'Content-Type': 'application/text',\n     },\n     retry: true,\n     maxRetries: 3,\n   });\n\n  if (data) {\n    console.log('Data:', data);\n  } else {\n    console.error('Error:', error.message);\n  }\n}\n```\n\nYou can of course do a lot more, see our mighty [Z-Fetch](https://github.com/Z-Js-Framework/z-fetch) for complete docs on what you can do, all nitty gritties covered.\n\nEnjoy buildinga cool things with z js, that's it for now, we are working on more docs and examples, stay tuned!\n\n## 😇 What if You want more?\n\nCome on, more stuff is coming, and if you reach all the way here, you are really a samurai now. You can start using Z Js to build your next app. See the examples folder for some examples, as we prepare more docs later, but that's it for now, that's Z Js framework, let's get building!\n\nMore documentation and examples of common use cases will be coming soon. Help contribute!\n\n## ✍️ Authors \u003ca name = \"authors\"\u003e\u003c/a\u003e\n\n- [@HusseinKizz](https://github.com/Hussseinkizz) - Z Js Creator\n\nYou can also see the full list of all awesome [contributors](https://github.com/Z-Js-Framework/z-js/graphs/contributors) who participated on this awesome project.\n\n## 🎉 Acknowledgements \u003ca name = \"acknowledgement\"\u003e\u003c/a\u003e\n\n- Shout out to [Kimmy Davis](https://github.com/KimmyDavis) for making the first coolest z js app, an audio player that actually works: [z shot-wave](https://z-shot-wave.netlify.app/) oof!\n- Shout out to [Bakunga Bronson](https://github.com/BakungaBronson) for making the first external pr and z js tailwind css demo!\n- Shout out to [Rasmus Schultz](https://x.com/mindplaydk) for making the first criticism about z's rendering and advising on the subsquent re-rendering improvements we have been making, he has benchmarked all vdom algorithms for example and has helped alot to see z improve to such heights too, a journey we still on!\n- React, Vue, And Solid Frameworks for inspiring Z js Framework and pioneering some of the paradimns adaptod here.\n- shout out to [Morphdom](https://github.com/patrick-steele-idem/morphdom) it is great dom diffing library and we used it to handle dom diffing efficiently!\n- Finally [Pionia Framework](https://pionia.netlify.app) also deserves a shout out for being the first backend framework to support z js out of the box, check it out, they really got some cool stuff there!\n- Thanks all friends who contributed thogugh wise to guide the z philosophy and approach.\n\n## 👾 What Next?\n\nWell, this is still work in progress. I am working on it in my little free time, so if you have other ideas or what, reach out to me at [hssnkizz@gmail.com](hssnkizz@gmail.com) or read [Contribution Guide](./CONTRIBUTION.MD) to get started on how things work and the whole project plan and roadmap!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz-js-framework%2Fz-js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fz-js-framework%2Fz-js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fz-js-framework%2Fz-js/lists"}