{"id":13724965,"url":"https://github.com/WebReflection/js-in-json","last_synced_at":"2025-05-07T19:32:04.402Z","repository":{"id":57283201,"uuid":"361209014","full_name":"WebReflection/js-in-json","owner":"WebReflection","description":"A server side agnostic way to stream JavaScript.","archived":false,"fork":false,"pushed_at":"2023-02-09T10:24:56.000Z","size":144,"stargazers_count":26,"open_issues_count":1,"forks_count":1,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-04-13T23:57:48.325Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/WebReflection.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-04-24T16:17:29.000Z","updated_at":"2023-02-09T10:24:58.000Z","dependencies_parsed_at":"2024-11-14T15:36:22.633Z","dependency_job_id":"00879ec1-b677-48c9-9c3b-e651062f501a","html_url":"https://github.com/WebReflection/js-in-json","commit_stats":{"total_commits":40,"total_committers":1,"mean_commits":40.0,"dds":0.0,"last_synced_commit":"d1cece4115a1942381ec7c23f15660cc7dcdc562"},"previous_names":[],"tags_count":15,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fjs-in-json","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fjs-in-json/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fjs-in-json/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/WebReflection%2Fjs-in-json/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/WebReflection","download_url":"https://codeload.github.com/WebReflection/js-in-json/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252943816,"owners_count":21829315,"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":[],"created_at":"2024-08-03T01:02:08.290Z","updated_at":"2025-05-07T19:32:04.397Z","avatar_url":"https://github.com/WebReflection.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"# JS in JS![O](./logo/JSinJSON.24.png)N\n\nA server side agnostic way to stream JavaScript, ideal for:\n\n  * inline hydration\n  * network free ad-hoc dependencies\n  * bootstrap on demand\n  * libraries on demand\n  * one JSON file to rule all SSR cases\n\nThe **Session** utility is currently available for:\n\n  * [JS](https://github.com/WebReflection/js-in-json-session#readme)\n  * [PHP](https://github.com/WebReflection/js-in-json-session/blob/main/php/session.php)\n  * [Python](https://github.com/WebReflection/js-in-json-session/blob/main/python/session.py)\n\n- - -\n\nAn \"*islands friendly*\" approach to Server Side Rendering able to produce *stream-able JS* on demand, via any programming language, through a single JSON bundle file instrumented to *flush()* any script, after optional transpilation and/or minification.\n\nThe produced output can be also pre-generated and served as static content, with the advantages that **js-in-json bundles require zero network activity**: forget round-trips, thousand *ESM* requests per library or project, and simply provide all it's needed right on the page.\n\n```js\n// a basic serving example\nconst {JSinJSON} = require('js-in-json');\n\n// see ## Options\nconst {options} = require('./js-in-json-options.js');\n\nconst islands = JSinJSON(options);\n// islands.save(); when needed to create the JSON bundle\n\nhttp.createServer((req, res) =\u003e {\n  // see ## Session\n  const js = islands.session();\n  js.add('Main');\n  res.writeHead(200, {'content-type': 'text/html'});\n  res.write(`\n    \u003c!doctype html\u003e\n    \u003cscript src=\"//external.cdn.js\"\u003e\u003c/script\u003e\n    \u003cscript\u003e${js.flush()}\u003c/script\u003e\n    \u003cbody\u003e\n      \u003cdiv class=\"component\"\u003e\u003c/div\u003e\n      \u003cscript\u003e${js.add('UI/component').flush()}\u003c/script\u003e\n    \u003c/body\u003e\n  `.trim());\n  js.add('Footer');\n  if (global.condition) {\n    js.add('SpecialCondition');\n    res.write(`\u003cscript\u003e${js.flush()}\u003c/script\u003e`);\n  }\n  res.end();\n});\n```\n\n## Session\n\nA *js-in-json* session can be initialized right away via `js-in-json/session` exported *Session* class, or through the main `JSinJSON(options).session()` utility.\n\nA session created via `JSinJSON` optionally accepts a JSON bundle, retrieved from *options*, if not provided, and it exposes 2 methods:\n\n  * `add(\"ModuleName\")` to *flush* its content *only once* and, if repeatedly added, and available, bootstrap its *code*\n  * `flush()` to return all modules and their dependencies previously added and, if available, their code to bootstrap\n\nIn order to have a *session*, a JSON bundle must be created.\n\n\n## Options\n\nFollowing the object literal with all its defaults that can be passed to the `JSinJSON(options)` export.\n\n```js\nconst {save, session} = JSinJSON({\n\n  // TOP LEVEL CONFIG ONLY\n\n  // MANDATORY\n  // the root folder from which each `input` is retrieved\n  // used to resolve the optional output, if relative to this folder\n  root: '/full/project/root/folder'\n\n  // OPTIONAL\n  // where to store the resulting JSON cache usable via JSinJSON.session(cache)\n  // if omitted, the cache is still processed and returned\n  output: './bundle.json',\n  // the global context used to attach the `require` like function\n  global: 'self',\n  // the `require` like unique function name, automatically generated,\n  // and it's different per each saved JSON (hint: don't specify it)\n  prefix: '_uid',\n\n\n  // OPTIONAL EXTRAS: CAN BE OVERWRITTEN PER EACH MODULE\n  // use Babel transformer to target @babel/preset-env\n  babel: true,\n  // use terser to minify produced code\n  minify: true,\n  // transform specific bare imports into other imports, it's {} by default\n  // see: rollup-plugin-includepaths\n  replace: {\n    // example: replace CE polyfill with an empty file\n    '@ungap/custom-elements': './empty.js'\n  },\n  // executed each time a JSinJSON.session.flush() happens\n  // no matter which module has been added to the stack\n  // it's missing/no-op by default and it has no access\n  // to the outer scope of this file (it's serialized as function)\n  code(require) {\n    // each code receives the `require` like function\n    const {upgradeAll} = require('Bootstrap');\n    upgradeAll();\n  },\n  // an object literal to define all modules flushed in the page\n  // whenever any of these is needed\n  modules: {\n    // the module name available via the `require` like function\n    Bootstrap: {\n      // MANDATORY\n      // the ESM entry point for this module\n      input: './bootstrap.js',\n\n      // OPTIONAL: overwrite top level options per each module\n      // don't transform and/or don't minify\n      babel: false,\n      minify: false,\n      // will be merged with the top level\n      replace: {'other': './file.js'},\n      // don't flush anything when injected\n      code: null\n    },\n\n    // other module example\n    Login: {\n      input: './login.js',\n      code() {\n        document.documentElement.classList.add('wait');\n        fetch('/login/challenge').then(b =\u003e b.json).then(result =\u003e {\n          self.challenge = result;\n          document.documentElement.classList.remove('wait');\n        });\n      }\n    }\n  }\n});\n```\n\n### Options Rules / Limitations\n\n  * the `root` should better be a fully qualified path, instead of relative\n  * the `code` is always transformed with `@babel/preset-env` target\n  * the `code` **cannot be asynchronous**\n  * modules *cannot* have `_` as name prefix, that's reserved for internal resolutions\n  * modules *should* have *non-npm* modules names, to avoid conflicts/clashing with imports\n  * modules *can* be capitalized\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWebReflection%2Fjs-in-json","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FWebReflection%2Fjs-in-json","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FWebReflection%2Fjs-in-json/lists"}