Transpiles Visual Basic for Applications (VBA 7.1, as in Word/Excel 2024) to JavaScript and runs it fully isolated from the host application — inside a sandboxed, opaque-origin iframe and a per-run WebWorker. Macros reach the host only through a capability barrier over JPC/postMessage.
This package is the language runtime and host-integration foundation. The Word/Excel object models are provided by a separate project and plugged in as the exposed host API.
Office macros are the classic malware vector. This runtime is built so that a hostile macro cannot:
- run in the host page's origin (it runs in an opaque-origin iframe + worker
under a strict CSP: no network, no external scripts, no
eval); - touch anything on the host except members explicitly marked
@exposed; - reach a host object it was not explicitly handed (object-capability tickets);
- smuggle executable text through the transpiler (all generated code passes a single validating emitter — escaped strings, validated identifiers, re-serialized numbers — and an ASCII-only verifier).
See docs/security.md for the threat model and invariants, docs/architecture.md
for the design, and docs/vba-language.md for the VBA semantics implemented.
import { MacroRuntime, ModuleKind, exposed } from "vba-macro-runtime";
// 1. Mark what the host exposes. Only @exposed members are reachable.
class Application {
@exposed get activeDocument() { return this.doc; }
@exposed cells(row: number, col: number) { return this.sheet.cell(row, col); }
}
// 2. Create the runtime with your host object model and UI hooks.
const runtime = new MacroRuntime(new Application(), {
msgBox: (text, buttons, title) => showDialog(text, title),
inputBox: (prompt) => promptUser(prompt),
log: (text) => console.log("[Debug]", text),
});
// 3. Load a VBA project (source per module) and run a macro.
runtime.loadProject([
{ name: "Module1", kind: ModuleKind.Standard, source: vbaSourceText },
]);
const outcome = await runtime.run("Module1.Main");Full VBA 7.1 language: Variant and all data types, arrays with custom
bounds, ReDim Preserve, UDTs, class modules (New, Class_Initialize,
Property Get/Let/Set, methods, default members), enums, Collection, the
complete operator set with Null propagation and banker's rounding, On Error GoTo/Resume Next/Resume, GoTo/GoSub, Select Case, With, For/For Each,
Do/While, conditional compilation (#If), and a broad built-in library
(strings, math, date/time, conversion, information, Format).
Not implemented (they don't exist in a browser; they raise trappable VBA
errors): UserForms, Declare (Win32 FFI), and CreateObject/COM. Extracting
vbaProject.bin from .docm/.xlsm belongs to the document-format project;
this package takes VBA source text.
npm install
npm run check # build sandbox assets + typecheck
npm test # 160+ unit tests (vitest)
npm run demo # build + serve the demo at http://localhost:8080
# Real-browser end-to-end (needs Chromium):
npx playwright install chromium
node scripts/build-assets.mjs && node scripts/build-demo.mjs && node test/browser-e2e.mjsZero runtime dependencies. Full bundle ~65 KB gzipped (~27 KB transpiler-only); cold-loads in ~25 ms locally.