Skip to content

mustang-im/visualbasic

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

24 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

VBA Macro Runtime

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.

Why this exists

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.

Usage

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");

What's implemented

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.

Build & test

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.mjs

Zero runtime dependencies. Full bundle ~65 KB gzipped (~27 KB transpiler-only); cold-loads in ~25 ms locally.

About

Transpiler from Visual Basic to JavaScript. Both the transpiler and the script run in a browser.

Resources

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors