{"id":20790335,"url":"https://github.com/lewis-wow/kiq","last_synced_at":"2026-05-12T07:32:28.399Z","repository":{"id":57289278,"uuid":"336854161","full_name":"lewis-wow/Kiq","owner":"lewis-wow","description":"Blazing fast virtual DOM class component based library for reactive UI","archived":false,"fork":false,"pushed_at":"2023-09-26T10:29:33.000Z","size":736,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-10T04:49:16.262Z","etag":null,"topics":["blazing-fast","component","declarative-ui","dom","front-end","html","javascript","reactive","ui","virtual","virtual-dom-library"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/lewis-wow.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,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-07T18:03:23.000Z","updated_at":"2024-08-28T02:14:23.000Z","dependencies_parsed_at":"2023-02-12T08:35:13.151Z","dependency_job_id":"6eca3d8d-cffb-4a71-ad52-11abc270d975","html_url":"https://github.com/lewis-wow/Kiq","commit_stats":null,"previous_names":["ujikcz/kiq"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewis-wow%2FKiq","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewis-wow%2FKiq/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewis-wow%2FKiq/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/lewis-wow%2FKiq/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/lewis-wow","download_url":"https://codeload.github.com/lewis-wow/Kiq/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243136282,"owners_count":20241988,"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":["blazing-fast","component","declarative-ui","dom","front-end","html","javascript","reactive","ui","virtual","virtual-dom-library"],"created_at":"2024-11-17T15:34:06.140Z","updated_at":"2026-05-12T07:32:28.355Z","avatar_url":"https://github.com/lewis-wow.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kiq.js\n\nBlazing fast virtual DOM class component based library for reactive UI\n\n## Inspiration\n\nReact.js, Jason Yu that creates simple virtual DOM library in about 50 minutes\n\n## Goal\n\nGoal is to create very simple, lightweight and very fast virtual DOM library with smart diff algorithm and performance optimalizations.\n\n## Optimalizations\n\nFirst render is called with requestAnimationFrame, so the main thread is no blocked and components will render when browser is ready to reflow and repaint the page.\n\nEvery changes are called as one big bundle of changes in one time, so browser don't reflow and repaint every time for every small change in DOM but 1 repaint and reflow for one state change.\n\n## Components\n\nComponents are javascript classes with special methods.\n\n## createElement\n\nThere are many posibilities how to create a virtual element. Some of them are with cleaner syntax.\n\n## Virtual element\n\nVirtual element is plain javascript object.\n\n### vanilla js\n\n```js\nKiq.createElement('div', { className: 'test' }, count)\n```\n\n### htm.js\n\nhtm is library that transforms template literals to virtual element.\n\n```js\nconst html = htm.bind(Kiq.createElement);\n\nhtml`\u003cdiv className=\"test\"\u003e${count}\u003c/div\u003e`\n```\n\n### babel jsx\n\njsx is Javascript XML, babel can compile the jsx code to `createElement` functions.\nThe code must start with jsx pragma.\nIt provides HTML-like syntax.\n\n```js\n/** @jsx Kiq.createElement */\n\n\u003cdiv className=\"test\"\u003e{count}\u003c/div\u003e\n```\n\n### create components\n\nProduce components is the same as virtual nodes, but the first parameter replace tag name with your component class.\nAttributes are props and children are ```props.children```.\n\n### props.children\n\nIn the component props can be passed as children too.\nYour children are then in props.children array.\n\n```js\n\u003cParent\u003e\n  \u003cChild /\u003e\n\u003c/Parent\u003e\n```\n\n```js\nKiq.createElement(Parent, null, \n  Kiq.createElement(Child)\n);\n```\n\nThe Parent component has now access to special ```props.children``` Array where on the first index is `Child` component.\n\n## render\n\nThis function should be called only once in the whole app.\nIt renders your app and produce real DOM objects and mount them to your page.\n\n```js\nKiq.render(Kiq.createElement(App), document.getElementById('app'));\n```\n\n## Components example\n\n``` js\nclass Counter extends Kiq.Component {\n  state = {\n    count: 0,\n  }\n\n  Element(props, state) {\n    return (\n      \u003cbutton onclick={() =\u003e this.setState({ count: state.count + 1 })}\u003e\n        {state.count}\n      \u003c/button\u003e\n    )\n  }\n}\n```\n\n## Kiq in ES5\n\nIf you want to your code is compatible with IE11 and other ES5 browsers you can use some javascript bundler to compile the code down to ES5.\n\n## state and props\n\nThese two are data that is used inside component.\nSimply props are \"function parameters\" and state are \"function local variables\", so props are not private inside component and income from the outside.\nState are private in component and there is not way to set state of component in another component (actually there is a way to do that, it is in the article below).\nState are reactive object, props are non reactive object, props should be only read-only.\n\n## setState\n\nComponent.setState component method can be only called if component is rendered, will mount or is mounted, else it throws error.\nYou shouldn't to mutate the original value of state as you can see in the example, instead of ```++state.count``` use ```state.count + 1```.\nEvery changes should be immutable.\nOn every setState call component will rerender, so on multiple changes, use setState only once and do all the changes in one.\nsetState is synchronnous function.\n\n### Can I set props?\n\nNo. There is no way to set props, because it is anti-pattern.\nProps should be read-only.\n\n### How to setState of parent component inside child component?\n\nIt is simple, you have to pass the \"setter\" function to the props of child component like this:\n\n```js\nclass Parent extends Kiq.Component {\n  state = {\n    count: 0,\n  }\n\n  setCount() {\n    this.setState({\n      count: this.state.count + 1,\n    })\n  }\n\n  Element(props, state) {\n    return \u003cChild setCount={this.setCount} count={state.count} /\u003e\n  }\n}\n\nclass Child extends Kiq.Component {\n  Element(props, state) {\n    return \u003cbutton onclick={props.setCount}\u003e{props.count}\u003c/button\u003e\n  }\n}\n```\n\n### Kiq.Component vs WebComponents\n\nWebComponents are encapsulated DOM elements, but Kiq.Component is logical encapsulation of element and data definition, where is used declarative DOM management.\n\n### Conditional rendering\n\n```js\nclass Fetch extends Kiq.Component {\n  state = {\n    books: null,\n  }\n\n  onComponentRender() {\n    fetch(\"https://www.anapioficeandfire.com/api/books\")\n      .then((res) =\u003e res.json())\n      .then((res) =\u003e {\n        this.setState({\n          books: res,\n        })\n      })\n  }\n\n  Element() {\n    if (!this.state.books) {\n      return \u003ch1\u003eLoading...\u003c/h1\u003e\n    }\n\n    return \u003cdiv\u003e{JSON.stringify(this.state.books)}\u003c/div\u003e\n  }\n}\n```\n\n### List rendering\n\n```js\nclass List extends Kiq.Component {\n  state = {\n    arr: [0, 1, 2, 3, 4],\n  }\n\n  Element() {\n    return (\n      \u003cul\u003e\n        {this.state.arr.map((item) =\u003e \u003cli key={item}\u003e{item}\u003c/li\u003e)}\n      \u003c/ul\u003e\n    )\n  }\n}\n```\n\n### Simple mouse move\n\nSimple mouse move example to show how easy is declarative way of DOM changes.\nDeclarative programming means you say what to do, but no how to do.\n\n```js\nclass MouseMove extends Kiq.Component {\n  state = {\n    x: 0,\n    y: 0,\n    count: 0,\n  }\n\n  onComponentRender() {\n    window.addEventListener(\"mousemove\", (e) =\u003e {\n      this.setState({\n        x: e.x,\n        y: e.y,\n      })\n    })\n  }\n\n  Element(props, state) {\n    return (\n      \u003cbutton\n        onclick={() =\u003e this.setState({ count: state.count + 1 })}\n        style={{\n          position: \"absolute\",\n          left: this.state.x + \"px\",\n          top: this.state.y + \"px\",\n        }}\n      \u003e\n        {state.count}\n      \u003c/button\u003e\n    )\n  }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewis-wow%2Fkiq","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flewis-wow%2Fkiq","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flewis-wow%2Fkiq/lists"}