{"id":50200863,"url":"https://github.com/olovajs/olova","last_synced_at":"2026-06-11T14:00:35.159Z","repository":{"id":254565770,"uuid":"846916416","full_name":"olovajs/olova","owner":"olovajs","description":"A smooth, minimal library for infusing JavaScript with dynamic behaviour","archived":false,"fork":false,"pushed_at":"2025-05-31T00:23:48.000Z","size":710,"stargazers_count":175,"open_issues_count":0,"forks_count":21,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-05-31T11:03:32.010Z","etag":null,"topics":["bangladesh","fornt-end","javascript","javascript-framework","javascript-library","jsx","olova","ui-design"],"latest_commit_sha":null,"homepage":"https://olova.js.org","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/olovajs.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,"zenodo":null}},"created_at":"2024-08-24T10:12:48.000Z","updated_at":"2025-05-31T00:23:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"780eb3e4-2063-4927-a5f9-a060baafdb38","html_url":"https://github.com/olovajs/olova","commit_stats":null,"previous_names":["deshijs/deshijs","olovajs/olova"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/olovajs/olova","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olovajs%2Folova","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olovajs%2Folova/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olovajs%2Folova/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olovajs%2Folova/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/olovajs","download_url":"https://codeload.github.com/olovajs/olova/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/olovajs%2Folova/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34201842,"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-11T02:00:06.485Z","response_time":57,"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":["bangladesh","fornt-end","javascript","javascript-framework","javascript-library","jsx","olova","ui-design"],"created_at":"2026-05-25T22:00:42.189Z","updated_at":"2026-06-11T14:00:35.148Z","avatar_url":"https://github.com/olovajs.png","language":"JavaScript","funding_links":[],"categories":["Developer Tools \u0026 Libraries"],"sub_categories":["🚀 How to contribute"],"readme":"# 🚀 Olova.js\n\nA lightweight, reactive JavaScript framework for building modern web\napplications. Olova.js provides a simple yet powerful API for creating reactive\nUIs with JSX support.\n\n## ✨ Features\n\n- 🎯 **Signals** - Reactive state management\n- 🔄 **Effects** - Automatic dependency tracking and side effects\n- 📝 **Memos** - Computed values with dependency tracking\n- 🎨 **JSX Support** - Write components using familiar JSX syntax\n- 🎭 **Components** - Function-based component system\n- 🔗 **Refs** - Direct DOM node references\n- 🎪 **Lifecycle Hooks** - `onMount` and `onUnmount` for component lifecycle\n  management\n- 🧩 **Fragments** - Support for multiple root elements\n- 🎨 **SVG Support** - First-class SVG element support\n\n## 📦 Installation\n\n```bash\n# Create a new project (recommended)\nnpm create vilo@latest\n\n# Or install directly in an existing project\nnpm install olova\n```\n\nFor now, you can use it directly in your project by copying the core files.\n\n## 🚀 Quick Start Guide\n\n### 1. Basic Counter Example\n\nA simple counter showing reactive state management:\n\n```jsx\nimport { render, setSignal } from \"./core/core.js\";\n\nconst Counter = () =\u003e {\n  const [count, setCount] = setSignal(0);\n\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003e{() =\u003e count()}\u003c/h1\u003e\n      \u003cbutton onClick={() =\u003e setCount(count() + 1)}\u003eIncrement\u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### 2. Multiple Elements with Fragment\n\nUsing fragments to render multiple elements:\n\n```jsx\nimport { render, Fragment } from \"./core/core.js\";\n\nconst MultipleElements = () =\u003e {\n  return (\n    \u003c\u003e\n      \u003cdiv\u003eFirst\u003c/div\u003e\n      \u003cdiv\u003eSecond\u003c/div\u003e\n    \u003c/\u003e\n  );\n};\n```\n\n### 3. Effects and Reactivity\n\nDemonstrating reactive effects:\n\n```jsx\nimport { render, setSignal, setEffect } from \"./core/core.js\";\n\nconst EffectsExample = () =\u003e {\n  const [name, setName] = setSignal(\"John\");\n\n  setEffect(() =\u003e {\n    console.log(`Name changed to: ${name()}`);\n  });\n\n  return (\n    \u003cdiv\u003e\n      \u003cinput\n        value={() =\u003e name()}\n        onInput={(e) =\u003e setName(e.target.value)}\n        type=\"text\"\n      /\u003e\n      \u003cp\u003eCurrent name: {() =\u003e name()}\u003c/p\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### 4. Computed Values with Memos\n\nUsing memos for derived state:\n\n```jsx\nimport { render, setSignal, setMemo } from \"./core/core.js\";\n\nconst MemoExample = () =\u003e {\n  const [firstName, setFirstName] = setSignal(\"John\");\n  const [lastName, setLastName] = setSignal(\"Doe\");\n\n  const fullName = setMemo(() =\u003e `${firstName()} ${lastName()}`);\n\n  return (\n    \u003cdiv\u003e\n      \u003cinput\n        value={() =\u003e firstName()}\n        onInput={(e) =\u003e setFirstName(e.target.value)}\n        placeholder=\"First Name\"\n      /\u003e\n      \u003cinput\n        value={() =\u003e lastName()}\n        onInput={(e) =\u003e setLastName(e.target.value)}\n        placeholder=\"Last Name\"\n      /\u003e\n      \u003cp\u003eFull name: {() =\u003e fullName()}\u003c/p\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### 5. DOM References with Refs\n\nDirect DOM manipulation using refs:\n\n```jsx\nimport { render, setRef } from \"./core/core.js\";\n\nconst RefsExample = () =\u003e {\n  const inputRef = setRef();\n\n  return (\n    \u003cdiv\u003e\n      \u003cinput ref={inputRef} type=\"text\" placeholder=\"Focus me!\" /\u003e\n      \u003cbutton onClick={() =\u003e inputRef().focus()}\u003eFocus Input\u003c/button\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### 6. Component Lifecycle\n\nManaging component lifecycle with hooks:\n\n```jsx\nimport { render, setSignal, onMount, onUnmount } from \"./core/core.js\";\n\nconst LifecycleExample = () =\u003e {\n  const [isVisible, setIsVisible] = setSignal(true);\n\n  const ChildComponent = () =\u003e {\n    onMount(() =\u003e {\n      console.log(\"Component mounted\");\n    });\n\n    onUnmount(() =\u003e {\n      console.log(\"Component will unmount\");\n    });\n\n    return \u003cdiv\u003eHello World\u003c/div\u003e;\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={() =\u003e setIsVisible(!isVisible())}\u003e\n        {() =\u003e (isVisible() ? \"Hide\" : \"Show\")}\n      \u003c/button\u003e\n      {() =\u003e isVisible() \u0026\u0026 \u003cChildComponent /\u003e}\n    \u003c/div\u003e\n  );\n};\n```\n\n### 7. List Rendering\n\nBuilding a dynamic todo list:\n\n```jsx\nimport { render, setSignal } from \"./core/core.js\";\n\nconst TodoList = () =\u003e {\n  const [todos, setTodos] = setSignal([\n    { id: 1, text: \"Learn Olova.js\" },\n    { id: 2, text: \"Build an app\" },\n  ]);\n\n  const [newTodo, setNewTodo] = setSignal(\"\");\n\n  const addTodo = () =\u003e {\n    if (newTodo().trim()) {\n      setTodos([...todos(), { id: Date.now(), text: newTodo() }]);\n      setNewTodo(\"\");\n    }\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cdiv\u003e\n        \u003cinput\n          value={() =\u003e newTodo()}\n          onInput={(e) =\u003e setNewTodo(e.target.value)}\n          placeholder=\"New todo\"\n        /\u003e\n        \u003cbutton onClick={addTodo}\u003eAdd Todo\u003c/button\u003e\n      \u003c/div\u003e\n      \u003cul\u003e\n        {() =\u003e\n          todos().map((todo) =\u003e (\n            \u003cli key={todo.id}\u003e\n              {todo.text}\n              \u003cbutton\n                onClick={() =\u003e\n                  setTodos(todos().filter((t) =\u003e t.id !== todo.id))\n                }\n              \u003e\n                Delete\n              \u003c/button\u003e\n            \u003c/li\u003e\n          ))\n        }\n      \u003c/ul\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n### 8. Conditional Rendering\n\nDifferent patterns for conditional rendering:\n\n```jsx\nimport { render, setSignal } from \"./core/core.js\";\n\nconst Conditional = () =\u003e {\n  const [show, setShow] = setSignal(false);\n  const [theme, setTheme] = setSignal(\"light\");\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={() =\u003e setShow(!show())}\u003eToggle Content\u003c/button\u003e\n      \u003cbutton onClick={() =\u003e setTheme(theme() === \"light\" ? \"dark\" : \"light\")}\u003e\n        Toggle Theme\n      \u003c/button\u003e\n\n      {/* Simple conditional */}\n      {() =\u003e (show() ? \u003cp\u003eContent is shown\u003c/p\u003e : \u003cp\u003eContent is hidden\u003c/p\u003e)}\n\n      {/* Conditional with multiple elements */}\n      {() =\u003e\n        theme() === \"light\" ? (\n          \u003cdiv style={{ background: \"white\", color: \"black\" }}\u003eLight Theme\u003c/div\u003e\n        ) : (\n          \u003cdiv style={{ background: \"black\", color: \"white\" }}\u003eDark Theme\u003c/div\u003e\n        )\n      }\n\n      {/* Conditional rendering with \u0026\u0026 operator */}\n      {() =\u003e show() \u0026\u0026 \u003cp\u003eThis only shows when show is true\u003c/p\u003e}\n    \u003c/div\u003e\n  );\n};\n```\n\n### 9. Components and Props\n\nCreating and using reusable components with props:\n\n```jsx\nimport { render } from \"./core/core.js\";\n\n// Button component with props\nconst Button = ({ text, onClick }) =\u003e {\n  return (\n    \u003cbutton\n      onClick={onClick}\n      style={{\n        padding: \"8px 16px\",\n        borderRadius: \"4px\",\n        border: \"none\",\n        backgroundColor: \"#0070f3\",\n        color: \"white\",\n        cursor: \"pointer\",\n      }}\n    \u003e\n      {text}\n    \u003c/button\u003e\n  );\n};\n\n// Using the Button component\nconst App = () =\u003e {\n  return (\n    \u003cdiv\u003e\n      \u003ch1\u003eComponent Example\u003c/h1\u003e\n      \u003cButton text=\"Click me!\" onClick={() =\u003e alert(\"Button clicked!\")} /\u003e\n      \u003cButton\n        text=\"Another button\"\n        onClick={() =\u003e console.log(\"Second button clicked\")}\n      /\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\nThis example shows:\n\n- How to create a reusable component with props\n- Passing different props to multiple instances\n- Handling events through props\n- Applying inline styles to components\n\n## 🛠️ API Reference\n\n### Core Functions\n\n| Function                  | Description                                |\n| ------------------------- | ------------------------------------------ |\n| `setSignal(initialValue)` | Creates a reactive signal                  |\n| `setEffect(effectFn)`     | Creates an effect that tracks dependencies |\n| `setMemo(computeFn)`      | Creates a computed value                   |\n| `setRef()`                | Creates a ref for DOM elements             |\n| `render(component, root)` | Renders a component to the DOM             |\n| `onMount(callback)`       | Runs when component mounts                 |\n| `onUnmount(callback)`     | Runs when component unmounts               |\n| `Fragment`                | Wrapper for multiple elements              |\n| `html`                    | Internal function for DOM creation         |\n\n## 🤝 Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## 📄 License\n\nMIT License\n\n## 👨‍💻 Author\n\n**Nazmul Hossain**\n\n---\n\nFor more information and updates, please check back regularly as this framework\ncontinues to evolve.\n\n\u003e 💡 **Pro Tip**: Check out the `examples` directory in the source code for more\n\u003e detailed examples and best practices!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folovajs%2Folova","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Folovajs%2Folova","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Folovajs%2Folova/lists"}