{"id":13725098,"url":"https://github.com/chromakode/isolated-core","last_synced_at":"2025-08-21T01:32:08.841Z","repository":{"id":57278132,"uuid":"50453223","full_name":"chromakode/isolated-core","owner":"chromakode","description":"Seamless in-page cold updates using iframes.","archived":false,"fork":false,"pushed_at":"2016-02-24T21:44:53.000Z","size":346,"stargazers_count":213,"open_issues_count":0,"forks_count":9,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-08-15T04:00:59.885Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://chromakode.github.io/isolated-core/","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/chromakode.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}},"created_at":"2016-01-26T19:26:45.000Z","updated_at":"2025-03-22T08:06:46.000Z","dependencies_parsed_at":"2022-09-18T15:03:16.603Z","dependency_job_id":null,"html_url":"https://github.com/chromakode/isolated-core","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/chromakode/isolated-core","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chromakode%2Fisolated-core","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chromakode%2Fisolated-core/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chromakode%2Fisolated-core/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chromakode%2Fisolated-core/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chromakode","download_url":"https://codeload.github.com/chromakode/isolated-core/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chromakode%2Fisolated-core/sbom","scorecard":{"id":281514,"data":{"date":"2025-08-11","repo":{"name":"github.com/chromakode/isolated-core","commit":"2624db11c740a98ccb0051309a247193bd510bcf"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Code-Review","score":0,"reason":"Found 1/30 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":"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":"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":"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":"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":"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":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: npmCommand not pinned by hash: scripts/deploy.sh:22","Info:   0 out of   1 npmCommand dependencies pinned"],"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":"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":"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":"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":"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":"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":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"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 1 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-17T15:58:18.768Z","repository_id":57278132,"created_at":"2025-08-17T15:58:18.769Z","updated_at":"2025-08-17T15:58:18.769Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":271415020,"owners_count":24755628,"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-20T02:00:09.606Z","response_time":69,"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":[],"created_at":"2024-08-03T01:02:12.914Z","updated_at":"2025-08-21T01:32:08.502Z","avatar_url":"https://github.com/chromakode.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# Isolated Core\n\n[![Build Status](https://img.shields.io/travis/chromakode/isolated-core/master.svg?style=flat-square)](https://travis-ci.org/chromakode/isolated-core)\n[![Coverage Status](https://img.shields.io/coveralls/chromakode/isolated-core/master.svg?style=flat-square)](https://coveralls.io/github/chromakode/isolated-core?branch=master)\n[![npm](https://img.shields.io/npm/v/isolated-core.svg?style=flat-square)](https://www.npmjs.com/package/isolated-core)\n[![npm](https://img.shields.io/npm/l/isolated-core.svg?style=flat-square)](https://github.com/chromakode/isolated-core/blob/master/LICENSE)\n\nA library for seamless in-page cold updates using iframes.\n\n[:zap: **DEMO**](http://chromakode.github.io/isolated-core/)\n\n\n## Introduction\n\nIn long running web apps, such as chat clients or music players, users leave pages open for weeks. It's useful to push code updates to existing clients, but in-page updates must be extremely fast and reliable to not become disruptive to the user experience.\n\nWith Isolated Core, your client-side JS (the \"core\") is contained within an `\u003ciframe\u003e`. To render UI, the iframe reaches up to manipulate the DOM of its parent document. This pattern decouples app execution from the visible UI, making it possible to seamlessly reload the entire app separately from the page without navigation or jank. This has some cool advantages:\n\n * Speed: updates load in the background and \"swapping cores\" is extremely fast.\n * Fault-tolerance: network and JS errors during init are caught before performing an update.\n * Predictability: loading an update runs the same code paths as reloading the page.\n\nIsolated Core is complementary to existing techniques like [Hot Module Replacement (HMR)](https://webpack.github.io/docs/hot-module-replacement-with-webpack.html) and is framework agnostic. Unlike HMR, Isolated Core reloads your entire app environment \\*cold\\* from a blank slate. This makes updates predictable and easy to reason about, and facilitates updating components that previously required a full page reload. In addition, Isolated Core makes rollouts safer: since updates load and initialize in the background, failures can be caught rapidly without disrupting the user.\n\n\n## Browser Compatibility\n\nIsolated core works on IE9+ and all other modern browsers. IE8 support is possible but not complete -- if you need it, please file an issue!\n\n[![Sauce Test Status](https://saucelabs.com/browser-matrix/isolated-core.svg)](https://saucelabs.com/u/isolated-core)\n\n\n## Usage\n\nIn the entry point of your app, call `coreInit`, passing it the URL to the current script and a function to run to initialize your app. When `coreInit` is first invoked from a script tag, it will create a new iframe, injecting the script you specify. Then, inside the iframe, your script runs again and `coreInit` calls the `run` function you specify.\n\nThis design makes Isolated Core compatible with a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy) and browsers which do not support Data URIs in iframes.\n\n**main.js:**\n\n```js\nimport { coreInit } from 'isolated-core'\n\ncoreInit({\n  // In non-IE, you can use document.currentScript.src here.\n  scriptURL: '/main.js',\n\n  // Note: we are deferring require()ing our code until the \"run\" function\n  // executes inside the iframe. Our init function is exported by index.js.\n  run: core =\u003e require('./').init(core),\n})\n```\n\nIn your initialization function, take a `core` argument and call `core.ready()` with handlers to `attach` and `detach` your UI. These handlers are responsible for instantiating and decontructing your UI in the parent document when your core is loaded or replaced. Both of these handlers receive the parent document (\"uidocument\") as an argument. For example, here's a basic React setup:\n\n**index.js:**\n\n```js\nimport React from 'react'\nimport ReactDOM from 'react-dom'\nimport MyComponent from './MyComponent'\n\nexport function init(core) {\n  core.ready({\n    attach(uidocument) {\n      ReactDOM.render(\u003cMyComponent /\u003e, uidocument.getElementById('container'))\n    },\n\n    detach(uidocument) {\n      ReactDOM.unmountComponentAtNode(uidocument.getElementById('container'))\n    },\n  })\n}\n```\n\nWhen `coreInit` creates the first iframe, it automatically attaches it, calling your attach handler.\n\nTo load an update, call `loadCore` with a script URL to execute. It returns a promise which resolves when the new core is loaded and ready to attach. It rejects if a script request fails to load (script tag `onerror`) or a JS exception is thrown during initialization. Under the hood, `loadCore` is creating a new iframe, injecting the script specified. Inside the new iframe, `coreInit` runs like before, and when it calls `core.ready()`, the promise resolves. For example:\n\n```js\nloadCore({\n  scriptURL: '/main.js',\n}).then(\n  function success(coreRef) =\u003e {\n    // Call launchCore to detach the current core and attach the new one.\n    coreRef.launchCore()\n  },\n\n  function failure(coreErr) {\n    // coreErr.type will be either \"request\" or \"js\"\n    // \"request\" type errors have a \"src\" property with the URL that failed to load.\n    // \"js\" type errors have an \"err\" property with the exception.\n    console.error(`core #${coreErr.id} failed to load: ${coreErr.type} error`)\n\n    // Call destroyCore to remove the iframe from the document.\n    coreErr.destroyCore()\n  }\n)\n```\n\nYou should use CSS to hide core iframes. The easiest way to do it is to match the `data-coreid` attribute:\n\n```css\niframe[data-coreid] { display: none }\n```\n\n\n## Caveats\n\nWhile in general the Isolated Core pattern provides a lot of benefits, there are a few trade-offs worth mentioning:\n\n * Cores typically share the same browser thread for a page, so if an update initializing in the background ties up the thread, it can cause framerate drops or pauses in the UI.\n\n * By its nature, cold loading requires more initialization time and memory than hot replacing modules. When a core is ready but not attached yet, it adds significant memory footprint to the page.\n\n * It's necessary to set aggressive HTTP caching headers for your core script because it will be loaded in both the initial page and then immediately again inside the first core iframe. For best results, use a CDN and include the hash of your bundles in the filename.\n\n\n## API\n\n### `coreInit({ scriptURL, run, args })`\n\nInitialize a core, creating an iframe on first page load if necessary.\n\nWhen called outside a core iframe, `coreInit` passes its options to `loadCore` and automatically attaches the first core when it's ready.\n\nWhen called inside a core iframe, `coreInit` invokes the `run` function with a `core` object, e.g.:\n\n```js\n{\n  id: 0,              // A unique numeric id for the core\n  args: {...},        // An object passed to loadCore by the invoking context\n  ready: \u003cfunction\u003e,  // Call with a handlers object when finished loading\n}\n```\n\nThe `core.ready()` function must be called by your `run` function when your core is ready to attach:\n\n```js\ncore.ready({\n  attach(uidocument) {\n    // render your UI to uidocument\n  }\n\n  detach(uidocument) {\n    // clean up your event handlers, etc.\n  }\n})\n```\n\n### `loadCore({ scriptURL, args })`\n\nLoad a new core with specified `args` by creating an iframe and injecting a script with the specified `scriptURL` into it. Returns a promise which resolves when the core is ready to attach, or rejects in case of request or JS error.\n\nWhen the promise resolves or rejects, it passes an object of the form:\n\n```js\n{\n  id: 0,                    // A unique numeric id for the core\n  args: {...},              // The args object you specified\n  context: \u003cwindow\u003e,        // A reference to the window object of the iframe\n  destroyCore: \u003cfunction\u003e,  // Call to remove the core's iframe\n}\n```\n\nIf the promise resolves, the return type will also include:\n\n```js\n{\n  launchCore: \u003cfunction\u003e,   // Call to detach the current core and attach this new one\n}\n```\n\nCalling `launchCore` will remove the current execution context from the DOM. Statements following `launchCore` will not execute.\n\nIf the promise rejects, the return type will also include:\n\n```js\n{\n  type: 'request'|'js',     // Either 'request' on network error, or 'js' on exception\n  src: \u003curl\u003e,               // If type: 'request', the URL that failed to load\n  err: \u003cError\u003e,             // If type: 'js', the exception object thrown\n}\n```\n\n## License\n\n[MIT](https://github.com/chromakode/isolated-core/blob/master/LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchromakode%2Fisolated-core","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchromakode%2Fisolated-core","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchromakode%2Fisolated-core/lists"}