Build MeshCore bots:
a Client with events and caches, and one standard for every piece of a bot — commands, events, jobs,
permissions and roles — declared with builders.
Not the official client library.
meshcore-dev/meshcore.js(@liamcottle/meshcore.js) is the low-level Companion protocol client used by MeshCore apps. This project is a bot framework with its own protocol layer.
pnpm add @meshcorejs/client serialport # radio plugged over USB
pnpm add @meshcorejs/client # radio on WiFi (TCP)
pnpm add @meshcorejs/client @abandonware/noble # radio over BluetoothWorks with npm and yarn too. Node.js 20 or newer.
| Package | Purpose |
|---|---|
@meshcorejs/client |
The framework: client, managers, builders, plugins, permissions |
@meshcorejs/protocol |
Companion Radio protocol codec, no I/O |
@meshcorejs/transports |
TCP, serial and BLE transports, plus a fake radio (/mock) |
@meshcorejs/testing |
Test bots without a radio: createTestClient() with simulated time |
@meshcorejs/plugin-ai |
Official plugin: /ask <question> answered by an AI model |
Example: examples/weather-bot (weather plugin, owner role, RadioConfig, morning
bulletin, tests).
Guides and the API reference on https://meshcore.js.org.
Declare the radio's identity and LoRa settings once; login() applies what differs and refuses to start if the
radio cannot honour it:
const client = new Client({
transport: new SerialTransport({ path: '/dev/ttyACM0' }),
radio: new RadioConfig({ name: 'TrainBot', txPower: 22, params: { frequency: 869.525, bandwidth: 250, spreadingFactor: 11, codingRate: 5 } }),
});Group bricks that live together, ship them as a package, configure them at the client:
import ai from '@meshcorejs/plugin-ai';
client.register(ai.configure({ apiKey: process.env.OPENAI_API_KEY ?? '' }));
await client.login();
await client.plugins.get('ai')?.reload();Official plugins are published under @meshcorejs/plugin-*; your own can live anywhere, even in the bot's
own plugins/ folder.
Everything the bot says on its own is English by default and overridable:
import { frenchReplies } from '@meshcorejs/client';
new Client({ transport, replies: frenchReplies }); // or { unknownCommandDM: '…' }Holders of Permissions.ManagePlugins / ManageJobs (or Administrator) get /plugins [load|unload|reload <name>]
and /jobs [run|pause|resume <name>] in DM. Bots without roles expose nothing extra.
- A MeshCore node running the Companion Radio firmware (protocol version 3 or newer).
- Node.js 20+ to run bots; Node.js 22.12+ and pnpm 11 to work on this repository.
- Serial:
pnpm add serialport. BLE:pnpm add @abandonware/noble. TCP needs nothing.
pnpm install
pnpm test
pnpm typecheck
pnpm build
pnpm check # Biome: format + lint + import order
pnpm check:publish # publint
pnpm knip # unused code and dependencies
pnpm check:typesContributions go through pull requests, see CONTRIBUTING.md. Releases use Changesets and are published to npm by CI.