How to Build a JavaScript Sandbox for Micro‑Frontend Applications

This article explains why sandboxing is essential in micro‑frontend systems, compares single‑instance and multi‑instance scenarios, and provides step‑by‑step implementations of JavaScript and CSS isolation using iframe‑based proxies, PostCSS namespace wrapping, and reusable APIs from the open‑source ConsoleOS project.

Alibaba Terminal Technology
Alibaba Terminal Technology
Alibaba Terminal Technology
How to Build a JavaScript Sandbox for Micro‑Frontend Applications

Background

Sandboxing is one of the most interesting parts of micro‑frontend architecture. Although a well‑defined convention can avoid most variable and CSS conflicts, large‑scale systems still need a technical sandbox to guarantee runtime isolation.

Single‑instance vs Multi‑instance

When a micro‑app is deployed as a single instance, only one instance occupies all browser resources at a time, so the sandbox mainly handles cleanup and state restoration during app switches. Multi‑instance apps share resources such as routing, styles, global variables and DOM, requiring a more complex sandbox.

JavaScript Sandbox Implementation

We isolate native browser objects by creating a closure that receives a mocked window, document, etc. The build step can wrap each sub‑app with a hook that injects the simulated objects.

function foo(window) {
  console.log(window.document);
}
foo({
  document: {}
});

ConsoleOS also provides a webpack plugin that generates a global hook:

// bundled code
__CONSOLE_OS_GLOBAL_HOOK__(id, function (require, module, exports, {window, document, location, history}) {
  /* bundled code */
});
function __CONSOLE_OS_GLOBAL_HOOK__(id, entry) {
  entry(require, module, exports, {window, document, location, history})
}

Alternatively the sandbox can be built at runtime with eval or new Function.

Native Object Simulation via iframe

Creating an iframe with a same‑origin about:blank URL gives us a completely isolated set of native objects that can be proxied.

const iframe = document.createElement('iframe');

We then wrap the iframe.contentWindow with a Proxy that returns sandbox‑specific objects, e.g. a sandbox document.

class Window {
  constructor(options, context, frame) {
    return new Proxy(frame.contentWindow, {
      set(target, name, value) {
        target[name] = value;
        return true;
      },
      get(target, name) {
        switch(name) {
          case 'document':
            return context.document;
          default:
        }
        if (typeof target[name] === 'function' && /^[a-z]/.test(name)) {
          return target[name].bind && target[name].bind(target);
        } else {
          return target[name];
        }
      }
    });
  }
}

CSS Isolation

Common CSS isolation techniques include CSS Modules, CSS namespaces, dynamic style sheets, and Shadow DOM. We chose a combination of CSS Modules and a custom namespace generated by a PostCSS plugin, which prefixes every style rule with the application’s unique prefix.

// host app
.next-btn {
  color: #eee;
}

/* sub app */
aliyun-slb .next-btn {
  color: #eee;
}

This approach allows multiple instances to coexist, works without a specific pre‑processor, and fully isolates different library versions.

Integration with Other Micro‑Frontend Systems

The sandbox implementation is open‑source on GitHub (github.com/aliyun/alibabacloud-console-os). Projects can import createContext, removeContext, or the convenience evalScripts API to run code inside the isolated environment.

import { createContext, removeContext } from '@alicloud/console-os-browser-vm';
const context = await createContext();
const run = window.eval(`(() => function({window, history, location, document}) {
  window.test = 1;
})()`);
run(context);
console.log(context.window.test); // 1
await removeContext(context);

For CSS sandboxing, a PostCSS wrapper can be added to the webpack configuration:

const postcssWrap = require('@alicloud/console-toolkit-plugin-os/lib/postcssWrap');
{
  test: /\.css$/,
  use: [
    'style-loader',
    {
      loader: 'postcss-loader',
      options: {
        plugins: [
          postcssWrap({
            stackableRoot: '.prefix',
            repeat: 1
          })
        ]
      }
    },
    'css-loader'
  ],
  exclude: /^node_modules$/
}
Sandbox architecture diagram
Sandbox architecture diagram
Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Frontend Architecturejavascript sandboxcss isolationiframe proxymicro-frontend
Alibaba Terminal Technology
Written by

Alibaba Terminal Technology

Official public account of Alibaba Terminal

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.