DEV Community

Sashka Argunov
Sashka Argunov

Posted on

RFC: Cache(Hash)able ES packages

This is literally a request for comments for my proposal of cachable and hashable JavaScript packages in the browsers. I'm not a browser-engine engineer, nor paid to write proposals: so there's a high chance I missed something crucial which makes it impossible.

Motivation

We reuse and re-download a lot of libraries like React between websites which are built using same webpack and same UglifyJS (which produce identical artifacts). And a lot application developers want for APIs like React to be built-in in the browser. On the other hand, browser-engine and TC39 engineers don't exactly know which APIs to implement.

Proposal

Package map, which is the only additional thing provided by app developer, looks like this:

<script type="packagemap">
{
    "packages": [
        {
            "name": "react", 
            "hash": "sha256:41a7ed1ba26217cf70059964c74665d0a9c364a4078f69a3ca6d1e2623b0679f"
            "location": "https://mywebsite/js/react_min.js"
        },
        ...
    ]
}
</script>

After package map was downloaded, browsers check if package is in the cache using "hash" contents:

  • If it is, then you can use that package;
  • If it's not, then browsers download package, and checks if computed hash is the right hash:
    • if the hash is correct, you can safely put package in the cache;
    • if it's not, your application continues working properly, but cache doesn't get populated by given package.

And because it's a generic hash, you can use packages downloaded from another websites.

So you, as an application developer, already know that your packages will be used on another websites, so you put only public npm libraries there. Internal packages can be cached using more traditional approaches like Service Workers or others.

And browser engineers can have insights like "70% of websites use this API, so we can pre-download or safely implement that as a built-in".

Security

Main concern of code-reuse is always security, and, as far as I know, previous attempts had one main angle of attack: Timing Attacks. For example, an attacker has a website which tries to download whole npm via package maps, if you don't use really specific package like "@my-company/really-obscure-package" then attacker shouldn't generally has any idea which websites you visit. After all, this cache should be populated by packages which are common between websites. So I don't see viable Timing Attack here.

Related work

Subresource Integrity

Subresource Integrity (SRI) is mainly intended for downloading assets from 3rd party CDNs. When SRI doesn't match, asset is discarded from evaluation, which is a bit different intention from package integrity hash.

Import Maps

Import maps is a mature proposal championed by Chrome developers and already implemented in Chrome, but their focus isn't on caching nor package metadata.

In conclusion

I've been thinking about this for a few months and reading related work. Although, I've been slacking a bit lately, I don't want to let this idea die. That is why I decided to share it with you. I'm really excited thinking of benefits this idea can bring to everyone. I will appreciate feedback from all of you, to get the grasp if I should push this into real proposal, and how to integrate it with existing ones.

Oldest comments (0)