I’ve always been interested in the concept of software as a “container” for other software. I’m not sure how much we recognize this, but lots of stuff we use runs inside other… stuff.
Here’s an obvious one —
Pretty much everything you do on your computer runs inside the operating system. And the OS is software like anything else. So we have software running inside other software.
Browsers are another thing: they’re a big container into which we pour the most insane stuff sometimes. Lots of websites are an unholy combination of HTML, CSS, JS and Lord knows what else (“Marketing wants access to Google Tag Manager…”).
Think about that for a second: your browser runs inside your OS, then it loads a website that uses JavaScript to basically load and run an entirely separate embedded application. In most cases, the applications are only peripherally aware of their containers. The browser knows the OS exists, and the JavaScript knows the browser exists, but they don’t spend a lot of time thinking about it – they just accept that as the environment and work inside it.
It all somehow works, most of the time. Software on software on software — it’s just turtles, all the way down.
In this respect, intranets are an interesting use case. I’ve long-maintained that intranets are usually just containers for other stuff. An intranet is often a framework, into which you load other functionality, which is often bespoke to the organization.
To this end, lots of content management systems are built in some form of the “everything is a module” architecture. Drupal, in particular, is famous for this. Even our product – Staffbase’s App and Intranet – is built on plugins. Our original feature – company news – is “just” a plugin. So is the ability to create simple pages. I’ve never tried, but I bet you could even remove them both if you wanted.
MediaWiki is software you’ve no-doubt used, maybe without knowing it. It’s the software that powers Wikipedia. It’s open-source, built in PHP. You can download it and run it yourself (…which I’ve done, way too many times).
I read an entire book on MediaWiki once (it’s free online, though I bought the hardcover; I just noticed there’s a new edition). It taught me that MediaWiki is simply a content framework that really allows you to expose stuff you decide to embed inside pages.
There are lots of formatting plugins to do things like display complicated math or weird citations. But there are also plugins like Cargo that let you integrate data from relational databases. And there’s Scribunto, which is a plugin that lets you write other plugins… but in Lua, instead of PHP. There are form plugins, and thread discussion plugins, and almost everything else – MediaWiki is effectively a container for other software.
I love this idea: the CMS as an… operating system? Instead of writing applications to run inside Windows, you’re writing applications to run inside MediaWiki.
And this brings us back to my employer: Staffbase. We allow this same thing: you can create “widgets” that live inside Staffbase content, and that can basically do whatever you like. In some senses, Staffbase can be an “organizational operating system” for integrating stuff that does… whatever.
We call Staffbase a “front door intranet.” But I like the idea of it being a “dinner party intranet.” Not only is it the way you get in, but once you get in there, you can find all sorts of interesting people and things with which you can interact. It becomes a place where wildly different functionality can be found and used.
The major difference between Staffbase and MediaWiki is that we’re a multi-tenant SaaS vendor, so we don’t let you do anything server-side. But given that most modern pages are dynamically assembled, rather than statically delivered, this isn’t much of a limitation anymore.
I really like the “Islands Architecture” metaphor from Astro, and I don’t know why this never caught in the first 30 years of the web.
Islands architecture works by rendering the majority of your page to fast, static HTML with smaller “islands” of JavaScript added when interactivity or personalization is needed on the page (an image carousel, for example). This avoids the monolithic JavaScript payloads that slow down the responsiveness of many other, modern JavaScript web frameworks.
(There are some great links in that article to prior art around the concept, if you’re interested.)
You can do this same architecture with Staffbase. We’ll handle delivering the page framework (the “operating system,” if you will), and your widget can do whatever you want.
We have an SDK for custom widgets, which I fundamentally misunderstood for a long time. The default npx command stubs out a widget using React to render, which led me to believe that React was a core pillar of the whole thing, but it turns out that’s not the case at all.
Our widgets are delivery-agnostic. They eventually run a method called renderBlock and they pass it a container which is the HTMLElement the widget represents. You can literally do whatever you want from there. In most cases, you’ll set the innerHTML of the container or otherwise manipulate it.
…but you can do literally anything, which is both good and bad.
Our widgets run in the global JS scope, which gives you access to the entire DOM. This is good in the sense that you have a lot of power, but… you also have a lot of power. (Insert line from Uncle Ben here…) No user can invoke a custom widget without it being installed (and presumably reviewed and vetted) by an admin, but there’s still not a lot of guardrails, by design.
To this end, I’ve been experimenting with how to “sandbox” functionality – call it “Fenced Island Architecture.” How could a widget execute in such a way that it can’t negatively affect anything outside of it? Could we get to a point where a widget executed inside some safe sub-environment?
I’m not the first person to have this idea, clearly. My history on the web goes all the way back to Java applets. And after that, we had Macromedia/Adobe Flash. These both bootstrapped little virtual machines inside web pages that executed code without letting it “reach outside itself.” The drawback was that they required plugins (though most everyone had them), and the bootstrapping took time and resources (Java applets were notorious for taking forever to appear and start working, and the “Skip Intro” link during Flash movie load times became a cliche long before Netflix added it).
Then, of course, there are IFRAMEs. Staffbase already has an IFRAME widget (two of them, in fact) – it comes pre-installed. I’ve played around with all sorts of permutations of this, and written a few variations of my own.
Unfortunately, IFRAMEs can be ugly and hacky. Sometimes they’re too isolated – for example, they don’t inherit styles, which you often want them to. Additionally, you have to do some acrobatics to get them to not make themselves obvious, especially when the size of the container content can change markedly (though support for this has gotten quite a bit better; I can reliably make an IFRAME non-obvious now, which wasn’t always possible).
Outside of IFRAMEs, I’ve had some luck with HTMX. This is one of the new “hypermedia” or “HTML over the wire” toolsets.
These are a weird combination of advancement and retrenchment – they’re dynamically sending out AJAX requests in the background, but instead of receiving JSON, parsing it, and translating it into HTML, they just get HTML fragments and paste it into the DOM.
HTMX has all sorts of declarative syntax to enable client-side functionality. For example, to retrieve new content and replace the existing content of a specific DIV when someone clicks a button, you do something like this:
<button hx-get="/html-fragment.html" hx-target="\#my-div"/\>
I got to wondering if this would enable some sandboxing, and I actually got some decent results with it. HTMX has all sorts of events to process the incoming HTML, and it was pretty easy to sanitize it, so that if someone tried to send back anything with raw JavaScript that could execute, I removed it.
The key is: I didn’t remove any of the declarative HTMX attributes. This means that you get all the functionality of HTMX (which is considerable), without letting someone dip into uncontrolled JavaScript. I’ve effectively “created” a safe application development language by subtracting the unsafe stuff.
Here’s an example: this is a widget I wrote called “HTMX Application.” You can embed it in any Staffbase content, and all it takes from the editor is an initial URL. It exchanges requests with a server to find the International Space Station and ask an AI some questions about it.
As near as I can tell, this is a “Fenced Island.” Nothing I could send back from my server infrastructure would let me run JavaScript on the page. It can even “lock” CSS inside a nested selector.
I haven’t totally verified it, but here’s my stab at the logic.
(Yes, HTMX requires a server to provide HTML – kind of a “formatting proxy.” But so do a lot of things. Given the combined problems of authentication and CORS, the idea of sending blind, unauthenticated requests to applications is often not possible. Also, I have some ideas here about a “common templating service,” but that’s for another time…)
Now, this is all a fun technical exercise, for sure. And I’ve been chasing this general idea for years – here I was talking about sandboxing languages in PHP over 20 years ago, I wrote an entire scripting subsystem for another CMS, and here’s me talking about it in both Denmark and Croatia at various times.
But there’s a larger and more important psychological component at play here. Employees have a lot of systems they deal with on a daily basis. I wrote about this a couple months ago:
The modern enterprise consists of a … constellation of software. Our industry has been trying to streamline this for years with varying degrees of success. The sheer number and variability of systems in use is something like a hailstorm that never ends. It’s often just thinly-managed chaos.
And most employees have very tight usage patterns around their platforms. They often use about 20% of what a given platform does. In a lot of cases, this functionality can be exposed through other, more efficient means… like embedding just the functionality they need in their front door intranet.
Front doors are great, but once you’re inside, let’s make it a dinner party.