npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

meshxt

v0.1.5

Published

MeshXT — Compression & error correction for Meshtastic. Extend your range by 2x.

Readme

MeshXT — Meshtastic Extended

Compression & error correction for Meshtastic — extend your range by 2x

MeshXT preprocesses your Meshtastic messages with intelligent compression and forward error correction, allowing you to send the same data using higher spreading factors for dramatically more range.

🔧 Want to flash your device directly? This is the JavaScript developer library. For a ready-to-flash firmware, see Meshtastic-MeshXT-Firmware — plug in USB, run 4 commands, done.

Installation

npm (for developers)

# Install globally for CLI use
npm install -g meshxt

# Or run directly with npx (no install needed)
npx meshxt encode "Hello world"

# Or add to your project as a dependency
npm install meshxt

From source

git clone https://github.com/DarrenEdwards111/MeshXT.git
cd MeshXT
npm test          # Run 70 tests
npm link          # Make CLI available globally (optional)

How It Works

Your Message ──→ Compress ──→ FEC Encode ──→ Packet Frame ──→ LoRa Radio
                 (40-50%)     (Reed-Solomon)  (2-byte header)
                 smaller       error-proof     fits 237 bytes

The key insight: smaller packets = higher spreading factors = more range.

If compression cuts your message in half, you can bump up the spreading factor by one step — roughly doubling your range with the same airtime.

Features

  • 🗜️ Smaz Compression — Short-string compression optimised for English text (15-50% savings)
  • 📖 Codebook Templates — 74 predefined messages encoded in 1-9 bytes ("I'm OK" = 1 byte)
  • 🛡️ Reed-Solomon FEC — Corrects up to 32 corrupted bytes per packet
  • 📡 Adaptive SF Selection — Auto-picks optimal spreading factor, bandwidth, and coding rate
  • 📦 Packet Framing — Complete packet format that fits Meshtastic's 237-byte limit
  • 🔧 CLI Tool — Encode, decode, benchmark, and estimate range from the command line
  • 🚫 Zero Dependencies — Pure Node.js, nothing to install

CLI Usage

# Encode a message (shows compression stats + range estimate)
meshxt encode "Are you free for dinner Thursday?"

# Encode with specific options
meshxt encode "Need help" --fec high --compress smaz

# Decode a hex packet
meshxt decode <hex_string>

# Benchmark compression on a message
meshxt bench "Need help at the old bridge, heading south"

# Estimate range for given LoRa parameters
meshxt range --sf 12 --bw 125 --power 14 --antenna 6

# List all codebook templates
meshxt codebook

# Show help
meshxt help

Example Output

$ meshxt encode "Are you free for dinner Thursday?"

📡 MeshXT Encode
─────────────────────────────────
Original:      33 bytes
Compressed:    24 bytes (27.3% saved)
+ FEC (medium): +32 bytes
+ Header:      +2 bytes
Total packet:  58 bytes / 237 max
─────────────────────────────────
Recommended:   SF12 BW500kHz CR8
Est. range:    ~4.3km (2mi)
─────────────────────────────────
Hex: 1120...
$ meshxt range --sf 12 --bw 125 --power 14 --antenna 6

📡 MeshXT Range Estimate
─────────────────────────────────
SF:            12
Bandwidth:     125 kHz
TX Power:      14 dBm
Antenna gain:  6 dBi
─────────────────────────────────
Est. range:    ~7.3km (4mi)
Link budget:   158.5dB
Sensitivity:   -135.5dBm

API Usage (as a library)

const meshxt = require('meshxt');

// ── Compression ────────────────────────────
const compressed = meshxt.compress('Are you free for dinner Thursday?');
console.log(`Compressed: ${compressed.length} bytes`);

const original = meshxt.decompress(compressed);
console.log(`Decompressed: ${original}`);

// ── Codebook (ultra-compact messages) ──────
// Simple templates (1 byte)
const sos = meshxt.codebook.encode('sos');           // 1 byte
const ok = meshxt.codebook.encode('ok');             // 1 byte
const omw = meshxt.codebook.encode('on_my_way');     // 1 byte

// Parameterised templates
const loc = meshxt.codebook.encode('location', { lat: 51.5074, lon: -3.1791 }); // 9 bytes
const eta = meshxt.codebook.encode('eta', { minutes: 15 });                      // 2 bytes
const weather = meshxt.codebook.encode('weather', { type: 'rain' });             // 2 bytes
const battery = meshxt.codebook.encode('battery', { percent: 42 });              // 2 bytes

// Decode
const decoded = meshxt.codebook.decode(loc);
console.log(decoded.text);   // "At location [51.507400, -3.179100]"
console.log(decoded.params); // { lat: 51.5074, lon: -3.1791 }

// List all 74 templates
const templates = meshxt.codebook.listTemplates();

// ── Forward Error Correction ───────────────
const data = meshxt.compress('Important message');
const protected_ = meshxt.fec.encode(data, 'medium');   // Add 32 parity bytes
const recovered = meshxt.fec.decode(protected_, 'medium'); // Corrects up to 16 errors

// FEC levels: 'low' (8 errors), 'medium' (16 errors), 'high' (32 errors)
console.log(`Parity bytes: ${meshxt.fec.parityBytes('medium')}`);         // 32
console.log(`Max corrections: ${meshxt.fec.maxCorrectableErrors('medium')}`); // 16

// ── Full Packet (compression + FEC + framing) ─
const { createPacket, parsePacket } = require('meshxt/src/packet');

const result = createPacket('Hello from MeshXT!', {
  compression: 'smaz',     // 'smaz', 'codebook', or 'none'
  fec: 'low',              // 'low', 'medium', 'high', or 'none'
});

console.log(`Packet size: ${result.packet.length} bytes`);
console.log(`Compression ratio: ${(result.stats.compressionRatio * 100).toFixed(1)}%`);

const parsed = parsePacket(result.packet);
console.log(`Message: ${parsed.message}`); // "Hello from MeshXT!"

// ── Adaptive LoRa Parameter Selection ──────
const rec = meshxt.adaptive.recommend(result.packet.length);
console.log(`Recommended: SF${rec.sf} BW${rec.bw}kHz`);
console.log(`Est. range: ${rec.rangeKm}km`);
console.log(`Airtime: ${rec.airtimeMs}ms`);

// Direct range estimation
const range = meshxt.adaptive.rangeEstimate(12, 125, 14, 6);
console.log(`Range: ${range.rangeKm}km`);
console.log(`Link budget: ${range.linkBudget}dB`);
console.log(`Sensitivity: ${range.sensitivity}dBm`);

Using with Meshtastic (Serial/BLE)

If you're building a Node.js app that talks to a Meshtastic device over serial or BLE, here's how to integrate MeshXT:

const meshxt = require('meshxt');
const { SerialPort } = require('serialport'); // npm install serialport

// Connect to your Meshtastic device
const port = new SerialPort({ path: '/dev/ttyUSB0', baudRate: 115200 });

// Sending: compress before sending via Meshtastic serial API
function sendMessage(text) {
  const packet = meshxt.createPacket(text, {
    compression: 'smaz',
    fec: 'low'
  });
  // Send packet.packet bytes via Meshtastic protobuf serial API
  // The receiving end needs MeshXT to decode
  console.log(`Sent "${text}" as ${packet.packet.length} bytes (was ${text.length})`);
}

// Receiving: decode incoming MeshXT packets
function onReceive(data) {
  const parsed = meshxt.parsePacket(data);
  if (parsed.valid) {
    console.log(`Received: ${parsed.message}`);
  }
}

Note: Both sender and receiver need MeshXT. For device-to-device without a computer, use the combined firmware instead.

Range Improvement

| Configuration | Typical Range | Notes | |--------------|--------------|-------| | Stock Meshtastic SF12 | ~50 km | No compression | | + MeshXT Smaz compression | ~80 km | 50% smaller → higher SF viable | | + Reed-Solomon FEC | ~90 km | Decodes at lower SNR | | + Directional antenna | ~200 km | 10dBi Yagi | | Combined | ~200 km / 125 mi | All optimisations |

Compression Benchmarks

| Message | Original | Compressed | Savings | |---------|----------|------------|---------| | "Roger that, heading to your location now" | 40 bytes | 19 bytes | 52% | | "Can you call me when you get this?" | 34 bytes | 21 bytes | 38% | | "Going to the store, do you need anything?" | 41 bytes | 26 bytes | 37% | | "The weather is looking good today" | 33 bytes | 23 bytes | 30% | | "On my way home now, be there in 20 minutes" | 42 bytes | 30 bytes | 29% |

Codebook — Ultra-Compact Messages

| Message | Bytes | |---------|-------| | "I'm OK" | 1 | | "SOS" | 1 | | "On my way" | 1 | | "Need help" | 1 | | "ETA 15 minutes" | 2 | | "Weather: rain" | 2 | | "Battery 42%" | 2 | | "At location [lat, lon]" | 9 |

74 templates covering emergencies, status, navigation, weather, and more.

Packet Format

┌─────────────────────────┬─────────────────────────┬───────────────────┐
│       Header (2B)       │    Payload (variable)   │   FEC Parity      │
├────────┬────────────────┼─────────────────────────┼───────────────────┤
│ Byte 0 │ Byte 1         │ Compressed message data │ Reed-Solomon ECC  │
│        │                │                         │                   │
│ VVVV   │ FFFF           │                         │ 16/32/64 bytes    │
│ CCCC   │ xxxx           │                         │                   │
└────────┴────────────────┴─────────────────────────┴───────────────────┘

V = Version (4 bits)     F = FEC level (4 bits)
C = Compression (4 bits) x = Flags (4 bits)

Total: ≤ 237 bytes (Meshtastic max payload)

FEC Error Correction

| Level | Parity Bytes | Corrects Up To | Overhead | |-------|-------------|----------------|----------| | Low | 16 | 8 byte errors | ~10% | | Medium | 32 | 16 byte errors | ~20% | | High | 64 | 32 byte errors | ~40% |

Compile & Runtime Test Results

═══════════════════════════════════════════
C++ Firmware Compile & Runtime Test Results
═══════════════════════════════════════════

Compression Test:
  ✅ Compress:    33 bytes → 24 bytes (27% saved)
  ✅ Decompress:  "Are you free for dinner Thursday?"
  ✅ Roundtrip:   Perfect match

FEC Test:
  ✅ Encode:      24 bytes → 40 bytes (+16 parity)
  ✅ Decode:      24 bytes (clean, no errors)
  ✅ Roundtrip:   Perfect match

Full Packet Test:
  ✅ Create:      33 bytes → 42 bytes (fits in 237 max)
  ✅ Parse:       "Are you free for dinner Thursday?"
  ✅ Roundtrip:   Perfect match
  ✅ Valid:        YES

═══════════════════════════════════════════
All tests passed — zero warnings, zero errors.
Node.js: 70/70 tests passing.
═══════════════════════════════════════════

UK 868 MHz ISM Band

MeshXT is optimised for the UK/EU 868 MHz ISM band:

  • Max ERP: 25 mW (14 dBm)
  • Duty cycle: 1% (g1 sub-band)
  • Adaptive SF selection respects duty cycle limits

Flashing MeshXT to Your Meshtastic Device

⚡ Use the combined firmware repo: Meshtastic-MeshXT-Firmware

MeshXT is a Meshtastic module — it needs the full Meshtastic firmware to run. You can't flash MeshXT on its own. The combined firmware repo gives you Meshtastic + MeshXT in one flash.

Heltec V3 (4 commands):

pip install platformio
git clone https://github.com/DarrenEdwards111/Meshtastic-MeshXT-Firmware.git
cd Meshtastic-MeshXT-Firmware
bash scripts/setup.sh
bash scripts/flash.sh heltec-v3

Other devices:

T-Beam, RAK4631, T-Deck, T-Echo — see the full device list and instructions.

C/C++ source files

This repo contains the MeshXT module source code in firmware/src/ (8 files, ~967 lines). These are the files that get integrated into the Meshtastic firmware build. For manual integration details, see the firmware repo.

Project Structure

meshxt/
├── package.json           # Zero dependencies
├── README.md
├── LICENSE                 # Apache 2.0
├── src/
│   ├── index.js           # Main entry point
│   ├── compress.js        # Smaz-style text compression
│   ├── codebook.js        # 74 predefined message templates
│   ├── fec.js             # Reed-Solomon GF(2^8) FEC
│   ├── adaptive.js        # LoRa parameter optimisation
│   ├── packet.js          # Packet framing (header + payload + FEC)
│   └── utils.js           # Helpers
├── bin/
│   └── longshot.js        # CLI tool
└── test/
    └── test.js            # 70 tests, all passing

Requirements

  • Node.js >= 16.0.0
  • No external dependencies

License

Apache 2.0 — Copyright 2026 Darren Edwards

Contributing

PRs welcome! Key areas for contribution:

  • C/C++ port for direct Meshtastic firmware integration
  • Improved compression codebook for non-English languages
  • Adaptive FEC that adjusts based on link quality
  • Real-world range testing and validation
  • Python port for MicroPython on ESP32

Get in Touch

Links

  • npm: https://www.npmjs.com/package/meshxt
  • GitHub: https://github.com/DarrenEdwards111/MeshXT
  • Firmware: https://github.com/DarrenEdwards111/Meshtastic-MeshXT-Firmware
  • Issues: https://github.com/DarrenEdwards111/MeshXT/issues
  • Discussions: https://github.com/DarrenEdwards111/MeshXT/discussions