clib_serialport_dart 1.1.0
clib_serialport_dart: ^1.1.0 copied to clipboard
A dart wrapper for clibserialport
clib_serialport_dart #
Full Dart FFI bindings for libserialport, bundled with precompiled shared libraries for macOS, Linux (x86_64/arm64), and Windows. No system install required — works directly from Git.
- Cross-platform: macOS (universal), Linux x86_64 & ARM64, Windows x86_64
- Complete API: Every public
libserialportfunction is mapped insrc/bindings.dart - Idiomatic Dart wrapper:
SerialPort,SerialPortConfig,listSerialPorts() - Zero setup: Loads binaries from
native/in the package - Integrity: SHA-256 checksums + optional
verify_binaries.dartverifier - Reproducible builds: GitHub Actions workflow builds + commits
/nativeautomatically
Table of Contents #
- Why
- Status & Compatibility
- Install
- Quick Start
- High-Level API
- Low-Level API (FFI)
- Precompiled Binaries
- Verify Checksums
- Updating Binaries (CI)
- Troubleshooting
- License
- Contributing
- Acknowledgments
Why #
Serial I/O from Dart/Flutter without relying on platform-specific plugins or system package managers. This package:
- exposes all of
libserialportvia Dart FFI, - adds a clean, high-level Dart API,
- bundles shared libraries so you don’t need to install anything on the system,
- includes CI to rebuild and refresh binaries whenever you want.
Status & Compatibility #
| Platform | Arch | Supported |
|---|---|---|
| macOS | Universal (arm64 + x86_64) | ✅ |
| Linux | x86_64 | ✅ |
| Linux | arm64 | ✅ |
| Windows | x86_64 | ✅ |
Mobile (Android/iOS): not officially supported by this repo out of the box.
libserialportcan be built for Android, but that’s out of scope here.
Dart SDK: >=3.0.0 <4.0.0
Install #
Add as a Git dependency:
# pubspec.yaml (clib_serialport_dart)
dependencies:
clib_serialport_dart:
git:
url: https://github.com/BR4YD3N-G/clib_serialport_dart.git
ref: main
That’s it. The shared libraries are shipped in native/ and loaded at runtime.
Quick Start #
import 'package:clib_serialport_dart/clib_serialport_dart.dart';
void main() {
// Enumerate
final ports = listSerialPorts();
for (final p in ports) {
print('${p.name} | ${p.description} | VID: ${p.vendorId.toRadixString(16)} '
'PID: ${p.productId.toRadixString(16)}');
}
if (ports.isEmpty) {
print('No serial ports found.');
return;
}
// Open + configure
final port = SerialPort(ports.first.name);
if (!port.open()) {
print('Failed to open ${ports.first.name}');
return;
}
final ok = port.configure(const SerialPortConfig(
baudRate: 115200,
dataBits: 8,
parity: SPParity.none,
stopBits: 1,
flowControl: SPFlowControl.none,
));
if (!ok) {
print('Failed to configure port.');
port.close();
return;
}
// Write
final bytesWritten = port.write('Hello\n'.codeUnits, timeoutMs: 1000);
print('Wrote $bytesWritten bytes');
// Read (try to read 6 bytes)
final data = port.read(6, timeoutMs: 1000);
print('Read: $data');
port.close();
}
High-Level API #
listSerialPorts() → List<SerialPortInfo> #
- Returns name, description, transport, USB VID/PID (if USB).
class SerialPort #
SerialPort(String name)bool open({SPMode mode = SPMode.readWrite})bool configure(SerialPortConfig cfg)int write(List<int> data, {int timeoutMs = 1000})List<int> read(int size, {int timeoutMs = 1000})int inputWaiting(),int outputWaiting()void flush(SPBuffer buffer),void drain()void setDTR(bool state),void setRTS(bool state)int getSignals()(bitmask as per libserialport)void close()
class SerialPortConfig #
const SerialPortConfig({
this.baudRate = 9600,
this.dataBits = 8,
this.parity = SPParity.none,
this.stopBits = 1,
this.flowControl = SPFlowControl.none,
});
Enums #
SPMode(read,write,readWrite)SPParity(none,odd,even,mark,space)SPFlowControl(none,xonxoff,rtscts,dsrdtr)SPBuffer(input,output,both)
Low-Level API (FFI) #
All public libserialport functions are mapped in lib/src/bindings.dart. You can call them directly if you need advanced/edge functionality not surfaced in the high-level API (e.g., event waits, raw signal masks, etc.).
Examples of mapped symbols:
- Enumeration & lookup:
sp_list_ports,sp_get_port_name,sp_get_port_description, … - Open/close:
sp_get_port_by_name,sp_open,sp_close,sp_free_port,sp_free_port_list - Configuration:
sp_set_baudrate,sp_get_baudrate,sp_set_bits,sp_set_parity,sp_set_stopbits,sp_set_flowcontrol, … - I/O:
sp_blocking_read,sp_blocking_write,sp_flush,sp_drain,sp_input_waiting,sp_output_waiting - Signals & events:
sp_get_signals,sp_set_dtr,sp_set_rts,sp_wait(where supported)
Precompiled Binaries #
Bundled under native/:
native/
├─ version.txt # tag/commit/date/flags
├─ checksums.txt # SHA-256 for each lib
├─ macos/libserialport.dylib
├─ linux/libserialport.so # x86_64
├─ linux/libserialport_arm64.so # ARM64
└─ windows/libserialport-0.dll # x86_64
The loader in bindings.dart automatically picks the correct file:
- macOS: universal
.dylib - Linux: chooses
libserialport.soorlibserialport_arm64.sobased on architecture - Windows:
libserialport-0.dll
Note about Flutter usage #
This repository is a pure Dart package that ships precompiled shared libraries
under native/. Flutter apps (desktop) will not automatically include those
shared libraries unless they are copied into the Flutter project's platform
folders or packaged by a Flutter plugin. To include the native libraries in a
Flutter app, either:
- Use the
tool/bundle_native.darthelper to copy the correct binaries into the Flutter project's platform folders, or - Build/publish a separate Flutter plugin that depends on this package and places the native artifacts into the plugin platform folders.
See example/README.md for a usage example with the bundler script.
Verify Checksums #
This repo includes verify_binaries.dart so anyone can verify the SHA-256 hashes without external tools:
dart run verify_binaries.dart
Expected output:
OK: native/macos/libserialport.dylib
OK: native/linux/libserialport.so
OK: native/linux/libserialport_arm64.so
OK: native/windows/libserialport-0.dll
All binaries verified successfully.
Alternatively on Linux:
cd native
sha256sum -c checksums.txt
Updating Binaries (CI) #
The repo ships a GitHub Actions workflow at:
.github/workflows/build-libserialport.yml
What it does:
- Builds
libserialportfor:- macOS (universal arm64+x86_64)
- Linux (x86_64 & ARM64)
- Windows (x86_64)
- Strips & optimizes binaries
- Uploads per-platform artifacts
- Publish job assembles
/native, generatesversion.txt+checksums.txt - Commits
/nativeback tomainand uploads anative_binariesartifact
Run from the Actions tab → “Build libserialport binaries”.
Troubleshooting #
macOS #
- Blocked by Gatekeeper: You may need to approve the
.dylib(System Settings → Privacy & Security) or run your app once from Terminal. - Permissions: Accessing USB serial devices sometimes requires TCC permissions for terminal apps.
Linux #
- Permissions: Add your user to the
dialout(or distro equivalent) group and re-login:sudo usermod -a -G dialout $USER - udev rules: Depending on devices, you may need udev rules for non-root access.
- Missing libudev headers in custom builds: Ensure
libudev-devis installed when rebuilding.
Windows #
- Driver: For USB-to-serial bridges (CP210x/FTDI/CH34x), install vendor drivers if needed.
- Antivirus false positives: Since we ship a DLL, whitelisting may be needed in some environments.
Common code errors #
- Timeouts:
read()returns empty list on timeout; increasetimeoutMsor checkinputWaiting(). - Port busy: Another process may be holding the port. Close any terminals/IDE monitors.
License #
- This package (Dart code): MIT — see
LICENSE - Bundled
libserialportshared libraries: LGPL-3.0-or-later- License texts in
third_party/libserialport/:COPYING.LESSER(LGPL v3)COPYING(GPL v3)NOTICEwith source URL and build details
- The shared libraries are dynamically linked at runtime to satisfy LGPL relinking requirements.
- The exact upstream version/commit is recorded in
native/version.txt.
- License texts in
Contributing #
PRs welcome! If you add or tweak FFI bindings:
- Update
lib/src/bindings.dartand keep typedefs accurate. - Add/adjust high-level wrappers only if they remain cross-platform and safe.
- Run
dart analyzeanddart test. - If you need new binaries, run the GitHub Actions workflow to rebuild
/native. - Update
native/version.txt+checksums.txtvia the publish job.
Publishing checklist:
LICENSEpresent (MIT)third_party/libserialport/license texts includedpubspec.yamlincludesrepositoryand/orhomepagedart pub publish --dry-runpasses
Acknowledgments #
libserialport— part of the Sigrok project.- Dart FFI team — for making native interop straightforward.