flowchart TB
subgraph Excel[Excel host]
WB[Workbook cells / ranges / names / tables / settings]
CodeSheet[Workbook _BOARDFLARE sheet\nnotebook source + opening mode]
CF[Excel custom functions\nBF.OUTPUT / BF.FUNCTION / BOARDFLARE.EXEC]
SR[Long-lived shared runtime]
end
subgraph Parent[Boardflare parent application]
Tabs[Python tabs / task-pane UI]
Host[NotebookSession + NotebookSurface]
Bridge[Spreadsheet Bridge\nExcel driver]
Store[Live notebook store]
end
subgraph Child[Separate-origin notebook iframe]
Marimo[Stock marimo WebAssembly export]
Pyodide[Pyodide / browser CPython]
Inputs[bf.inputs Anywidget model]
Publish[bf.publish Anywidget model]
end
WB <--> Bridge
CodeSheet <--> Host
CF <--> SR
SR --> Tabs
Tabs --> Host
Host <--> Store
Host <-->|validated MessagePorts| Marimo
Marimo --> Pyodide
Pyodide --> Inputs
Pyodide --> Publish
Inputs <-->|workbook-input capability| Host
Publish <-->|outputs capability| Host
Host <--> Bridge
Store <--> CF
Architecture and Runtime
This page is for developers, security reviewers, and advanced workbook authors who need the implementation model. For normal workbook use, start with Getting Started and Working with Excel.
Boardflare gives substantial Python work a reactive marimo notebook while keeping Excel connected as the workbook-data, assumptions, review, and delivery surface. The shipping runtime uses a stock marimo WebAssembly export rather than a Boardflare fork. Boardflare owns the host integration around that runtime.
Complete runtime topology
The important boundary is that notebook Python does not receive an unrestricted Office.js workbook object or arbitrary external network access. The child runtime’s CSP keeps connect-src 'self'; workbook integration is exposed through the documented boardflare package capabilities.
Responsibility boundaries
| Layer | Owns |
|---|---|
| Excel / spreadsheet host | Workbook cells, formulas, defined names, hidden code sheet, host events |
| Excel shared runtime | Long-lived JavaScript runtime used by the task pane and custom functions |
| Spreadsheet Bridge | Host-neutral workbook capability contract and the Excel driver |
| Boardflare notebook host | Session startup, source persistence, reactive input/output capabilities, worksheet registry integration |
| marimo | Notebook editing, serialization, dependency graph, reactive execution, notebook UI primitives |
| Pyodide | Browser/WebAssembly CPython and compatible package runtime |
boardflare Python package |
Documented bf.ref, bf.inputs, and bf.publish interfaces plus Anywidget models |
| Notebook worksheet adapters | Streaming BF.OUTPUT and BF.FUNCTION integration with the live publication registry |
| Legacy execution path | BOARDFLARE.EXEC, workbook-stored legacy functions, and the runpy worker |
Boardflare deliberately does not depend on marimo private runtime modules, mutate minified marimo internals, replace the kernel worker, or persist a second executable Python catalog for notebook functions.
Calculation and authentication are separate lifecycles
The Notebook component has calculation semantics even when it is not visible. In Excel, the notebook runtime is kept mounted across task-pane navigation and is allowed to mount while Office authentication is still resolving.
flowchart LR
Start[Excel starts Boardflare shared runtime]
Calc[Mount notebook calculation runtime]
Auth[Resolve Office SSO]
Source[Restore saved source / starter]
Run[Run marimo + Pyodide]
Pub[bf.inputs / bf.publish connect]
Formulas[BF.OUTPUT / BF.FUNCTION resolve]
SignIn[Task-pane sign-in UI]
Start --> Calc
Start --> Auth
Calc --> Source --> Run --> Pub --> Formulas
Auth --> SignIn
This separation is intentional. A workbook that only needs saved BF.OUTPUT() or BF.FUNCTION() formulas can calculate without waiting for the sign-in UI. Office identity is not a prerequisite for the core calculation runtime.
Startup lifecycle
A fresh NotebookSession creates a session ID, secure nonce, source capability, and child iframe. Startup then follows this sequence:
sequenceDiagram
participant Excel
participant Parent as Boardflare parent
participant Child as Notebook child
participant Marimo
participant Python as Pyodide / Python
Excel->>Parent: Start shared runtime / mount Notebook
Parent->>Child: Load separate-origin notebook child
Child->>Parent: Request source capability\n(session + nonce + protocol + port)
Parent-->>Child: Transfer source MessagePort
Child->>Parent: source.initialize
Parent-->>Child: Saved source or no saved source + opening mode
Child->>Child: Fall back to bundled starter when needed
Child->>Marimo: Mount stock export in Edit or App presentation
Marimo->>Python: Start browser Python runtime
Python->>Parent: bf.inputs capability connection
Parent-->>Python: Initial workbook snapshot
Python->>Parent: bf.publish prepare / claim
Parent-->>Python: Publication acknowledged
The notebook frontend has a 90-second startup timeout. During normal startup, streaming Excel formulas can remain in Excel’s native #BUSY! state until a registry is available or startup fails terminally.
Workbook inputs, outputs, and formulas
Workbook data enters the notebook through declared reactive inputs, and calculated results return to Excel through published outputs and callable functions.
The canonical Python APIs, parameter signatures, workbook design patterns, formula behaviors, and type conversion contracts are documented in the reference:
- The Marimo Reactive Model and Python Notebooks: Reactive evaluation, UI controls, variable rules, and runtime constraints.
- The Boardflare Python API: Authoritative reference for
bf.inputs(),bf.ref(),bf.selection(), andbf.publish(). - Workbook Design: Inputs, Table Selections, and Outputs: Declaring input ranges, table selections, and
=BF.OUTPUT()/=BF.FUNCTION()formulas.
At the runtime layer, workbook inputs are managed by an Anywidget model that connects to the host’s workbook-input capability. Output values and callable functions register with the host’s publication store, allowing streaming custom functions to evaluate reactively as notebook cells calculate.
Notebook formulas and legacy formulas are separate
The add-in intentionally retains two independent worksheet execution systems:
flowchart LR
subgraph Notebook[Notebook path]
N1[BF.OUTPUT / BF.FUNCTION]
N2[Lightweight shared-runtime adapters]
N3[Live notebook store]
N4[bf.publish Anywidget]
N5[Retained Python values / callables]
N1 --> N2 --> N3 --> N4 --> N5
end
subgraph Legacy[Legacy path]
L1[Workbook Name Manager LAMBDA]
L2[BOARDFLARE.EXEC]
L3[Legacy runpy worker]
L4[Workbook-stored function object]
L1 --> L2 --> L3 --> L4
end
Notebook functions are not registered in Excel Name Manager and are not persisted as an executable function catalog. The legacy Editor does register Name Manager LAMBDAs that call BOARDFLARE.EXEC. A notebook bundle failure must not prevent the established BOARDFLARE.EXEC association from remaining available.
See Legacy Functions Editor for the compatibility workflow.
Workbook source lifecycle
Boardflare persists notebook source, not a frozen Python interpreter.
stateDiagram-v2
[*] --> BundledStarter: no saved notebook
[*] --> SavedWorkbook: saved notebook exists
BundledStarter --> SavedWorkbook: marimo Save + verified persistence
SavedWorkbook --> StagedUpload: upload .py
StagedUpload --> SavedWorkbook: marimo Save + verified persistence
StagedUpload --> SavedWorkbook: Restore saved notebook after startup failure
SavedWorkbook --> BundledStarter: Reset saved notebook
An uploaded .py file is staged in memory and starts a new Edit session. It does not overwrite the workbook code sheet until marimo Save reaches Boardflare and persistence verifies successfully. That distinction is why a broken upload can be discarded without deleting the last saved notebook.
Download flushes FileStore writes that marimo has already submitted and exports the latest source acknowledged by Boardflare. It cannot serialize editor changes that marimo has never submitted through Save.
Save and persistence sequence
sequenceDiagram
participant User
participant Marimo
participant FileStore as Boardflare FileStore
participant Source as Source capability
participant Sheet as Workbook _BOARDFLARE sheet
User->>Marimo: Save
Marimo->>Marimo: Serialize current notebook source
Marimo->>FileStore: saveFile(source)
FileStore->>FileStore: Queue save callback
FileStore->>Source: source.save(source, opening mode)
Source->>Sheet: Write notebook record
Source->>Sheet: Read record back
Sheet-->>Source: Stored source + metadata
Source->>Source: Verify source/hash/mode
alt verification succeeds
Source-->>FileStore: Acknowledge persisted source
FileStore-->>User: Boardflare status = Saved
else write/read-back fails
Source->>Sheet: Attempt previous-value rollback
Source-->>FileStore: Save failure
FileStore-->>User: Boardflare status = Save failed
end
Marimo’s own clean/dirty state is not proof that the asynchronous workbook write completed. The Boardflare save status is authoritative for durable workbook persistence.
Workbook persistence contracts and limits
Boardflare persists the complete notebook source, metadata, and opening mode directly in the workbook. The sheet layout (format version 1 on the hidden _BOARDFLARE worksheet), edit loop handshake, and size boundaries are maintained in the canonical reference:
- Workbook Editing: Code Sheet & AI Handshake: Layout of
_BOARDFLARE, theH1request counter andH2response handshake, and text-formatting rules. - System Limits and Constraints: Source size limits (200,000 UTF-8 bytes joined source, 32,000 characters per cell), execution timeouts, and payload limits.
Spreadsheet Bridge
Notebook code does not call Office.js directly. Host-specific workbook operations live behind @boardflare/spreadsheet-bridge.
flowchart TB
Notebook[Boardflare notebook integration] --> Bridge[Spreadsheet Bridge]
Bridge --> ExcelDriver[Excel driver]
ExcelDriver --> Office[Office.js / Excel workbook]
Validate save/reopen and worksheet-function startup in the Excel add-in before distributing a workbook.
Implementation boundaries
Session IDs, nonces, message ports, capability protocol messages, hidden worksheet layout schemas, shared-runtime stores, and driver internals are implementation details. Keeping those layers private lets Boardflare evolve the transport without breaking workbook code.
For complete API signatures, limits, and developer contracts, see the canonical Boardflare Notebook Reference.
For trust boundaries, AI data flow, iframe connection validation, package/network behavior, and executable-workbook guidance, continue to Security and Data Flow.