{"id":29557718,"url":"https://github.com/aminehabchi/mini-framework","last_synced_at":"2025-07-18T11:16:30.295Z","repository":{"id":301884473,"uuid":"946810810","full_name":"aminehabchi/mini-framework","owner":"aminehabchi","description":"Build a lightweight front-end JavaScript framework built from scratch","archived":false,"fork":false,"pushed_at":"2025-06-29T11:10:44.000Z","size":26,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-06-29T12:24:35.686Z","etag":null,"topics":["framework","javascript","mini-framework","oop","react","spa"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/aminehabchi.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"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":"2025-03-11T17:57:15.000Z","updated_at":"2025-06-29T11:11:12.000Z","dependencies_parsed_at":"2025-06-29T12:24:57.523Z","dependency_job_id":"769e1e77-9400-4581-bbee-de44fd824352","html_url":"https://github.com/aminehabchi/mini-framework","commit_stats":null,"previous_names":["aminehabchi/mini-framework"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aminehabchi/mini-framework","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehabchi%2Fmini-framework","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehabchi%2Fmini-framework/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehabchi%2Fmini-framework/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehabchi%2Fmini-framework/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aminehabchi","download_url":"https://codeload.github.com/aminehabchi/mini-framework/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aminehabchi%2Fmini-framework/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":265748222,"owners_count":23822065,"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":["framework","javascript","mini-framework","oop","react","spa"],"created_at":"2025-07-18T11:16:23.142Z","updated_at":"2025-07-18T11:16:29.665Z","avatar_url":"https://github.com/aminehabchi.png","language":"JavaScript","readme":"# 🧩 Custom JavaScript Framework\n\nA lightweight front-end JavaScript framework built from scratch, featuring **virtual DOM**, **component-based architecture**, **client-side routing**, and **state management**. Perfect for learning how modern frameworks like React work under the hood or for building small SPAs.\n\n---\n\n## ✨ Features\n\n- 🔄 **Virtual DOM** with efficient diffing and patching\n- 🧱 **Component-based architecture** with lifecycle methods\n- 🗺️ **Client-side routing** with navigation\n- 📊 **Global and local state management**\n- 📌 **Reference system** for DOM element access\n- 🧹 **Automatic event cleanup** on route changes\n\n---\n\n## 📁 Project Structure\n\n```\n/framework\n  ├── framework.js     # Core Framework class with routing \u0026 state\n  ├── component.js     # Base Component and NotFoundComponent classes\n  └── helpers.js       # Virtual DOM creation, diffing, and patching\n```\n\n---\n\n## 🚀 Quick Start\n\n### 1. Setup\n\nInclude the framework in your HTML:\n\n```html\n\u003c!DOCTYPE html\u003e\n\u003chtml\u003e\n\u003chead\u003e\n    \u003ctitle\u003eMy App\u003c/title\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n    \u003cdiv id=\"app\"\u003e\u003c/div\u003e\n    \u003cscript type=\"module\" src=\"./main.js\"\u003e\u003c/script\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n```\n\n### 2. Initialize your app\n\nCreate `main.js`:\n\n```js\nimport { Framework } from './framework/framework.js';\nimport { Home, Game } from './components.js';\n\nexport const app = new Framework({ score: 0 });\n\n// Define routes\napp.route(\"/\", Home);\napp.route(\"/game\", Game);\n\n// Start the application\napp.start();\n```\n\n---\n\n## 📖 API Reference\n\n### 🧱 Components\n\nAll components extend the base `Component` class and must implement `getVDom()`:\n\n```js\nimport { Component } from './framework/component.js';\nimport { createVElement } from './framework/helpers.js';\n\nexport class Home extends Component {\n  getVDom() {\n    return createVElement(\"div\", { class: \"home\" }, [\n      createVElement(\"h1\", {}, [\"Welcome to My App!\"]),\n      createVElement(\"button\", { \n        onclick: () =\u003e this.framework.navigateTo(\"/game\") \n      }, [\"Start Game\"])\n    ]);\n  }\n\n  mounting() {\n    console.log(\"Home component mounted\");\n  }\n\n  unmounting() {\n    console.log(\"Home component unmounting\");\n  }\n}\n```\n\n### 🔧 Virtual DOM\n\nCreate elements using `createVElement(tag, props, children)`:\n\n```js\n// Simple element\ncreateVElement(\"h1\", {}, [\"Hello World\"]);\n\n// Element with props\ncreateVElement(\"div\", { id: \"container\", class: \"wrapper\" }, [\n  createVElement(\"p\", {}, [\"Content here\"])\n]);\n\n// Element with event handlers\ncreateVElement(\"button\", { \n  onclick: () =\u003e console.log(\"Clicked!\") \n}, [\"Click Me\"]);\n```\n\n### 📊 State Management\n\n```js\n// Set state and trigger re-render\nthis.framework.setState(\"score\", 100);\n\n// Set state without re-render\nthis.framework.setWState(\"temporary\", true);\n\n// Get state value\nconst currentScore = this.framework.getState(\"score\");\n```\n\n### 📌 References\n\nAccess DOM elements directly:\n\n```js\n// Create element with ref\ncreateVElement(\"input\", { ref: \"userInput\", type: \"text\" }, []);\n\n// Access the DOM element later\nconst inputElement = this.framework.getRef(\"userInput\");\ninputElement.focus();\n```\n\n### 🗺️ Routing\n\n```js\n// Define routes\napp.route(\"/\", HomeComponent);\napp.route(\"/about\", AboutComponent);\napp.route(\"/contact\", ContactComponent);\n\n// Navigate programmatically\nthis.framework.navigateTo(\"/about\");\n```\n\n### 🔄 Lifecycle Methods\n\n```js\nclass MyComponent extends Component {\n  mounting() {\n    // Called after component is first rendered\n    this.setupEventListeners();\n  }\n\n  unmounting() {\n    // Called before navigating away from this component\n    this.cleanup();\n  }\n}\n```\n\n---\n\n## 💡 Complete Example\n\n```js\nimport { Component } from './framework/component.js';\nimport { createVElement } from './framework/helpers.js';\n\nclass Counter extends Component {\n  getVDom() {\n    const count = this.framework.getState(\"count\") || 0;\n    \n    return createVElement(\"div\", { class: \"counter\" }, [\n      createVElement(\"h2\", {}, [\"Counter App\"]),\n      createVElement(\"p\", {}, [`Count: ${count}`]),\n      createVElement(\"div\", {}, [\n        createVElement(\"button\", { \n          onclick: () =\u003e this.increment() \n        }, [\"+\"]),\n        createVElement(\"button\", { \n          onclick: () =\u003e this.decrement() \n        }, [\"-\"]),\n        createVElement(\"button\", { \n          onclick: () =\u003e this.reset() \n        }, [\"Reset\"])\n      ])\n    ]);\n  }\n\n  increment() {\n    const current = this.framework.getState(\"count\") || 0;\n    this.framework.setState(\"count\", current + 1);\n  }\n\n  decrement() {\n    const current = this.framework.getState(\"count\") || 0;\n    this.framework.setState(\"count\", current - 1);\n  }\n\n  reset() {\n    this.framework.setState(\"count\", 0);\n  }\n\n  mounting() {\n    console.log(\"Counter component mounted\");\n  }\n\n  unmounting() {\n    console.log(\"Counter component unmounting\");\n  }\n}\n```\n\n---\n\n## 🎯 Best Practices\n\n- **Keep components small and focused** - Each component should have a single responsibility\n- **Use refs sparingly** - Prefer state-driven updates over direct DOM manipulation\n- **Clean up in unmounting()** - Remove timers, intervals, or external listeners\n- **Leverage the virtual DOM** - Let the framework handle DOM updates for you\n\n---\n\n## 🔧 Browser Support\n\nThis framework uses modern JavaScript features:\n- ES6 Modules\n- Arrow functions\n- Destructuring\n- Optional chaining\n\nSupported browsers: Chrome 61+, Firefox 60+, Safari 10.1+, Edge 16+\n\n---\n\n## 🚀 What's Next?\n\nThis framework demonstrates core concepts found in production frameworks. To extend it further, consider adding:\n\n- Component props and data passing\n- Computed properties and watchers\n- Animation and transition system\n- Server-side rendering support\n- Development tools and debugging\n\n---\n\n## 🤝 Contributing\n\nContributions are welcome! Feel free to:\n- Report bugs or suggest features\n- Fork the project and submit pull requests\n- Use this framework in your own projects\n- Share your learning experience\n\n---\n\n## 📄 License\n\nThis project is open source and available under the [MIT License](LICENSE).","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faminehabchi%2Fmini-framework","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faminehabchi%2Fmini-framework","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faminehabchi%2Fmini-framework/lists"}