How it works

One server. Every device.

Muxit runs as a background service on your machine. Devices speak their native protocols — serial, TCP, USB (serial / USB-TMC), MQTT — and Muxit translates everything into one clean JavaScript API. Scripts, dashboards, and AI all use the same API.

1Devices
2Drivers
3Connectors
4Your code, dashboards, and AI

1 — Devices

Anything with a port or an IP address.

Power supplies, oscilloscopes, multimeters, robots, spectrometers, temperature loggers, ESP32 boards, Arduinos, Raspberry Pis, IP cameras. If it speaks a protocol, Muxit can probably reach it.

Supported transports out of the box: serial and TCP, directly from JavaScript via createSerialTransport and createTcpTransport. Higher-level protocols ride on top: SCPI over either, MQTT through the built-in MqttBridge driver, ONVIF for IP cameras, and vendor binary streams via dedicated drivers.

2 — Drivers

A small adapter for each device's protocol.

A driver is a small adapter that speaks the device's native protocol and exposes a uniform interface — get, set, execute — back to Muxit. The Muxit core never references specific devices; everything goes through this interface.

There are three driver formats, picked to match the kind of hardware you're connecting:

Generic SCPI + a connector config

For any SCPI-compliant instrument. Use the built-in SCPI driver and describe the device's commands in a short declarative block inside the connector config. The AI can draft the whole config from a programming manual. Works with oscilloscopes, power supplies, multimeters, SMUs, signal generators, and RF gear from every major vendor.

JavaScript drivers (.driver.js)

For custom protocols, ESP32 firmware, vendor-specific serial protocols, anything non-SCPI. Plain JavaScript. Twenty lines is often enough.

simple-psu.driver.js
// simple-psu.driver.js
export default {
  meta: {
    name: "SimplePSU",
    properties: {
      voltage: { type: "number", access: "rw", unit: "V" },
      current: { type: "number", access: "r",  unit: "A" },
    },
    actions: { reset: { description: "Reset to defaults" } },
  },
  async init(config) {
    this.transport = createSerialTransport(config.port, { baudRate: 9600 });
  },
  async get(prop) { return await this.transport.query(`${prop}?`); },
  async set(prop, val) { await this.transport.send(`${prop} ${val}`); },
  async execute() { await this.transport.send("*RST"); },
};

Compiled plugins (.dll)

For vendors that ship closed-source C/C++ or .NET SDKs. We wrap these as C# DLL plugins, built and signed by the Muxit team. Full hardware integration with no licensing or distribution fuss for the end user.

All three formats present the same interface to Muxit. Scripts don't know or care which kind of driver is underneath.

3 — Connectors

The driver, configured for your specific device.

A connector wraps a driver with your configuration, custom methods, and computed properties — giving each device a friendly name and a tailored API.

psu.js
// workspace/connectors/psu.js
export default {
  driver: "MockInstrument",
  config: { defaultVoltage: 0, defaultCurrent: 1.0 },
  poll: ["power"],

  methods: {
    rampTo: [async (c, target) => {
      const current = await c.voltage();
      const step = (target - current) / 10;
      for (let i = 1; i <= 10; i++) await c.voltage(current + step * i);
      return await c.voltage();
    }, "Ramp voltage to target in 10 steps"],
  },

  properties: {
    power: [async (c) => {
      const v = await c.measured_voltage();
      const i = await c.measured_current();
      return Math.round(v * i * 1000) / 1000;
    }, "Calculated power (W)"],
  },
};

The split is deliberate: drivers are commodities, connectors are personal. A driver works for any instance of a device; a connector is your specific configuration of it — your voltage limits, your safety methods, your computed power readout. You write connectors once and they live in your workspace folder, version-controlled with the rest of your code.

The internal slogan: you write connectors, the community builds drivers.

4 — Your code

Scripts, dashboards, AI — all the same API.

In a script, properties read like properties and write like assignments. No await, no callbacks, no boilerplate.

usage.js
const psu = connector("psu");
psu.voltage = 12;
log.info(`Current draw: ${psu.measured_current}A`);

The same psu object is bound to dashboard widgets, exposed to the AI as tool calls, and accessible to external clients over the WebSocket API. One model, four ways to use it.

When you plug in something new

New instrument? The AI drafts the driver.

Driver coverage is the single biggest reason hobbyist and indie lab automation tools fail to adopt. Muxit turns that on its head: when you plug in a new device, the AI can draft a working connector or driver for you in minutes.

  1. Point at a manual (optional). Drop a datasheet or programming manual into your workspace. Not required, but it helps the AI pick the right commands rather than guessing.
  2. Probe the instrument. The AI runs *IDN? over TCP, serial, or USB-TMC to confirm vendor, model, serial, and firmware — so the draft matches the actual device in front of you.
  3. Muxit drafts the connector. A JavaScript connector config with a declarative command block for properties and methods. For non-SCPI gear, a full custom JavaScript driver.
  4. You review and approve. Write safety gates are on by default. Every generated connector is plain JavaScript — no black box. You can hot-reload it into the running server to test.

Every new instrument the AI learns expands the platform for everyone who plugs in the same device next.

The app

One window, three panels.

Muxit runs as a native background service and serves its UI over a local web server. Open it in any browser — or let it run headless on a lab PC and connect from your laptop across the network.

Scripts, drivers, and device communications all run inside the Muxit service, sandboxed. Your automation keeps running even when the browser is closed.

Hardware panel (left).

Every connector with its live properties. Read values update in real time; writable fields are editable inline. Drag any property onto a script or dashboard — Muxit inserts the right code or widget for you.

Scripts and dashboards (centre).

The main workspace holds both. Switch between code and drag-and-drop control panels in the same tab. Autocomplete knows every connected device.

AI chat (right).

Ask questions about your hardware or have the AI drive it directly. Tool calls are visible and gated — you stay in control.

Dashboards

JSON files, drag-and-drop widgets.

Dashboards are JSON files. Drag widgets onto a grid, bind them to device properties, and they update automatically.

Available widgets: gauge, chart, scope, slider, knob, button, toggle, indicator, terminal, video stream.

Drag a property from the hardware panel onto a dashboard to create a widget. Drag a script onto the grid for a start/stop control. Because everything is JSON, dashboards go in version control with the rest of your code.

How AI plugs in

Three ways, all on the same connector API.

Muxit's AI integration sits on top of the same connector API everything else uses. There are three ways to bring AI into the picture, and they coexist:

Built-in AI chat and voice.

Muxit ships with a chat panel and voice input. Routed through the Muxit AI proxy on paid tiers (no API keys to manage), or to a local LLM on Pro and above (Ollama, LM Studio).

MCP server (free on every tier).

Native Model Context Protocol integration. Bring your own AI client — Claude Desktop, Claude Code, ChatGPT, any MCP-aware tool — and it connects directly to your bench. No Muxit AI credits required.

The ai() function in scripts.

Call AI from inside automation scripts. Image inputs work — pass a webcam frame and ask a question about what's visible. Returns a string you can branch on.

ai-example.js
const cam = connector("webcam");
if (ai("Is the LED still on?", cam.snapshot) === "no") {
  psu.output = false;
}

In all three paths, the AI sees the same connector API your scripts see. Tool calls are visible and gated; write operations require explicit approval by default.

Safety, sandboxing, and what stays local

How Muxit treats your code, your data, your hardware.

Scripts run sandboxed.

Muxit uses an embedded V8 engine (ClearScript) — not Node.js. Scripts can't touch the filesystem, can't open network connections, can't spawn processes. They can only call connectors you've explicitly defined.

Connectors run in the same sandbox.

Custom connector methods are plain JavaScript with allowlisted globals: connector(), log, console, emit(), delay() (capped at 30 seconds), and the transport factories (createSerialTransport, createTcpTransport). No filesystem, no shell, no surprise network calls.

Plugins are RSA-signed.

Compiled drivers (.dll plugins) are RSA-signed and verified at load time. You can see who built every component before it runs.

Local-first by default.

The Muxit server runs on your machine. Your scripts, connectors, dashboards, and device communications stay on your machine. Nothing is uploaded unless you explicitly use the AI or voice features through the Muxit proxy — and even then, only the prompts and tool calls relevant to that AI call leave your network. Bring your own MCP client or run a local LLM and the entire AI flow stays inside your network.

Plain JavaScript end to end.

Connectors and scripts are readable JavaScript files in a folder you can put under version control. Diff them, review them, commit them. Drivers in JavaScript and SCPI-config form are also readable; only compiled plugins are opaque, and those are signed.

What's where on disk

For the curious or the cautious.

  • workspace/connectors/ your connector configs (JavaScript files, one per device).
  • workspace/scripts/ your automation scripts (JavaScript files).
  • workspace/dashboards/ your dashboards (JSON files).
  • workspace/drivers/ community JavaScript drivers and SCPI definitions. Premium plugins live in a separate signed-plugin folder.
  • workspace/config/ server configuration, including license cache (HMAC-signed) and TLS settings.

The whole workspace/ directory is yours. Point it at a shared drive (Dropbox, OneDrive, NAS) and multiple Muxit installations can read the same connectors, scripts, and dashboards.

Out of scope

What Muxit isn't.

A few things Muxit is not trying to be, in case the framing matters:

Not a microcontroller IDE.

Muxit doesn't replace the Arduino IDE, PlatformIO, or ESP-IDF. It sits one layer above — once your microcontroller is running and speaking MQTT or serial, Muxit talks to it.

Not a CAD or simulation tool.

Muxit drives real hardware in real time. It doesn't simulate circuits, model physics, or design layouts.

Not a LIMS or ELN.

Muxit is for instrument control and automation, not for managing samples, users, batches, or regulatory document workflows. It can produce data for those systems, but it's not one.

Not a SaaS.

The Muxit server runs on your machine. There's a small cloud component for licensing, the AI proxy, and the extension marketplace — everything else is local.