Heads-up  ·  FMWarriors exclusive

FM-broadcaster: a tiny shared state bus for FileMaker Web Viewers

Just wanted to show you something I've been playing with. It's a single HTML file that turns every Web Viewer in your FileMaker client into a node on a live, shared key/value store — so any layout, window, or even a different .fmp12 can read, write, and react to the same data in real time. No server, no schema, no polling.

Single File Real-Time Zero Dependencies MIT

An experimental tool I'd like your feedback on  ·  FileMaker Pro 19+

What it actually is

FM-broadcaster is one HTML file (index.html) that you host anywhere — local web server, intranet, S3, whatever serves HTTP. You point your Web Viewers at that URL. From that moment on, every Web Viewer instance running in the same FileMaker client process automatically discovers its siblings and joins a shared in-memory key/value store. State propagates between Web Viewers in milliseconds, and FileMaker scripts can read, write, query, or be notified of changes through a small JSON message protocol.

Under the hood it uses two native browser primitives — BroadcastChannel for instant peer-to-peer messaging, and localStorage for durability across panel closes. Both are origin-scoped to the FileMaker client process, which is exactly the boundary we want: state is shared inside your machine's FileMaker session and nowhere else.

How the pieces fit together

FILEMAKER PRO CLIENT (one machine, one process) FILE A.fmp12 Layout 1 Web Viewer instance c485a2 Layout 2 Web Viewer instance 1373ae FILE B.fmp12 Dashboard Web Viewer instance 1b7341 Popover Web Viewer instance 9ae012 BroadcastChannel "fm-broadcaster" — real-time pub/sub between instances localStorage (persistence) survives panel closes & FM restarts FileMaker Scripts fmCommand() in · onChange / onResult out

Each Web Viewer that loads index.html gets a unique instance ID and joins the channel. Mutations from any instance (or from FileMaker via Perform JavaScript in Web Viewer) flow through a single applyMutation function that updates the store, persists it, broadcasts it, and notifies FileMaker via FileMaker.PerformScript. A two-message handshake (request_syncsync_full) lets late-joining panels pick up the current state from existing peers.

What it looks like in practice

Two FM-broadcaster Web Viewer windows running side by side, showing the same key/value store synchronized in real time, with the JSON onChange payload visible at the bottom of each window.
Two Web Viewers in the same FileMaker client. Adding from_date in the left window appears instantly in the right one, and FileMaker receives the onChange payload (bottom panel) on both sides — same token, same data.

What you can do with it (from FileMaker)

The short version: Web Viewers natively cannot talk to each other, and FileMaker layouts natively cannot push events to each other. This single HTML file makes both trivial. Anywhere your solution has more than one window open, more than one Web Viewer, or more than one .fmp12 in the same client, FM-broadcaster unlocks UX patterns — live selection sync, observable globals, async-with-token, cross-Web-Viewer talk, instant notifications — that are otherwise either impossible or require heavyweight server-backed contortions.

16 things you could actually do with it

From quick wins to small architectural shifts. Some are obvious, some are not — would love your take on which feel useful in your solutions.

01

Cross-window & cross-file UI state sync

Open three windows of the same solution, or two different .fmp12 files — selecting a customer in one highlights the same record everywhere. Currently impossible without server round-trips or external scripting.

02

Real-time messaging without OnTimer polling

Replace Install OnTimer Script patterns — which burn CPU and feel laggy — with event-driven push. A layout subscribes to a key; when any other layout writes it, FileMaker receives onChange immediately.

03

Shared session context across files

Currently logged-in user, tenant, environment flag, demo mode, current project — write once in a launcher file, every Web Viewer in every opened file sees it. Survives layout switches via localStorage.

04

Wizard & multi-step flow state

A long wizard split across multiple layouts or cards keeps its state in the broadcaster instead of a globals table or a passed parameter chain. Back/forward navigation, popovers, and modal dialogs all read and write the same store transparently.

05

Cross-window selection & focus tracking

Master/detail across windows: a list window in one place, a detail window in another — selecting in the master pushes the selected ID to every detail window via a single key. No External Data Source calls, no record locking.

06

Lightweight cache for expensive computations

Cache server-side script results — permission matrices, complex JSON aggregates — keyed by user or role. Subsequent layouts read from the broadcaster instead of re-running the script. The default persist=true makes the cache survive layout closes.

07

Inter-Web-Viewer messaging on the same layout

If you have two Web Viewers on a single layout — say, a chart and a control panel — they can talk to each other directly without round-tripping through FileMaker scripts. This is currently nearly impossible: Web Viewers cannot natively communicate.

08

UI notifications & toast bus

Any script anywhere in the solution writes to a notifications key; a single notification Web Viewer in a status-bar layout displays them. One line of FileMaker code replaces an entire custom notification subsystem.

09

Async correlation via tokens

The token pattern (UUID flows through addonChange) lets FileMaker scripts behave as if calling a synchronous API with a callback. Native FileMaker has no clean idiom for this — usually faked with global variables and Pause/Resume.

10

A poor-man's shared dictionary

The query API — get, keys, exists, count, clear — gives FileMaker an in-memory dictionary that requires no table, no schema pollution, and no JSONSetElement/JSONGetElement gymnastics for every lookup.

11

Cross-file plugin-style architecture

A "core services" file exposes business logic via broadcaster keys — currentUserRole, featureFlags.betaUi. Add-on .fmp12 files just read those keys. Decouples solutions in ways External Data Sources cannot.

12

Multi-monitor & floating window dashboards

One window holds a KPI dashboard, others hold edit forms. Saves in any form push the new value to the dashboard window in real time — with no Refresh Window calls or timer-driven re-queries.

13

Live presence indicator

The peers registry already tracks live instances and their colors. Trivial to expose to FileMaker as "X windows currently open" or "user is editing in another window" indicators.

14

Channel-isolated test & demo modes

Append ?channel=demo to let a training file run alongside production data in the same FileMaker client, with no state bleed. Native FileMaker has no such isolation primitive for in-memory state.

15

Form-level autosave drafts & undo buffer

Rapid keystroke-level autosave to localStorage via persist=true, totally outside FileMaker's record commit cycle. Recover work after a crash without polluting the schema with draft tables.

16

Replacing global-variable contention

Global variables ($$x) appear shared but are per-window in subtle ways and don't notify on change. The broadcaster gives you observable globals with a built-in change event — something FileMaker has never offered.