00:00:01.760 --> 00:00:04.799
Hello and welcome to another edition of Coffee with Developers.
00:00:04.879 --> 00:00:09.199
I've got a friend here again who's been on the show a few times on the live show as well.
00:00:09.359 --> 00:00:13.679
Please welcome Thomas Steiner, who is a developer relations engineer at Google.
00:00:13.759 --> 00:00:14.880
How are you doing today, Thomas?
00:00:15.119 --> 00:00:16.079
Hello, I'm doing great.
00:00:16.160 --> 00:00:16.559
How are you?
00:00:16.800 --> 00:00:17.359
I'm not bad.
00:00:17.440 --> 00:00:22.239
We both complained that the weather the summer is almost over after we complained that it was too hot for a long time.
00:00:22.320 --> 00:00:25.199
And we're both German, so if we don't complain, we're unhappy.
00:00:25.440 --> 00:00:26.879
So I think that's the main thing.
00:00:27.280 --> 00:00:30.719
Well, the core difference is you live in Berlin, I live in Spain.
00:00:30.879 --> 00:00:38.159
So my summer is still technically not over, but like now, Thomas, you pinked me that you have something cool and new happening to us.
00:00:38.320 --> 00:00:46.799
You've been known to me as somebody who works on web platform things that actually allow the web platform to go beyond where the web was going before.
00:00:46.880 --> 00:00:53.600
Like you were part of Project Fugu, and you actually allowed browsers to access things that they weren't able to access before.
00:00:53.759 --> 00:00:57.920
Now, today you said that you have something new called cross-origin storage or cos.
00:00:58.320 --> 00:00:59.119
What's that about?
00:00:59.439 --> 00:01:07.599
Well, cross-origin storage solves one of the uh oldest problems in computer science, um, which is uh not naming things but caching.
00:01:07.760 --> 00:01:11.359
Um so we were both around for a long time, right?
00:01:11.439 --> 00:01:29.680
So we remember the age of uh the jQuery CDNs and so on, and um this super early promise of hey, let's just agree on the same CDN uh URL of jQuery and the same version, and then if we browse different websites that happen to use those same URLs, then we will get a cache benefit.
00:01:29.760 --> 00:01:36.159
And um, yeah, we will just have jQuery for free um when the first page has loaded it and the second page then uses it.
00:01:36.400 --> 00:01:42.239
In practice, it never was that easy just because there were so many jQuery-ish like CDNs around.
00:01:42.319 --> 00:01:49.519
So there was the Ajax, uh Google Ajax library, uh, there was a Microsoft um similar Ajax library um thing around.
00:01:49.680 --> 00:01:52.640
Um people, of course, wanted to self-host thing things.
00:01:52.799 --> 00:01:55.120
Um people didn't agree on the same version.
00:01:55.280 --> 00:02:00.480
So there was a lot of um churn essentially around um like yeah, actually agreeing on the same thing.
00:02:00.719 --> 00:02:02.319
And then, of course, bundles happened.
00:02:02.400 --> 00:02:12.000
So uh bundles really quickly um yeah entered the market, and uh people started realizing oh, um, from the entire jQuery, I'm only using um whatever 70%.
00:02:12.560 --> 00:02:17.039
So the other uh 30% I can just uh that code eliminate and uh move them away.
00:02:17.199 --> 00:02:20.319
And then of course bundles starting to actually mingle things together.
00:02:20.479 --> 00:02:34.080
So you had um jQuery and Lodash and your own vendor, um whatever is something code, and it got uh all mingled together in one big bundle, and then of course, uh this um ruined all of the caching immediately.
00:02:34.319 --> 00:02:36.639
And then also um privacy happened.
00:02:36.719 --> 00:02:45.520
So um in the uh old days when we still could have good things, um, people started realizing oh, um, there's a way how I can time an attack.
00:02:45.599 --> 00:02:57.199
So if I know that a certain page puts a certain resource on the cache, as an attacker, I can just request this uh resource and time and see how long did it take um for this resource to arrive.
00:02:57.360 --> 00:02:59.039
Um if it was short, it was cached.
00:02:59.120 --> 00:03:05.599
So I could say, um, let's see if uh Chris has something from uh whatever randombank.com in his cache.
00:03:05.680 --> 00:03:17.599
And if I know that uh the logo of randombank.com is in Chris's cache, I can with a certain probability say that Chris is likely a customer of uh randombank.com and uh has been there recently.
00:03:17.759 --> 00:03:19.199
Um of course that's upgrade.
00:03:19.280 --> 00:03:23.919
So uh pages um yeah, could sniff what was in other people's caches.
00:03:24.400 --> 00:03:43.439
So um browsers, all of them essentially started isolating their caches, which means um even if now you agreed on the exact same URL, exact same uh version number, um, it didn't work anymore because browsers just yeah, refused to give you access to something that was not the current pages uh caching context.
00:03:43.759 --> 00:03:54.000
So, long story short, um this is like part of the motivation, but then of course, um you mentioned uh I work on things that were previously not um possible on the web.
00:03:54.159 --> 00:03:58.080
And um, one of the things that we started having on the web is um Web AI.
00:03:58.240 --> 00:04:33.199
So um it is one thing if you don't have jQuery and you need to uh download it again, um, even if you have it already, but it's an entirely different thing if you work with AI applications, and those AI applications try to load a model like uh let's say the Whisper um audio uh transcription model, and um you use two different apps that would depend on the same model, but of course each of them has to download the model again, and um, it starts to become prohibitive relatively quickly, which is why we have seen a lot of web AI demos, but we've not seen that many um actual production rollouts with uh AI.
00:04:33.360 --> 00:04:42.959
Um, people might remember the last time I was on a show, this was uh I forgot when, a year ago maybe, um, when we talked about Web AI, um, but in the context of built-in AI.
00:04:43.120 --> 00:04:58.000
So one of the approaches to dealing with this problem is to just say, okay, so rather than having each page download its own model, we just put one model in the browser and um call it the built-in um browser uh model that you can just use from high-level JavaScript APIs.
00:04:58.160 --> 00:05:00.480
This works for many cases, but not for all of them.
00:05:00.720 --> 00:05:02.639
And um, people also want control.
00:05:02.800 --> 00:05:18.959
So people uh in some cases um need absolute control, they uh actually exactly want to know what is, for example, an embedding model that they use so that uh they can run embeddings on the server and on the client, and the same embeddings, whatever uh location they've been created at still work.
00:05:19.360 --> 00:05:24.560
So there's this, but then also there's things like uh web fonts.
00:05:24.639 --> 00:05:32.319
Like um, if you think uh in uh CJK languages, um, people need web fonts um that are um yeah very, very powerful.
00:05:32.399 --> 00:05:36.399
They have the full range of uh the glyphs um in CJK languages.
00:05:36.560 --> 00:05:45.199
You have uh emoji uh color fonts that are really big that a lot of pages need because like uh native uh emojis support sometimes isn't great.
00:05:45.360 --> 00:05:53.199
So, for example, on Windows um for a long time, I'm not sure if today still, but you had um instead of the flag emojis, you had like uh the named flag.
00:05:53.360 --> 00:05:59.360
So instead of the German flag, you had DE as a uh like icons, which just didn't look great.
00:05:59.519 --> 00:06:00.800
Um, so these kind of things.
00:06:00.959 --> 00:06:05.040
So people started uh to depend on um uh web fonts for that.
00:06:05.279 --> 00:06:14.000
So there's a whole range of things, like uh resources in general that uh people want, but they don't necessarily want to download.
00:06:14.160 --> 00:06:21.920
So if they have them, it's great, but like downloading them every single time can become expensive, um, like download-wise, storage-wise.
00:06:22.079 --> 00:06:41.759
Um, if you work in AI and you uh download, let's say Gemma 4, um one of Google's models, uh 2.5 gigabytes, I think, uh, in one of the typical web runnable uh quantizations, um you just end up with a browser profile that is full of cached resources that you already have several times if you work with several applications.
00:06:42.000 --> 00:06:48.160
And long, long story short, um, this is where then finally um the cross-origin storage API proposal comes in.
00:06:48.319 --> 00:06:57.360
The core idea is rather than addressing things by their URLs, so the jQuery uh URL kind of problem, we address things by their content hash.
00:06:57.519 --> 00:07:01.920
So if you have a resource, you can calculate the hash of that resource.
00:07:02.079 --> 00:07:17.759
And as long as the hash stays the same, it doesn't matter if you have downloaded it from my SketchGD server or Chris's official CDN or Microsoft's super, super highly official CDN, as long as the hashes match, um, you can be sure that the integrity of the resource is given.
00:07:18.000 --> 00:07:21.519
So this is the first thing that we sort of uh thought about.
00:07:21.600 --> 00:07:23.680
So it's a content address storage.
00:07:23.839 --> 00:07:29.360
Um, so wherever you got a resource from, as long as the hash matches, um, it can be shared.
00:07:29.600 --> 00:07:34.399
And um, cross-origin storage is also an API that has different entry points.
00:07:34.480 --> 00:07:37.839
So it's an imperative API, but also a declarative API.
00:07:38.000 --> 00:07:46.720
Um, imperative in a sense of um you can ask the browser, hey, browser, do you have in your cross-orig storage a resource with the hash ABC123?
00:07:47.199 --> 00:07:53.759
Um the browser will then look in its cost cache and say, yes, I have that, or it will say, No, I don't have it.
00:07:53.920 --> 00:07:57.439
Um, if you have it, great, because then you can just use it.
00:07:57.519 --> 00:08:01.439
Um, if not, you can download it from the network, just as you uh would do today.
00:08:01.600 --> 00:08:15.120
And then, of course, ideally, once you download it, uh put it in the cost cache for the next time for yourself, like your own uh usage, but also of course for other pages that you um yeah hope that will also use that resource.
00:08:15.199 --> 00:08:16.720
So it's a giving and a taking.
00:08:16.800 --> 00:08:30.560
So um the idea is really um if you put something in the cost cache, there needs to be a certain likelihood that other pages would use this um resource as well, or that you um could use it if some other page has put this into the cost cache.
00:08:30.720 --> 00:08:33.759
There's different um levels of sharing.
00:08:33.840 --> 00:08:37.360
So um you can think of like the easiest one, which is global share.
00:08:37.519 --> 00:08:43.279
So you put something and it's just there, like in the old days with the HTTP cache that was shared.
00:08:43.440 --> 00:08:48.320
Um, but then there's nuances in between, like you can say um we are, let's say, an office suit.
00:08:48.559 --> 00:08:54.159
So we have uh uh write.example.com, calc.example.com, and slides.example.com.
00:08:54.240 --> 00:08:59.840
And this office suit has a shared um AI model that uh they use, for example, for a proofreading.
00:08:59.919 --> 00:09:02.799
So I could say, okay, so this is my shared AI model.
00:09:02.879 --> 00:09:07.679
Um, I want to make this available for my three pages that I I know um use this resource.
00:09:07.759 --> 00:09:09.759
And when I say pages, that's actually origins.
00:09:09.840 --> 00:09:12.000
Um need to be precise with the terms here.
00:09:12.080 --> 00:09:16.799
Um so you can say, yeah, I'm sharing this resource with these three uh origins.
00:09:17.120 --> 00:09:20.080
And then um you can also um just not say anything.
00:09:20.159 --> 00:09:34.240
So if you um just put a resource in the cache, um, it will be shared for the same site resources, um, which is like a little bit more complex, but you can think of it um as the um all of the subdomains of a of a given um URL.
00:09:34.559 --> 00:09:37.440
So more or less that's the entire story.
00:09:37.519 --> 00:09:40.000
And then um I said this is the imperative API.
00:09:40.080 --> 00:09:43.919
There's also a declarative way of tapping into the cost um storage.
00:09:44.080 --> 00:09:48.399
And um, the idea there is um you today when you load a script, you put a script tag.
00:09:48.559 --> 00:09:54.240
Um, if you load a style sheet, you put a link um href uh pointing at the CSS resource.
00:09:54.399 --> 00:10:05.600
Um and the idea there is to just say um by adding an attribute, cross-origin storage, you opt those resources into taking part in your entire uh cross-ordin storage story.
00:10:05.759 --> 00:10:23.360
So you say um this is my um, let's say tailwind, and I know the tailwind version 123 has their hash ABC uh four five six, and um you put this information in the integrity um attribute on the link tag and in the cross-origin storage uh attribute, you put how you want to share this resource.
00:10:23.440 --> 00:10:26.159
So, like if a tailwind or something like that, it would be global.
00:10:26.240 --> 00:10:29.440
So you would put a star, um, which makes it available globally.
00:10:29.679 --> 00:10:33.840
And um, yeah, if the resource is found in the cost cache, it will be just used.
00:10:34.000 --> 00:10:39.039
And if it's not, it will be downloaded from the URL that you have given and then put in the cost cache.
00:10:39.279 --> 00:10:42.000
And then, of course, I said the integrity is part of this.
00:10:42.080 --> 00:10:52.559
So um, whatever URL you put there, it could be your own server-hosted, um, self-hosted uh server, it could be um a CDN of whatever tab or jQuery or whatever.
00:10:52.639 --> 00:11:06.879
Um, as long as the integrity matches, the uh hashes match that you um mentioned um is the one that you expect, and then the downloaded bytes have exactly that hash, you can be sure that um the resource is um the one that you actually expected.
00:11:07.120 --> 00:11:09.519
So that's more or less the story.
00:11:10.559 --> 00:11:17.600
I mean, it solves the problem also that CDNs going away or CDNs being uh domains expiring, people taking those over.
00:11:17.679 --> 00:11:26.000
I mean, we had that problem, I think, with one of the jQuery extensions kind of things, where then a malware distribution happened because people just pointed to a URL.
00:11:26.240 --> 00:11:28.879
Now, my question is uh I have a few questions.
00:11:28.960 --> 00:11:34.320
Uh the first one is like uh we do uh we do this by hash, that makes a total sense.
00:11:34.399 --> 00:11:36.240
That's what we did with BitTorrent as well.
00:11:36.399 --> 00:11:39.279
But who controls the hashes and who generates them?
00:11:40.080 --> 00:11:48.639
So how do you know that the hash that that actually you have right now is the one that has been uh has been the proper one, not a malware controlled one.
00:11:48.720 --> 00:11:54.080
Is there a centralized service or a W3C protocol where you can get the hashes from?
00:11:54.639 --> 00:11:55.360
So it depends.
00:11:55.440 --> 00:12:00.960
Um, if you want to use your own resources, of course, you control them, you can calculate the hashes yourself.
00:12:01.120 --> 00:12:05.200
Um, you can always calculate the hashes yourself, even for resources that you don't control.
00:12:05.360 --> 00:12:10.639
So you can um download something from a CDN and then just uh calculate the hash.
00:12:10.799 --> 00:12:14.159
Um ideally, the CDN already publishes uh the hash.
00:12:14.320 --> 00:12:18.080
If you think in the AI space, um most people get their models from Hugging Face.
00:12:18.320 --> 00:12:24.720
Hugging Face publishes all the um SHA 256 uh hashes alongside each of the model resources.
00:12:24.960 --> 00:12:30.080
Um ideally, um yeah, you just have the uh hashes already.
00:12:30.159 --> 00:12:36.320
Um if you think uh in the world of uh npm, each of the resources on npm um has a hash already.
00:12:36.399 --> 00:12:44.159
So there's uh JS Deliver, one of the um like on top CDNs, um, make available the hashes for all of the NPM resources.
00:12:44.399 --> 00:12:54.559
So um there's no central institution or something that would publish a hash because yeah, it wouldn't really make sense, and also everyone can just calculate the hashes themselves.
00:12:54.799 --> 00:13:06.559
So in the case of as I said AI, um I guess most people would trust the uh hash that is uh published by Hugging Face, but then even then something could go wrong on the way, like there could be a bit flip or something.
00:13:06.720 --> 00:13:15.200
Um but in the browser, the um API built into um the browser, like the cost um API, would still check the hash.
00:13:15.279 --> 00:13:21.039
So it would say I'm expecting a resource to arrive in the cost cache that has the uh hash ABC123.
00:13:21.360 --> 00:13:35.519
But if the um actual resource that comes down um through the wire, like after a fetch or something, is um presented with a different hash, it would then just refuse this resource and say, like, oh, there's a data um error, so that's a hash mismatch.
00:13:35.679 --> 00:13:38.159
I won't put that resource in the in the cost cache.
00:13:38.480 --> 00:13:47.600
Um one of the like, I guess, most popular cases of this um abuse scenario that you mentioned happening was I think polyfill.io.
00:13:48.000 --> 00:13:55.440
Um I think it came out of the Guardian or something, so some UK um publisher or maybe Financial Times, I'm not sure anymore.
00:13:55.600 --> 00:14:09.279
Um, but like they were taken over by I think some Chinese investor, and then this Chinese investor decided to just apart from delivering polyfills, also to deliver whatever tracking and abuse and stuff um software.
00:14:09.519 --> 00:14:13.039
So with this, um it would get noticed immediately.
00:14:13.120 --> 00:14:25.840
So um you would call the same URLs as always, but then all of a sudden something else would come back that is no longer um yeah, uh meeting the hash requirements, and um you would catch it in the other thing, of course, is then the storage on my device.
00:14:26.000 --> 00:14:35.279
Like, do I uh uh do I the but once I call the API, do I get to pick a folder, or is this something that happens in memory as part of the browser?
00:14:35.440 --> 00:14:38.399
Or uh and in what format is the data being stored?
00:14:38.559 --> 00:14:45.279
Is it just as files or is it in a SQLite database, or how do I how do I pick in my device where I want to store these things?
00:14:45.679 --> 00:14:55.200
So in the native browser implementation, um you don't do anything as a user, you just uh as a developer call the API, and then the browser just takes care of uh storing the file somewhere.
00:14:55.279 --> 00:15:09.279
So I guess the simplest implementation could be to just put it somewhere in your browser profile, um like application support, Chrome, Edge, whatever you have as your browser, somewhere deeply nested um in your browser uh browser profile.
00:15:09.360 --> 00:15:11.759
Um, but this is more uh an implementation detail.
00:15:11.919 --> 00:15:20.159
The browser could, for whatever reason, decide to put those into um blobs in an index DB or SQLite database, um whatever is cheapest.
00:15:20.240 --> 00:15:24.960
Um it's an implementation detail that you as a developer um don't need to be concerned with.
00:15:25.200 --> 00:15:32.240
Um you can try already some of the um like demo implementations um that I did.
00:15:32.320 --> 00:15:43.919
Um if you go to goo.gleslash cos-chromium, um you can download a special Chromium um build for Mac that has the API already um enabled and you can just test it locally.
00:15:44.000 --> 00:15:47.360
It even has DevTool support so you can inspect what is going on.
00:15:47.519 --> 00:15:51.679
Um this is an early prototype, it's not uh official at all.
00:15:51.759 --> 00:15:57.519
Um, but for just seeing how the API would work, um, it is very um useful already.
00:15:57.840 --> 00:16:05.600
Um like this is one thing, um, but then also um you mentioned how the data is stored.
00:16:05.679 --> 00:16:09.120
Yeah, again, this is something that each browser vendor can decide for themselves.
00:16:09.200 --> 00:16:13.279
Um, I think most of them will just do something that already is implemented.
00:16:13.360 --> 00:16:26.240
So um, I guess there are some code paths that you can share with, for example, the cache API, like the regular um SOS worker kind of cache API, um where you have similar um requirements, you need to store vlogs somewhere, um, files.
00:16:26.399 --> 00:16:28.080
There's the OPFS API.
00:16:28.159 --> 00:16:35.200
So I think um for many browsers, um, yeah, it will be not that many new things to invent if they decide to implement.
00:16:35.360 --> 00:16:43.039
Um, I just had my uh AI uh implement a whole bunch of uh yeah different browsers uh with this API.
00:16:43.200 --> 00:16:50.639
And um, like looking at the code that uh Claude at least generated, it was typically around um 45,000 lines of code.
00:16:50.720 --> 00:16:59.120
So not a massive, massive change um compared to uh like I don't know, other features that require super um substantial changes in the code base.
00:16:59.519 --> 00:17:04.079
Uh that of course brings me to storage limits and storage uh opportunities.
00:17:04.240 --> 00:17:13.599
I remember when we did local storage for the first time, and then we didn't set any limits in Firefox back then when I worked in Mozilla, and then there were scripts that basically flooded my hard drive with like two seconds.
00:17:13.839 --> 00:17:16.480
Um is there a quota API?
00:17:16.640 --> 00:17:20.319
Is there is there a way of knowing what can be stored and what can't be stored?
00:17:20.720 --> 00:17:25.920
So um the core idea is to just have the same logic as with uh the regular cache API.
00:17:26.079 --> 00:17:30.480
Um it should be impossible for one origin to flood your um cache.
00:17:30.640 --> 00:17:54.400
So there's like implementation limits uh in place where you can just say um this is um like most browsers do do it in a way that they uh don't look actually at the actual free disk space, but they um make up, for example, 10 gigabytes uh free disk space to avoid finger printing so that you don't work on the actual free disk space, but on this supposed disk uh space.
00:17:54.640 --> 00:18:06.319
And then um you just look at how much of this is already um occupied by other um resources like index db, cache API, whatever, and um you then get a share of this.
00:18:06.559 --> 00:18:09.039
So um again, there's nothing new invented.
00:18:09.119 --> 00:18:11.759
Um there should be no new attack vectors.
00:18:11.920 --> 00:18:18.799
Um, one attack vector, of course, that you might be wondering about uh uh about is wait, um, this entire timing attack.
00:18:18.880 --> 00:18:26.079
Um so if you can determine um there was a resource that is uh in someone's cache, how does this new proposal deal with it?
00:18:26.319 --> 00:18:30.319
And the response to that is um the so-called public hash list.
00:18:30.480 --> 00:18:39.039
So the idea of this is um we only allow you to share resources globally if those resources meet a popularity minimum threshold.
00:18:39.200 --> 00:18:50.319
So if you have something like React, that's on many, many pages, um, that's a very popular uh framework, or let's uh even uh today uh use jQuery, still the most popular framework of them all.
00:18:50.480 --> 00:18:52.720
Um it is a very popular framework.
00:18:52.799 --> 00:19:04.160
So um by looking at um your cache, you can find out yes, the user visited a site that has React or has jQuery or something, um, but like there's not much that you could derive from this.
00:19:04.240 --> 00:19:22.480
So there's no private information like before when I mentioned um your uh bank logo that someone in theory could put into the cost cache and make available globally, um, because the bank logo would not be a resource that is uh globally very popular, it would not be um yeah, it would not be shared um with everyone.
00:19:22.799 --> 00:19:31.680
So this is um one way of uh avoiding this attack, and then the other is um just to reduce the amounts of what we call probes.
00:19:31.839 --> 00:19:36.000
So uh a probe is when you ask the cost cache, hey, do you have the resource ABC?
00:19:36.160 --> 00:19:37.440
Um, two, three.
00:19:37.599 --> 00:19:50.079
And um, by just limiting the uh number of probes that you can make, um, you can avoid um having like uh what um what most people say uh 32 bits is enough to identify you uh on the internet.
00:19:50.400 --> 00:20:15.359
Um so by having a probe limit that is way beyond that, you can avoid um yeah having uh you exposed to this kind of attack where you say um this is something that uh you have in your cache and all and then you create a bit vector and hope for a 32 uh bit vector uh to then identify the person, um the browser will actively make it impossible to uh probe too many times.
00:20:15.759 --> 00:20:18.000
So uh who's on board with that one already?
00:20:18.079 --> 00:20:25.920
I mean, you have uh I posted here as well, you have a preview in Chrome, uh which is Chromium, which means probably Brave and Edge as well.
00:20:26.160 --> 00:20:34.480
Uh but uh is there any insight, is there any interest from Apple's side, from Firefox's side already as well, or is it just very early days on that?
00:20:35.119 --> 00:20:36.880
So it is definitely early days.
00:20:37.039 --> 00:20:42.799
Um there are um position senders position requests um for Apple and Mozilla.
00:20:42.880 --> 00:20:48.799
The Mozilla one was filed by a Mozilla employee, um, the other one was filed by uh by us by Chrome.
00:20:49.119 --> 00:20:54.319
Um who is on board with that API also is a lot of um partners that we work with.
00:20:54.480 --> 00:21:03.200
So um there's the Chrome status page for um the API, and on this Chrome status page we list um the partners that are interested already and have implemented.
00:21:03.359 --> 00:21:11.599
Um amongst them are Transformers.js, um, WebLLM and uh WLAMA, so in the AI space, all the big names essentially.
00:21:11.759 --> 00:21:19.680
Um, because of that for them, of course, this uh AI model um caching is a big, big uh prohibiting factor, limiting factor.
00:21:19.839 --> 00:21:25.440
Um internally, we have Light RT, uh LMJS, who is also working on adding support.
00:21:25.680 --> 00:21:29.279
So we have essentially the whole range of AI frameworks.
00:21:29.440 --> 00:21:34.400
Um, Flutter is another partner um internally at Google that has implemented the API.
00:21:34.559 --> 00:21:42.480
So if you have two Flutter applications, um, they both can share through COS the SKIA framework that Flutter applications use to render.
00:21:42.720 --> 00:21:52.240
And um in the WebAssembly space, we also um have the MScripten open source um team on board at Google, and they also have uh added support to MScripten.
00:21:52.480 --> 00:21:59.839
So if you um work on a WebAssembly package, you can opt in your build to um be cross-origin uh shareable.
00:22:00.319 --> 00:22:20.160
So I think that's also something that could be interesting for a lot of bigger packages like SQLite, like FFMHEC, all those big, big tools that people compile to WebAssembly and then use on like your video editors or any kind of local first database apps, for example.
00:22:20.559 --> 00:22:23.039
So there's a lot of ecosystem interest.
00:22:23.119 --> 00:22:36.640
And there's also someone from the like US data public space who has expressed interest in this API for big law databases that this person wants to work with.
00:22:36.799 --> 00:22:41.759
So there's a lot of interest from essentially all those spaces.
00:22:42.079 --> 00:22:44.480
Internally at Google, we also have the Google Fonts team.
00:22:44.799 --> 00:22:53.119
So they make uh the Google Fonts API available, and through this API you can download the Google Fonts directory of fonts.
00:22:53.519 --> 00:23:03.279
The big, big ones are, of course, the Noto emoji font that is really big but also really beautiful and yeah, makes your emoji look consistent on all the platforms.
00:23:03.440 --> 00:23:06.160
So there's a lot of interest uh from Google Fonts as well.
00:23:06.480 --> 00:23:10.079
You also have an extension here that actually allows you to play with that.
00:23:10.160 --> 00:23:10.799
How does that work?
00:23:10.960 --> 00:23:14.559
Does that simulate the storage in another way?
00:23:14.640 --> 00:23:18.960
Or I mean that there's extensions for all the uh major block browser platforms.
00:23:19.039 --> 00:23:22.319
So you can install it for Chrome, for uh Firefox, and for Safari.
00:23:22.480 --> 00:23:27.599
And then of course, when I say Chrome, this uh includes all of like Edge and Brave and uh all the other Chromiums.
00:23:27.839 --> 00:23:33.599
And um, the way this works is um that it injects the proposed API into each web page.
00:23:33.759 --> 00:23:40.640
So uh navigator.cross origin storage dot request uh file handle um would be the uh imperative API.
00:23:40.799 --> 00:23:52.240
It injects that uh into each pages um that you uh browse to, and then um it has a so-called um extension off-screen page, and this off-screen page does have a cache.
00:23:52.400 --> 00:23:58.720
Um, so internally it just uses this off-screen pages service worker uh cache.
00:23:58.799 --> 00:24:07.759
Um, but as a developer, you get exactly the um experience that you would get um from the final API, just um bundled into an extension.
00:24:07.839 --> 00:24:17.119
So um the idea is of course, um if there's any kind of changes to the API, which still might happen, it's early A's, um, we will reflect them in the extension.
00:24:17.200 --> 00:24:27.359
So if you work with the extension code against the extension um API surface, um, you will at some point, if the uh API changes, have to make some adjustments locally.
00:24:27.440 --> 00:24:32.480
But then once the API ships um in Chrome, hopefully, uh sometime in Q4.
00:24:32.960 --> 00:24:38.720
Um if you have coded against the extension, um, it should be just something that is uh a zero up for you.
00:24:38.799 --> 00:24:40.240
So no changes required.
00:24:40.319 --> 00:24:54.400
Um the extension would then just recognize oh, the browser already has the API natively, I don't do anything, so the extension becomes a no-op, and um you can uninstall the extension um if you want to um after the browser has gained native support.
00:24:54.720 --> 00:25:03.279
The last thing, of course, every time we came up with some storage bits were like uh uh um was it synchronous, was it asynchronous, what is the speed of it to load?
00:25:03.440 --> 00:25:09.119
Uh, I guess you didn't go for a service worker because you could have extended a service worker to do that as well, right?
00:25:09.440 --> 00:25:22.240
Um so the service worker cache, yes, to some extent, but then it doesn't mentally really super well fit the service worker model, um, because there's various ways um how you could feed into the cost cache.
00:25:22.319 --> 00:25:29.759
So um you could download from a resource, but you could also just make up your own um blobs from whatever local uh logic that you have.
00:25:29.920 --> 00:25:35.680
You could even imagine um, like a lot of people have downloaded uh AI models locally to OLAMA or something.
00:25:35.839 --> 00:25:39.359
So um you could even imagine having some sort of browser setting.
00:25:39.519 --> 00:25:50.240
You could say um I want to uh upload um with uh scare codes my local AI model that I already have from OLAMA into the cost cache, so that would not be a URL to begin with.
00:25:50.319 --> 00:26:03.519
Um so there's a lot of um nuances there where we said um it makes more sense to develop this as its own um like storage mechanism that is clearly from the start um content addressed.
00:26:03.759 --> 00:26:08.000
Um but then like there's of course all the different uh entry points.
00:26:08.079 --> 00:26:15.680
So I mentioned before there's uh the link and the script tag entry point um where you can just have regular HTML um for fonts.
00:26:15.759 --> 00:26:18.559
Um you have uh CSS font face declarations.
00:26:18.640 --> 00:26:27.039
Um, so you declare a font face, like at font face, and then you uh at some point need to declare the uh source of um yeah, where the font should come from.
00:26:27.200 --> 00:26:33.440
And this source it looks like a function, so it's uh it's a URL parenthesis, then you provide the actual URL.
00:26:33.599 --> 00:26:41.839
And then after that, you have space separated um request uh URL modifiers, and um one of them is integrity that's already there.
00:26:41.920 --> 00:26:48.559
Um so for just making sure that uh the font that you get back has actually the um hash that you expect it to have.
00:26:48.720 --> 00:26:57.039
Um but then with this new proposal, um you would also have a uh URL request modifier cross-orget storage that opts in this resource uh into cost.
00:26:57.440 --> 00:27:06.480
And then the final integration that we have will be for fetch, so just a regular uh fetch API, um, where you have a request init uh option.
00:27:06.640 --> 00:27:30.960
So um just like today, where you have um as a first parameter the URL, and then as a second, um you have an object, and one of those object fields would be cross-origin storage, again with all those uh separate uh options that I said before, like you could have star for global sharing, you could have um empty string for same-site sharing, and you could have an array of the origins that you want to uh share your resource with.
00:27:31.119 --> 00:27:43.920
Um, so yeah, in the background, um yeah, as I said, it might be even using some logic that is already there from OPFS, from the cache API or something, but like it's a separate thing as a storage mechanism, as brokehost.
00:27:44.400 --> 00:27:47.200
Now, uh, what would you want people to do to help you with that?
00:27:47.279 --> 00:27:49.920
Like you have an audience of millions here right now.
00:27:50.160 --> 00:27:52.960
What would what would make you happy if people play with it?
00:27:53.119 --> 00:27:54.400
Where can they give feedback?
00:27:54.640 --> 00:27:56.640
What kind of feedback are you looking for?
00:27:57.039 --> 00:28:02.559
So because the X Engine exists for all of the browsers, um definitely do try the API.
00:28:02.720 --> 00:28:08.319
Um there's an explainer um that we have that is uh pretty pretty comprehensive.
00:28:08.400 --> 00:28:12.880
It has a lot of examples that you can just hopefully copy and paste and um just work with it.
00:28:13.039 --> 00:28:26.480
Um there's some convenience functions that I have published uh on my GitHub around, for example, getting a resource and making sure this entire uh Sha hashing um is being resolved correctly for you.
00:28:26.720 --> 00:28:29.920
Um so try the API, give us feedback.
00:28:30.079 --> 00:28:39.599
If you see you as a developer can use this for your project, for your app, um definitely um on our GitHub there's a way to express support.
00:28:39.759 --> 00:28:44.720
So I can formally say, like, we are Project ABC, um, we publish this and that.
00:28:44.960 --> 00:28:48.559
Um, we have exactly this problem that costs would solve.
00:28:48.640 --> 00:28:50.079
Um, here is the numbers.
00:28:50.160 --> 00:28:51.680
Um, like I don't know, I'm making this up.
00:28:51.759 --> 00:28:52.880
So we are FFmpeg.
00:28:53.119 --> 00:29:16.160
Um not saying that FFmpeg does, we are FFmpegvasm, and we are being used on whatever these thousand pages, each of those thousand pages, sorry, origins, again, um the uh term somatic here, each of those thousand origins use the exact same copy of um WebAssembly, uh sorry, FFFMP sorry, FFMPEG, that's a hard word, um, to use uh for WebAssembly.
00:29:16.559 --> 00:29:21.200
And um, yeah, if this API existed, um this would help us a lot.
00:29:21.359 --> 00:29:38.000
So the idea there is really to demonstrate uh developer interest um with yeah, actual numbers that people can uh look at and say, yeah, uh as a browser vendor, if I'm considering this API over something else, um I can say, yeah, this does make sense for uh solving the use case.
00:29:38.240 --> 00:29:47.039
Um if you have any kind of feedback, of course, uh around the API shape, around um how things work, um definitely the GitHub is our uh place.
00:29:47.279 --> 00:29:52.799
Um once the code lands in uh Chromium, you can of course also file um implementation bugs.
00:29:52.880 --> 00:29:59.759
So if something is specified to do XYZ, but it actually does XYZ prime, um, you should tell us about this bug.
00:29:59.839 --> 00:30:03.519
So um, this is of course then once uh actual code lands.
00:30:03.680 --> 00:30:07.519
Um the first uh change lists, CL, um, are up.
00:30:07.599 --> 00:30:20.000
So if you're really interested, um I maintain um a list called uh uh awesome cross-origin storage, and on this list, awesome cross-origin storage, you will find um, for example, the umbrella bug.
00:30:20.160 --> 00:30:34.960
So if you are uh super eager to uh see every single thing that is moving around this API, you can um yeah, star the umbrella bug or even star one of the dependency bugs and see um how the um API progresses uh implementation-wise.
00:30:35.119 --> 00:30:56.240
But I the biggest thing today is try it out, um, make use of uh even just uh an application that already or an API that already has implemented um the um the API, so uh Transformers.js, as I mentioned before, like build an application with Transformers.js, enable um the flag in Transformers.js that opts you into using uh cross origin storage.
00:30:56.559 --> 00:30:57.759
Um nothing breaks.
00:30:57.920 --> 00:31:03.119
So from the start, this is uh conceived as a um progressive enhancement.
00:31:03.359 --> 00:31:18.240
So if you don't have the API, if you don't have the extension supported uh or installed, um if you use a completely different browser that um refuses to implement the API, which is always something that can happen, um, nothing should break.
00:31:18.319 --> 00:31:20.720
So you don't make it worse than it is today.
00:31:20.799 --> 00:31:26.319
Um, in the worst case, the person already has downloaded the Gemma 4 model and they just need to download it again.
00:31:26.480 --> 00:31:28.720
Um, but uh yeah, this is just how it is.
00:31:28.799 --> 00:31:33.680
Um you can make it better, um, but like you can't make it worse by using this APA.
00:31:34.720 --> 00:31:35.279
Excellent.
00:31:35.440 --> 00:31:36.400
Well, thanks, Thomas.
00:31:36.480 --> 00:31:37.920
This was once again an interesting thing.
00:31:38.000 --> 00:31:45.599
I'm gonna put an article around it as well once we have the recording here done and list to all the resources so people don't have to actually look at the banners that I put in there.
00:31:45.839 --> 00:31:47.599
And uh yeah, good luck with that.
00:31:47.680 --> 00:31:55.039
I think it's a uh it's a great opportunity to think about uh uh differently and the sizes that we want to store these days.
00:31:55.200 --> 00:32:03.440
Like, I mean, we we we we kind of gave up on CDNs for like things like jQuery because uh with HTTP2, it wasn't that much of an issue anymore.
00:32:03.680 --> 00:32:12.480
And people are not too worried about uh about long I mean performance has changed a lot because people take on a lot more things.
00:32:12.640 --> 00:32:21.759
I mean, you can turn you can turn your app if from a web app to an AI app just by renaming every loading into thinking and then making people wait that way.
00:32:21.839 --> 00:32:24.480
And we kind of got got used to that one.
00:32:24.880 --> 00:32:36.319
But it's a great opportunity to uh and I love that it's uh that it's a what uh uh uh WICG uh thing as well, and not just a uh a Google one, so that there's more people involved as well.
00:32:36.640 --> 00:32:42.960
And um, yeah, once again, innovating in public, and uh that's where people can take part in.
00:32:43.200 --> 00:32:46.960
And uh we need you to actually tell us about what you think about that.
00:32:47.039 --> 00:32:51.440
So take a look at the cross-origin storage bits and bobs that Thomas has talked about.
00:32:51.599 --> 00:32:54.000
And I want to thank you for uh bringing it up to me.
00:32:54.160 --> 00:32:56.799
So, any last words for people out there?
00:32:57.680 --> 00:32:59.039
Many one thing that I forgot.
00:32:59.119 --> 00:33:02.240
Um, one of the interesting integrations that we have is also Nuxt.
00:33:02.319 --> 00:33:07.759
So if you work uh with a Nuxt app, um you can also integrate um with the proposal from the start.
00:33:07.839 --> 00:33:19.599
So there's uh on Daniel Rose uh GitHub repo, there's a um a repo called um uh cross-original storage, and there's a beat plugin um that you can just enable with your Nuxt app.
00:33:19.680 --> 00:33:30.400
Um, so even if you don't build anything AI, and this was something that I super uh yeah emphasized um during the development, we shouldn't just solve this for AI, we should solve this for the general part.
00:33:30.559 --> 00:33:34.799
Um, like if you build a Nuxt app, uh definitely also just give this a try.
00:33:34.960 --> 00:33:40.079
Um, I think what you mentioned before, um, we gave up on uh CDNs and so on.
00:33:40.160 --> 00:33:47.440
Um this time, I hope we have a chance to get it right by working with the frameworks, with uh Nuxt and uh friends from the start.
00:33:47.519 --> 00:33:55.279
Um, yeah, we can get it right this time um so that uh the bundlers can actually be bundling uh aware of something like COS.
00:33:55.599 --> 00:33:59.119
Um so I think this is also something um that we can get uh right this time.
00:33:59.200 --> 00:34:02.000
So yeah, I think that's maybe the final word.
00:34:02.079 --> 00:34:03.519
Um thanks so much for having me here.
00:34:03.599 --> 00:34:07.519
And um, yeah, look forward to a lot of people testing.
00:34:08.079 --> 00:34:12.400
Well, enjoy Spain, I will enjoy Berlin, and it was great to have you once again.
00:34:12.559 --> 00:34:24.000
And uh um sadly enough, I guess you won't be in America because we're coming with the We Are Developers World Congress to San Jose at the end of the month, but I don't think that's on your list at the moment, is it?
00:34:24.639 --> 00:34:25.840
Uh not at the moment.
00:34:25.920 --> 00:34:30.800
I'm actually enjoying a travel-free September because my October and November will be crazy.
00:34:30.960 --> 00:34:34.400
But yeah, September is just me in my home office.
00:34:34.960 --> 00:34:40.239
Well, there will be lots of other people from Google and probably some of them that are involved with this as well that you can talk to.
00:34:40.400 --> 00:34:45.679
This was Coffee with Developers with Thomas Steiner once again, and uh we probably will have you again on the show.
00:34:45.840 --> 00:34:47.920
Thanks very much, and thanks for watching.
00:34:48.239 --> 00:34:48.880
Cheers.