Architecture
The app is the VS Code extension running in its own window. It runs several processes on your machine. This page shows what each one does and how they connect.
The parts
Who does what
| Part | What it does | Runs in | Network |
|---|---|---|---|
| Shell | Starts the Node process and opens the window. Remembers the window's size and position. If you start the app twice, it shows the window that is already open. | onelake-studio.exe, Tauri | None |
| Window | Draws the tree, tabs, menus, dialogs and status bar. Each tab is the extension's page inside an iframe. It does not have the OneLake token. | WebView2, which is Edge | 127.0.0.1 only |
| Node process | The extension's code, unchanged. It handles sign-in, blocks anything that writes, turns names into tables, keeps the local catalog up to date, serves Excel, and runs Export to Fabric. | node.exe, dist/desktop.js | Fabric REST API, OneLake lists and metadata |
| Local catalog | A SQLite file on your machine. It stores all metadata: lists of workspaces, items and tables, table metadata, Delta history, opened models, and what was read. The tree reads it, even before you sign in. | A SQLite file, read with node:sqlite | None |
| Query server | Runs the SQL from every tab. Tabs connect to it with DuckDB's Quack protocol, and share one memory limit and the data already read. | DuckDB 2.0, in a separate process | OneLake: rows and files |
| Keep-offline engine | Downloads every table of a model set to Keep offline, so it works without internet. Queries never wait for it. It stops when there is nothing left to download. | DuckDB, a second process: one thread, 1 GB | OneLake |
| Disk cache | Stores the bytes DuckDB reads from OneLake. A file is downloaded again only if it changed. One cache per Microsoft account, used by both DuckDB processes. | Files, cache_httpfs | None |
| Excel's endpoint | Lets Excel PivotTables query a semantic model over XMLA. The queries run on the query server. | The Node process, HTTP on 127.0.0.1 | None |
| Command line | Sends its command to the running app, which answers with its own sign-in, cache and engine. If the app isn't running, the command line starts its own process. | bin/cli.mjs | Through the app |
| Fabric app | A model's Pivot, published with Export to Fabric. It runs in the browser after a Fabric sign-in and reads the model's tables there. | Fabric, and the browser | OneLake |
What happens when you run a query
- Each semantic model the query names is opened from its local copy. The first time, its definition is read from Fabric.
- dax-sql rewrites a query on a model as plain SQL over table names. A query that names no model is left as it is.
- The Node process refuses more than one statement and anything that isn't a read, using DuckDB's own parser to tell.
- Each table name becomes a view, made from the local catalog, and each file name becomes its
abfss://address. A name that doesn't exist fails here. - The query runs on the query server. Stop cancels only that tab's queries. A result over
maxResultRows(200,000 by default) is counted, and only the first rows go to the tab.
Sync
Lists of what exists come from the local catalog, not from OneLake. The local catalog is one SQLite file per account on your machine. The tree, SHOW ALL TABLES and Go To read it.
- Workspaces you have open or pinned are refreshed when their lists are older than
catalogTtlMinutes. - Every 12 hours, one process reads the lists for the rest of the tenant: five requests every 15 seconds. If Fabric answers 429, it waits a minute.
- A table read 3 times in 14 days has its metadata checked every hour. When nothing else is running, each new version is downloaded in full, so it works offline.
- With no internet or no sign-in, no request is sent, and everything already read still works.
The servers
DuckDB runs in a separate process. The Node process checks each statement before sending it: it must only read, and every name must resolve to a table.
- Statements go over Quack. Stop cancels only its own tab's statements.
- The OneLake token, the offline switch, and the data for the Logs and Performance tabs go over a separate OS pipe, because Quack logs everything it receives.
- Keep offline uses a second DuckDB process, so downloading a model's tables never slows a query. The two processes share only the disk cache.
- The server runs in UTC, because OneLake stores timestamps in UTC. Otherwise dates wouldn't match between tables.
The server and Keep offline in detail
Excel's XMLA endpoint
Excel talks to a semantic model using XMLA over HTTP, and the Node process answers. Excel sees the model as one cube: each table is a dimension, each column a hierarchy, and each measure is in [Measures].
Excel (MSOLAP) --XMLA over http://127.0.0.1--> Node process
Discover -> the model's tables, columns and measures, as a cube
Execute -> MDX -> model SQL -> dax-sql -> read-only check -> query server
- It understands only the MDX that Excel PivotTables send. Anything else gets an error that says what isn't supported.
- Subtotals and totals are calculated, not summed, so distinct counts and ratios are correct on every row.
- The port opens the first time you use Open in Excel. It listens on 127.0.0.1 only and needs a token. Requests from a browser are refused.
Export to Fabric
Export to Fabric is the only feature that writes, and it asks before writing anything. It copies the model's file into the lakehouse's Files/ folder and publishes the app with the Fabric REST API.
- The app doesn't hold a copy of the model. It reads the model from the lakehouse each time it runs.
- The app's function creates a read-only link for each table in the model, and for no other table. The browser reads the tables with DuckDB-WASM.
- Only people who can open the app in Fabric can load the page.
Ports and tokens
Everything listens on 127.0.0.1 only, and every connection needs a token.
| Who | How | Protection |
|---|---|---|
| Window | HTTP: events from the app, POST requests back | The token from the first request is kept in an HttpOnly, SameSite=Strict cookie. Requests with a different Host or Origin are refused. |
| Query server | Quack, on a local port | Each server gets a new random session token. Without it, the server runs nothing. |
| Excel | XMLA over HTTP | A token in the address. Requests with an Origin header are refused. |
| Command line | A local pipe | No network port. |
Sign-in uses MSAL with the Azure CLI's public client ID, so no app registration is needed. The token cache is encrypted for your Windows user. DuckDB gets the OneLake token as a storage secret.
In VS Code
The parts are the same, except VS Code is the window and its Microsoft account provider does the sign-in. On one machine, the app, the extension and the command line share the local catalog and the cache.