{"id":18137790,"url":"https://github.com/tc39/proposal-source-phase-imports","last_synced_at":"2025-10-14T21:32:12.715Z","repository":{"id":37328693,"uuid":"401276992","full_name":"tc39/proposal-source-phase-imports","owner":"tc39","description":"Proposal to enable importing modules at the source phase","archived":false,"fork":false,"pushed_at":"2025-02-07T23:54:01.000Z","size":268,"stargazers_count":144,"open_issues_count":6,"forks_count":10,"subscribers_count":21,"default_branch":"main","last_synced_at":"2025-03-29T12:02:29.708Z","etag":null,"topics":["javascript","proposal","tc39"],"latest_commit_sha":null,"homepage":"https://tc39.es/proposal-source-phase-imports/","language":"HTML","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/tc39.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-08-30T08:51:56.000Z","updated_at":"2025-03-12T00:05:04.000Z","dependencies_parsed_at":"2024-04-18T17:33:26.421Z","dependency_job_id":"b6f16ee1-b753-4d46-9982-3da571b56edb","html_url":"https://github.com/tc39/proposal-source-phase-imports","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":"tc39/template-for-proposals","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-source-phase-imports","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-source-phase-imports/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-source-phase-imports/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tc39%2Fproposal-source-phase-imports/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tc39","download_url":"https://codeload.github.com/tc39/proposal-source-phase-imports/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247339145,"owners_count":20923012,"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":["javascript","proposal","tc39"],"created_at":"2024-11-01T15:06:55.379Z","updated_at":"2025-10-14T21:32:07.674Z","avatar_url":"https://github.com/tc39.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Source Phase Imports\n\n## Status\n\nChampion(s): Luca Casonato, Guy Bedford\n\nAuthor(s): Luca Casonato, Guy Bedford, Nicolo Ribaudo\n\nStage: 3\n\nStage 3 reviewers: Daniel Ehrenberg, Kris Kowal\n\nUpstream PR: https://github.com/tc39/ecma262/pull/3492\n\n## Motivation\n\nFor both JavaScript and WebAssembly, there is a need to be able to more closely\ncustomize the loading, linking, and execution of modules beyond the standard\nhost execution model.\n\nFor JavaScript, creating userland loaders would require a module source type\nin order to share the host parsing, execution, security, and caching semantics.\n\nFor WebAssembly, imports and exports for WebAssembly modules often require custom\ninspection and wrapping in order to be set up correctly, which typically requires\nmanual fetch and instantiation work that is not provided for in the current host\n[ESM integration][wasm-esm] proposal.\n\nSupporting syntactical module source imports as a new import phase creates a\nprimitive that can extend the static, security and tooling benefits of modules\nfrom the ESM integration to these dynamic instantiation use cases.\n\n## Proposal\n\nThis proposal allows ES modules to import a reified representation of the\ncompiled source of a module when the host provides such a representation:\n\n```js\nimport source x from \"\u003cspecifier\u003e\";\n```\n\nThe `source` module source loading phase name is added to the beginning of the\nImportStatement.\n\nOnly the above form is supported - named exports and unbound declarations are\nnot supported.\n\n### Dynamic form\n\nJust as with static and dynamic imports, there is a need for static and dynamic access\nto sources, to be able to support both those sources that are required to be instantiated\nfrom source text during initialization of an application, and those that are optionally or\nlazily created at runtime.\n\nThe dynamic form uses a `import.\u003cphase\u003e` import call:\n\n```js\nconst x = await import.source(\"\u003cspecifier\u003e\");\n```\n\nBy making the phase part of the explicit syntax, it is possible to statically distinguish between\na full dynamic import and one that is only for a source (where dependencies don't need to be\nprocessed).\n\nOptional [import attributes][] may still be specified with the second argument in a `with` key,\njust like for dynamic import, and without conflict due to the design of phased evaluation.\n\n### Loading Phase\n\nModule source imports can be seen to be one type of evaluation phase.\n\nIf the [asset references proposal][] advances in future this could be seen\nas another type of phase representing an earlier phase of the loading process.\n\n```js\nimport asset x from \"\u003cspecifier\u003e\";\nawait import.asset(\"\u003cspecifier\u003e\");\n```\n\nOnly the `source` import source phase is specified by this proposal.\n\n### Defining Module Source\n\nThe object provided by the module source phase must be an object with\n`AbstractModuleSource.prototype` in its prototype chain, defined by this specification\nto be a minimal shared base prototype for a compiled modular resource.\n\nIn addition it defines the `@@toStringTag` getter returning the constructor name string\ncorresponding to the name of the specific module source subclass, with a strong\ninternal slot check.\n\n### JS Module Source\n\nFor JavaScript modules, the module source phase is then specified to return\na `ModuleSource` object, representing an ECMAScript Module Source, where\n`ModuleSource.prototype.[[Proto]]` is `%AbstractModuleSource%.prototype`.\n\nFuture proposals may then add support for [bindings lookup methods][],\nthe [ModuleSource constructor][module soruce] and [instantiation][] support.\n\nNew properties may be added to the base `%AbstractModuleSource%.prototype`, or shared\nwith ECMAScript module sources via `ModuleSource.prototype` additions.\n\n### Wasm Module Source\n\nFor WebAssembly modules, the existing `WebAssembly.Module.prototype` object is to be\nupdated to have a `[[Proto]]` of `%AbstractModuleSource%.prototype` in the\n[WebAssembly JS integration API][wasm-js-api].\n\nThis allows workflows, as explained in the motivation, like the following:\n\n```js\nimport source FooModule from \"./foo.wasm\";\nFooModule instanceof WebAssembly.Module; // true\n\n// For example, to run a WASI execution with an API like Node.js WASI:\nimport { WASI } from 'wasi';\nconst wasi = new WASI({ args, env, preopens });\n\nconst fooInstance = await WebAssembly.instantiate(FooModule, {\n  wasi_snapshot_preview1: wasi.wasiImport\n});\n\nwasi.start(fooInstance);\n```\n\nThe static analysis benefits of not needing a custom `fetch` and\n`WebAssembly.compileStreaming` apply not only to code analysis and security\nbut also for bundlers.\n\nIn turn this enables [Wasm components to be able to import][]\n`WebAssembly.Module` objects themselves in future.\n\n### Other Module Types\n\nAny other host-defined module types may define their own host module sources. If a given module does not define a source representation for it's source, importing it with a \"source\" phase target fails with a `ReferenceError` at link time.\n\nHost-defined module sources must include `%AbstractModuleSource%.prototype` in their prototype chain and support the `[[ModuleSourceRecord]]` internal slot containing the `@@toStringTag` brand check and underlying source host data.\n\n## Security Benefits\n\nThe native ES module loader is able to implement security policies, including\nsupport for [Content Security Policies][CSP] in browsers. This property does not just impact platforms using CSP, but also other platforms with systems to restrict permissions, such as Deno. These policies are based on protecting which URLs are supported for the compilation and execution of scripts or modules.\n\nExtending the static security benefits of the host module system to custom loaders is a security benefit of this proposal. For Wasm, it would enable source-specific CSP policies for dynamic Wasm instantiation.\n\n## Cache Key Semantics\n\nBecause `[[ModuleSourceObject]]` is keyed on the base module record, it will always\nbe unique to the module being imported from.\n\n## Q\u0026A\n\n**Q**: How does this relate to import attributes?\n\n**A**: Import attributes are properties of the module request, while source imports\nrepresent phases of that specific request / key in the module map, without affecting\nthe idempotency of the module load. Both can be used together for a resource to indicate alternative phasing for the given module resource and attributes.\n\n**Q**: How does this relate to module expressions and compartments?\n\n**A**: The module object that is provided has been carefully specified here to be\ncompatible with the linking model of module expressions and compartments.\n\n**Q**: Why not just use `const module = await\nWebAssembly.compileStreaming(fetch(new URL(\"./module.wasm\",\nimport.meta.url)));`?\n\n**A**: There are multiple benefits: firstly if the module is statically\nreferenced in the module graph, it is easier to statically analyze (by bundlers\nfor example). Secondly when using CSP, `script-src: unsafe-eval` would not be\nneeded. See the security improvements section for more details.\n\n[CSP]:\n    https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy\n[ECMA-262 ES modules HostLoadImportedModule refactoring]:\n    https://github.com/tc39/ecma262/pull/2905\n[Wasm components to be able to import]:\n    https://github.com/WebAssembly/component-model/blob/main/design/mvp/Explainer.md#ESM-integration\n[Wasm module object]:\n    https://webassembly.github.io/spec/js-api/index.html#modules\n[asset references proposal]: https://github.com/tc39/proposal-asset-references\n[bindings lookup methods]: https://github.com/tc39/proposal-compartments/blob/master/1-static-analysis.md\n[compartments]: https://github.com/tc39/proposal-compartments\n[import attributes]: https://github.com/tc39/proposal-import-attributes/\n[instantiation]: https://github.com/tc39/proposal-compartments/blob/master/0-module-and-module-source.md#module-instances\n[module-linking]:\n    https://github.com/WebAssembly/module-linking/blob/main/proposals/module-linking/Binary.md#import-section-updates\n[module expressions]: https://github.com/tc39/proposal-module-expressions\n[module source]: https://github.com/tc39/proposal-compartments/blob/master/0-module-and-module-source.md#modulesource\n[wasm-js-api]: https://webassembly.github.io/spec/js-api/#modules\n[wasm-esm]:\n    https://github.com/WebAssembly/esm-integration/tree/master/proposals/esm-integration\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftc39%2Fproposal-source-phase-imports","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftc39%2Fproposal-source-phase-imports","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftc39%2Fproposal-source-phase-imports/lists"}