This is one of the cleverest things I've seen in JS in a while.<p>In a nutshell, they use a same origin iframe to ensure the plugin gets its own copy of globals (so it can't mess up the globals your app uses), coupled with a proxy object which whitelists certain globals for the plugin to use along with certain vars from your app.<p>Really rather clever, although the guys who develop browsers should consider an API for something like this as it's becoming such a common use case.
wow, we are literally working this problem right now, and I made an off hand comment that it'd be nice if Figma shared how they did their plugins. thank you for this!<p>edit: having now read the article, this is amazing, lots of get insights here. one question to the author if you are reading: it seems like it would be a worthy idea to open source the 500 line, security-sensitive interface Realm-shim. Selfishly, we would use it, but also, we (and surely others) would add eyeballs to it to ensure it's correct. Since it's a small slice of the system, and agonistic to the product itself, it seems unlikely to be part of any kind of technical competitive advantage. Any plans to do so?
Well I'm surprised I haven't seen it yet, but I'm using Google Caja[0] for my own side project[1] (which, actually, I haven't touched in a while..) This allows plugin developers to create fully custom HTML plugins that run in the same frame (which is crucial for AudioNodes to be operated on by multiple plugins in my case.) Example of a plugin: <a href="https://github.com/lwansbrough/attack/blob/master/src/plugins/push2-test.html" rel="nofollow">https://github.com/lwansbrough/attack/blob/master/src/plugin...</a><p>Actually my demo goes as far as showing how one plugin can register a resource that is then used by another plugin. In this case I developed a plugin which registers a high level interface for access to an Ableton Push 2 device, and then another plugin uses that interface to draw to the Push's display using the canvas API. <a href="https://twitter.com/lwansbrough/status/1125842014128312320" rel="nofollow">https://twitter.com/lwansbrough/status/1125842014128312320</a><p>[0] <a href="https://github.com/google/caja" rel="nofollow">https://github.com/google/caja</a>
[1] <a href="https://github.com/lwansbrough/attack/blob/master/src/areas/daw/components/plugin/Plugin.vue" rel="nofollow">https://github.com/lwansbrough/attack/blob/master/src/areas/...</a>
I know I'm just piling on (positively), but this was <i>such</i> as excellent post. Honestly, I think my biggest reaction after reading this was how amazing the engineering culture must be at this company. Working at a startup, with a relatively small team, but still having the luxury of all that time to try out multiple different approaches, get feedback, can the ones that didn't work without making it feel like a "failure" in any way.<p>Major, major kudos. This is how engineering should be done.
I really like Figma's engineering blog. I find that they do a great job introducing the concepts that need to be understood with the level of detail in their implementation of those concepts. I'm always learning something new when I read an entry.<p>This is the first time I've heard of Realms API or QuickJS, will need to keep those in mind if I ever need to write a plugin system.
Thank you very much! this is very helpful for me. I'm making <a href="https://epiphany.pub" rel="nofollow">https://epiphany.pub</a> , it also needs to run users' code. I thought iframe was the only viable way to run third parties' untrusted code, I have never heard of Realms shim. I will looking into it!
Related work by the AMP team is their worker dom project: <a href="https://github.com/ampproject/worker-dom" rel="nofollow">https://github.com/ampproject/worker-dom</a><p>The gist is to mirror a subset of DOM apis in workers and project changes back out to the main page.<p>As far as I know a few companies have tried similar methods, but most write proprietary APIs, rather than using the DOM.<p>Still in development but the examples are promising.
I learned about Figma recently, in this HN-frontpage article about fast software: <a href="https://craigmod.com/essays/fast_software/" rel="nofollow">https://craigmod.com/essays/fast_software/</a><p>It really is delightfully fast. It's no surprise that the team behind it is producing this caliber of content.
Has anyone tried running the solution? It doesn't seem to work...
The below code results in the console logging the document object, which has the document object, and the code hits a ReferenceError when trying to log the 'a' variable.
Calls to p.whateverPropYouMakeUp result in the log 'get for target: ...'<p><pre><code> const proxyHandler = {
get(target, name){
console.log(`get for target: `, target, name);
return 'tacos';
},
}
const p = new Proxy({}, proxyHandler);
with (p){
console.log(`document with proxy: `, document);
console.log(`access random property: `, a);
}
</code></pre>
<a href="https://jsfiddle.net/wf02n4gs/" rel="nofollow">https://jsfiddle.net/wf02n4gs/</a>
Pardon my ignorance, but what if my JS was "for (;;) {}"? Can this handle heavy-CPU plugins? Maybe in a service/web worker? Part of the Realm API being a good use case for plugins I assume would include this kind of isolation but I admit to not having looked in detail.
Prior work in this area: <a href="http://www.adsafe.org/" rel="nofollow">http://www.adsafe.org/</a>. It is a dated library targeted at safe DOM manipulations. However, it was researched quite carefully (see the PDFs in the left column)
This post was such a ride.<p>At one point they found a fucking legitimate reason to compile a javascript interpreter to javascript(wasm) to run javascript!
Can't wait for the ability to trigger plugins on events instead of having to select them from a menu [1]. That would open the door to many more useful plugins running automatically for ex every time a file is saved.<p>1: <a href="https://www.figma.com/plugin-docs/whats-supported/#trigger-plugin-code-on-events" rel="nofollow">https://www.figma.com/plugin-docs/whats-supported/#trigger-p...</a>
Plugins. The security nightmare of desktop applications and the main reason Google store / Apple store is banishing developers accounts left and right.
Like Schneier always said "you can always create an unbreakable security for you but smarter ones will find holes in it". I'm curious how this one will hold on long term, let's say an year from now.
I think PayPal tried something like this awhile back that did not get much traction.<p>"PayPal Apps" Developer Guide (2010):
<a href="https://www.paypalobjects.com/webstatic/en_US/developer/docs/pdf/PayPalApp.pdf" rel="nofollow">https://www.paypalobjects.com/webstatic/en_US/developer/docs...</a>
That's a very interesting topic! Does anyone know of other resources (blog posts or books) talking about how to build such extensibility in a SaaS app?<p>Obviously, there are lots of inspiration to be drawn from apps we use everyday, such as GitHub, JIRA, etc, but these behind the scenes view is very informative.