{"id":13850854,"url":"https://github.com/aacgn/atomic","last_synced_at":"2025-08-31T04:32:04.880Z","repository":{"id":57093952,"uuid":"268190062","full_name":"aacgn/atomic","owner":"aacgn","description":"A JavaScript library for building atomic interfaces with vertical and horizontal micro-frontends","archived":false,"fork":false,"pushed_at":"2020-07-26T17:29:16.000Z","size":159,"stargazers_count":16,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-08-19T07:21:49.762Z","etag":null,"topics":["angular","atomic-template","atoms","dom-events","javascript","micro-frontend","micro-frontends","molecules","postmessage","reactjs","single-spa","transition-page","virtual-dom","vuejs"],"latest_commit_sha":null,"homepage":"","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/aacgn.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":"2020-05-31T01:40:23.000Z","updated_at":"2024-05-17T13:15:24.000Z","dependencies_parsed_at":"2022-08-22T19:31:25.577Z","dependency_job_id":null,"html_url":"https://github.com/aacgn/atomic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aacgn/atomic","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aacgn%2Fatomic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aacgn%2Fatomic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aacgn%2Fatomic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aacgn%2Fatomic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aacgn","download_url":"https://codeload.github.com/aacgn/atomic/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aacgn%2Fatomic/sbom","scorecard":{"id":158604,"data":{"date":"2025-08-11","repo":{"name":"github.com/aacgn/atomic","commit":"50d360468d4ff0a3b8da7b92ce98ad566e470e0c"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/29 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":"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":"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":"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":"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":"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":"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":"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":"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":"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":"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: MIT License: 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 2 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-16T12:40:40.480Z","repository_id":57093952,"created_at":"2025-08-16T12:40:40.481Z","updated_at":"2025-08-16T12:40:40.481Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272940147,"owners_count":25018839,"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","status":"online","status_checked_at":"2025-08-31T02:00:09.071Z","response_time":79,"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":["angular","atomic-template","atoms","dom-events","javascript","micro-frontend","micro-frontends","molecules","postmessage","reactjs","single-spa","transition-page","virtual-dom","vuejs"],"created_at":"2024-08-04T21:00:26.947Z","updated_at":"2025-08-31T04:32:04.572Z","avatar_url":"https://github.com/aacgn.png","language":"JavaScript","readme":"![alt logo](assets/atomic_logo.png)\n\n# atomic micro-frontends: A JavaScript library for building interfaces with vertical and horizontal micro-frontends\n\n![alt license](https://img.shields.io/github/license/aacgn/atomic?style=flat-square) ![alt version](https://img.shields.io/github/package-json/v/aacgn/atomic?style=flat-square) ![alt tag](https://img.shields.io/github/v/tag/aacgn/atomic?style=flat-square) ![alt npm-version](https://img.shields.io/npm/v/@aacgn/atomic?style=flat-square)\n\n## 📄 Description\n\nAtomic is a front-end library, based on iframes, that enables javascript developers to generate interfaces with vertical and horizontal micro-frontends from any framework-native using only client-side techniques and components based on Atomic Design.\n\n## ✨ Features\n\n* **Dependency Free**: Micro-frontends wrapped by Atomic don't need any extra library dependencies or configuration in their files to be used.\n* **Shared Runtime**: Atomic Router provide a transition page option that is responsable for override temporarily pages that are loading micro-frontends, allowing it to show it content only when the micro-frontends are fully loaded and running at same time as a single product, keeping the UX intact.\n* **Shared Context**: Atomic Pages provide a shared global object of context with all their micro-frontends, keeping a \"single source of truth\" concept for all of them.\n* **Clean Communication**: Atomic embbed the entire shell application with a MessageEvent interceptor to properly deal with internal events (e.g., navigation and store), turning suh events more user friendly, and parse postMessage events (mostly provided by our micro-frontends) into actual CustomEvents, in order to turn their event listener declaration and data transfer object more semantic and synthetic for our app.\n* **Atomic Design Components**: Atomic provide your own component abstraction to build our pages. Distributed as atoms, molecules, organisms, templates and pages, they are following the Atomic Design methology creating a merge of thoughts for the application composition and re-use of elements between the front-end and UX / UI teams.\n\n## 📚 Examples\n\n### Atomicfy\n\nAtomicfy is a Spotify clone that was built with Atomic, using micro-frontends from Vue.js, React.js, Angular 9 and Svelte. If you got any curiosity about how was made, please check our [repository link](https://github.com/aacgn/atomicfy).\n\n## 🔎 Atomic Micro-Frontends Concepts\n\nBefore start building our own application, it's important to understand some basic principles of micro-frontend architecture.\n\n### Definition\n\nThe first one it's the definition. You can define the micro-frontends architecture in two ways: horizontal, which allows multiple micro-frontends per page; and vertical, which allows one micro-frontend per business domain.\n\n![alt horizontal split](assets/horizontal_split.png)\n\n![alt vertical split](assets/vertical_split.png)\n\nOpting for a horizontal design means you’ll split a view into multiple parts, which may or may not be owned by the same team. The challenge is to ensure that these different parts have a cohesive look and feel. Bear in mind that with this approach, we’re breaking one of the first principles we’ve defined for micro-frontends: model around a business domain. (Though I’d also say it’s hard to consider a footer a business domain!)\n\nOpting for vertical splitting means you’ll look at the same problem from a business rather than a technical point of view. You’ll assign each business domain, such as authentication UI or the catalog UI, to a team. This enables each team to become domain experts—which, as I noted earlier, is especially valuable when teams have more agency to employ that expertise. In fact, each domain team, despite how many views the domain is composed of, can operate with full autonomy.\n\nOf the two, vertical splitting is closest to the traditional SPA or server-side rendering approach. It doesn’t heavily fragment the implementation, and each team truly owns a specific area of the application.\n\n### Composition\n\n![alt client side composition](assets/client_side_composition.png)\n\nAtomic uses a client-side composition. That architecture can be defined by the usage of an application shell to load multiple micro-frontends directly from a CDN (or from the origin if the micro-frontend is not yet cached at the CDN level), often with JavaScript or an HTML file as the micro-frontends’ entry point. This way, the application shell can dynamically append the DOM nodes (in the case of an HTML file) or initialize the JavaScript application (if the entry point is a JavaScript file).\n\nIt’s also possible to use a combination of iframes to load different micro-frontends, **which is the exatcly case of Atomic solution**.\n\n### Routing\n\nAs with compositions, Atomic choose a client-side architecture.\n\nThe client-side routing, in which an app shell contains and loads the micro-frontends, is mainly used when you’ve sliced your applications vertically, so that the app shell loads one micro-frontend at a time instead of a multitude at once. If you’re using a horizontal split, you should have a page—a container like the app shell—that contains the different micro-frontends. By changing the URL, you can load a different page with a different view.\n\n### Communication between micro-frontends\n\nIf you’ve opted for a horizontal split, your next step is to define how your micro-frontends communicate with each other. One method is to use an event emitter injected into each micro-frontend. This would make each micro-frontend totally unaware of its fellows, and make it possible to deploy them independently. When a micro-frontend emits an event, the other micro-frontends subscribed to that specific event react appropriately.\n\nYou can also use custom events. These have to bubble up to the window level in order to be heard by other micro-frontends, which means that all micro-frontends are listening to all events happening within the window object. They also dispatch events directly to the window object, or bubble the event to the window object, in order to communicate.\n\n![alt communication betwwen micro-frontends](assets/communication_between_micro_frontends.png)\n\n![alt requests from micro-frontends](assets/requests_micro_frontend.png)\n\nIf you’re working with a vertical split, you’ll need to understand how to share information across micro-frontends. For both horizontal and vertical approaches, think about how views communicate when they change. It’s possible that variables may be passed via query string, or by using the URL to pass a small amount of data (and forcing the new view to retrieve some information from the server). Alternatively, you can use web storage to temporarily (session storage) or permanently (local storage) store the information to be shared with other micro-frontends.\n\n\u003e **Note**: Most of the micro-frontend concepts presented into \"How Atomic Works\" section, was extract from the article \"Micro-frontends in context\" wrote by Luca Mezzalira (@lucamezzalira). If you want to learn more this topic, please take a look at the full content of paper using this [link](https://increment.com/frontend/micro-frontends-in-context/#authors).\n\n## 🌞 Usage\n\n### Boiler template\n\nAtomic has a boiler template available with webpack, webpack-dev-server and babel already configured in our [atomic-template](https://github.com/aacgn/atomic-template) repository. Please, starting using it for new projects.\n\n### Documentation\n\n#### Atomic\n\n```javascript\nimport { Atomic } from \"@aacgn/atomic\";\nimport Router from \"./router\";\n\nimport \"./global.css\";\n\nnew Atomic(Router, document.getElementById(\"root\"));\n```\n\nAtomic is also know as the application manager, it responsability is provide communication and integration between every piece of the library. Beyond link the Atomic Router to a start redenring point, as can be easily predicted by their parameters, it's main job is intercepting MessageEvents with the attribute \"hasAtomicSignature\" setted as true and properly treating them based on their message content (that, by the way, will be explained in the next section).\n\n##### MessageEvent interceptor\n\nAs previously mentioned, Atomic main job is to intecept MessageEvents with the attribute \"hasAtomicSignature\" setted as true and properly treating them based on their message content. But, what you don't know it's how you can use it.\n\nIn the current version, we have three public funcionalities:\n\n* navigate: Responsible for link you to another page\n* store: Reponsible for update the data of global context store\n* custom_event: Reponsible for transform MessageEvent into a CustomEvent\n\nTo use them, you must first define a object with following attributes:\n\n* hasAtomicSignature: A bool field that is reponsible for enable or disable the interception of Atomic in this event\n* event: A string field that is reponsible for identify the public functionality that you wanna use\n* data: A object field that store and pass the a needed information of the public functionality that you wanna use\n\nAfter that, you must pass this object through a window.postMessage method and are done.\n\nJust to make sure that you gonna do right in your first time, I gonna provide some examples in the content bellow:\n\n```javascript\nconst postMessageData = {\n    hasAtomicSignature: true,\n    event: \"navigate\",\n    data: \"/\"\n};\n\nwindow.postMessage(postMessageData, \"*\");\n```\n\n```javascript\nconst postMessageData = {\n    hasAtomicSignature: true,\n    event: \"store\",\n    data: {\n        name: \"login\",\n        data: {\n            oAuthToken: {}\n        }\n    }\n};\n\nwindow.postMessage(postMessageData, \"*\");\n```\n\n```javascript\nconst postMessageData = {\n    hasAtomicSignature: true,\n    event: \"custom_event\",\n    data: {\n        name: \"hello\",\n        data: {\n            message: \"Hello, Antonio Neto. How are you?\"\n        }\n    }\n};\n\nwindow.postMessage(postMessageData, \"*\");\n```\n\n#### Atomic Router\n\n```javascript\nimport { AtomicRouter } from \"@aacgn/atomic\";\n\nimport LoginPage from \"../pages/LoginPage\";\nimport DashboardPage from \"../pages/DashboardPage\";\n\nimport TransitionPage from \"../pages/TransitionPage\";\n\nconst routes = [\n    {\n        path: \"/\",\n        page: LoginPage()\n    },\n    {\n        path: \"/dashboard\",\n        page DashboardPage()\n    }\n]\n\nconst Router = new AtomicRouter(\n    {\n        routes: routes,\n        mode: \"history\",\n        transitionPage: TransitionPage()\n    }\n);\n\nexport default Router;\n```\n\nAtomic Router is the responsible for controling what is being displayed in the screen and. With it you can define routes, mode, and a transition page that is gonna be used when micro-frontends wrapped into a page are loading.\n\n##### Routes\n\nRoutes it's a array of object where the user will declare and structure the URL paths, controling when and what your application will render.\n\nCurrently, our inner array object have only two attributes that must be passed:\n\n* Path: Conditional URL path location where your page will be rendered.\n* Page: Component that your router is gonna display when the path setted be reached.\n\nFor example, in the code bellow our application will render the DashboardPage component when the URL path location reach \"dashboard\". Depending on the mode of routing you choosed, your URL path will be something like this: http://localhost:8888/dashboard or http://localhost:8888/#/dashboard.\n\n```javascript\nconst routes = [\n    {\n        path: \"/\",\n        page: LoginPage()\n    },\n    {\n        path: \"/dashboard\",\n        page DashboardPage()\n    }\n]\n```\n\n##### Mode\n\nMode it's related with how your URL paths will work. Currently, you can choose between two modes:\n\n* History\n* Hash\n\nIn general scenarios, hash and history can be used, unless you care more about the appearance. # Symbols in URLs do not look very beautiful.\n\nWith History, we use conventional address bar URL. For example, this URL: http://www.abc.com/hello. The value of path is /hello.\n\n\u003e **Note**: If you gonna use history mode, please, remember to set your server with historyApiFallback.\n\nWith Hash, we use in the address bar URL along side withs # symbols. For example, this URL: http://www.abc.com/#/hello. The value of hash is #/hello。The feature is that although hash appears in the URL, it will not be included in the HTTP request and has no effect on the back end, so changing hash will not reload the page.\n\n##### Transition Page\n\nThe trasition page option was developed to temporarily override a page that must be render when a micro-frontend wrapper are being loaded, that way we can provide a experience of single product, keeping the UX intact.\n\n#### Components\n\nComponents are the responsible for translate our javascript objects into actually DOM elements for our browser pages. Currently, they can be split in the following types:\n\n* Atoms\n* Molecules\n* Organisms\n* Templates\n* Micro-frontends Wrapper\n* Pages\n\nAll of them follows the Atomic Design methodology and have a unique reponsability, along side with our own properties to be declared and used in the library.\n\n#### Atoms\n\nAtoms are the basic building blocks of matter. Applied to web interfaces, atoms are our HTML tags, such as a form label, an input or a button.\n\nWe can use it in Atomic as the following implementation:\n\n```javascript\n\nimport { createAtom } from \"@aacgn/atomic\";\n\nimport \"./index.css\";\n\nconst BaseButton = (textContent) =\u003e createAtom({\n    tag: \"button\",\n    attr: {\n        className: \"base-button\"\n    },\n    props: {\n        textContent: textContent\n    }\n});\n\nexport default BaseButton;\n\n```\n\n#### Molecules\n\nThings start getting more interesting and tangible when we start combining atoms together. Molecules are groups of atoms bonded together and are the smallest fundamental units of a compound. These molecules take on their own properties and serve as the backbone of our design systems.\n\nWe can use it in Atomic as the following implementation:\n\n```javascript\n\nimport { createMolecule } from \"@aacgn/atomic\";\n\nimport BaseInput from \"./BaseInput\";\nimport BaseButton from  \"./BaseButton\";\n\nimport \"./index.css\";\n\nconst SearchField = () =\u003e createMolecule({\n    tag: \"div\",\n    attr: {\n        className: \"search-field\"\n    },\n    props: {\n        children: [\n            BaseInput(\"Enter Keyword\"),\n            BaseButton(\"Search\")\n        ]\n    }\n});\n\nexport default SearchField;\n\n```\n\n#### Organisms\n\nMolecules give us some building blocks to work with, and we can now combine them together to form organisms. Organisms are groups of molecules joined together to form a relatively complex, distinct section of an interface.\n\n\nWe can use it in Atomic as the following implementation:\n\n```javascript\n\nimport { createOrganism } from \"@aacgn/atomic\";\n\nimport Logo from \"./Logo\";\nimport NavBar from \"./NavBar\";\nimport SearchField from \"./SearchField\";\n\nimport \"./index.css\";\n\nconst TopBar = () =\u003e createOrganism({\n    tag: \"div\",\n    attr: {\n        className: \"top-bar\"\n    },\n    props: {\n        children: [\n            Logo(),\n            NavBar([\"Home\", \"About\", \"Blog\", \"Contact\"]),\n            SearchField()\n        ]\n    }\n});\n\nexport default TopBar;\n\n```\n\n#### Templates\n\nAt the template stage, we break our chemistry analogy to get into language that makes more sense to our clients and our final output. Templates consist mostly of groups of organisms stitched together to form pages. It’s here where we start to see the design coming together and start seeing things like layout in action.\n\n\nWe can use it in Atomic as the following implementation:\n\n```javascript\n\nimport { createTemplate } from \"@aacgn/atomic\";\n\nimport TopBar from \"./TopBar\";\nimport CatalogCarousel from \"./CatalogCarousel\";\nimport CatalogRecommendation from \"./CatalogRecommendation\";\n\nimport \"./index.css\";\n\nconst DashboardTemplate = (carouselItems, recommendationItems) =\u003e createTemplate({\n    tag: \"div\",\n    attr: {\n        className: \"dashboard\"\n    },\n    props: {\n        children: [\n            TopBar(),\n            CatalogCarousel(carouselItems),\n            CatalogRecommendation(recommendationItems)\n        ]\n    }\n});\n\nexport default DashboardTemplate;\n\n```\n\n#### Pages\n\nPages are specific instances of templates. Here, placeholder content is replaced with real representative content to give an accurate depiction of what a user will ultimately see.\n\n```javascript\n\nimport { createPage } from \"@aacgn/atomic\";\n\nimport DashboardTemplate from \"./DashboardTemplate\";\n\nimport \"./index.css\";\n\nconst DashboardPage = () =\u003e createPage({\n    name: \"dashboard\",\n    context: {\n        carouselItems: [],\n        recommendationItems: []\n    },\n    mount: function() {\n        return DashboardTemplate(this.context.carouselItems, this.content.recommendationItems);\n    },\n    onMount: function(ref) {\n        console.log('hello');\n    },\n    onUnmount: function(ref) {\n        console.log('bye');\n    }\n});\n\nexport default DashboardPage;\n```\n\n### Micro-frontends Wrapper\n\nFinally, we came to our last component. It responsability is insert the micro-frontend from any framework-native in our pages.They doesn't have any hierarchy level and can be called in any of level of atomic design, the only restriction it's be a child of a page.\n\nGoing to a more pratice way, imagine that everything exemplified previously until template as putted into a micro-frontend, the following example bellow will demonstrate how wrap that and use into our page.\n\nDashboardMicroFrontendWrapper\n```javascript\nimport { createMicroFrontendWrapper } from \"@aacgn/atomic\";\n\nimport \"./index.css\";\n\nconst DashboardMicroFrontendWrapper = () =\u003e createMicroFrontendWrapper({\n    attr: {\n        className: \"dashboard-micro-frontend-wrapper\"\n    },\n    props: {\n        url: \"http://localhost:3000\"\n    }\n});\n\nexport default DashboardMicroFrontendWrapper;\n```\n\nDashboardPage\n```javascript\n\nimport { createPage } from \"@aacgn/atomic\";\n\nimport DashboardMicroFrontendWrapper from \"./DashboardMicroFrontendWrapper\";\n\nimport \"./index.css\";\n\nconst DashboardPage = () =\u003e createPage({\n    name: \"dashboard\",\n    context: {\n        carouselItems: [],\n        recommendationItems: []\n    },\n    mount: function() {\n        return DashboardMicroFrontendWrapper();\n    },\n    onMount: function(ref) {\n        console.log('hello');\n    },\n    onUnmount: function(ref) {\n        console.log('bye');\n    }\n});\n\nexport default DashboardPage;\n```\n\n\u003e **Note**: If you wanna catch the context object inside our micro-frontends use window.AtomicContextStore['name-of-your-page'] in it or just send the data through postMessage such as postMessage.\n\n\n### Auxiliar functions\n\nAtomic also provide for it's shell application a couple of auxiliar functions. Currently, they are:\n\n* dispatchEvent: Responsible for send events to micro-frontends declared into our application.\n* navigateTo: Reponsible for redirect our application to another path\n* storeData: Responsible for storage data into a context store item\n* mapContextStore: Responsible for return all context store object\n\nExamples:\n\n```javascript\nimport { dispatchEvent } from \"@aacgn/atomic\";\n\ndispatchEvent(\"carouselItems\", 12, [\"dashboard-micro-frontend-wrapper\"]);\n``` \n\n```javascript\nimport { navigateTo } from \"@aacgn/atomic\";\n\nnavigateTo(\"/\");\n``` \n\n```javascript\nimport { storeData } from \"@aacgn/atomic\";\n\nstoreData(\"dashboard\", {carouselItems: [], recommendationItems: []});\n``` \n\n```javascript\nimport { mapContextStore } from \"@aacgn/atomic\";\n\nmapContextStore(\"dashboard\");\n``` \n\n\n## 👪 Contributing\nPull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.\n\nPlease make sure to update tests as appropriate.\n\n## 📃 License\n\n```LICENSE\nMIT License\n\nCopyright (c) 2020 Antonio Neto\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","funding_links":[],"categories":["Tools"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faacgn%2Fatomic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faacgn%2Fatomic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faacgn%2Fatomic/lists"}