dualsense_api 1.0.1 copy "dualsense_api: ^1.0.1" to clipboard
dualsense_api: ^1.0.1 copied to clipboard

Control a Sony DualSense (PS5) controller over USB on macOS via HIDAPI + Dart FFI: read sticks, triggers, buttons, battery and audio jack in real time, and command the lightbar color.

dualsense_api #

Control a Sony DualSense (PS5) controller connected over USB from Dart/Flutter on macOS. Reads sticks, analog triggers, buttons, D-Pad, battery and the 3.5mm audio jack in real time, and commands the lightbar color.

Built on HIDAPI via Dart FFI — no native Flutter plugins, no platform channels.

Requirement: HIDAPI installed on the system #

This package does not bundle the native hidapi library — it loads it from the system at runtime. Before using it, install it with Homebrew:

brew install hidapi

This installs libhidapi.dylib at /opt/homebrew/lib/libhidapi.dylib, which is the path DualSenseBindings.macOS() expects (Homebrew on Apple Silicon). If you're on an Intel Mac, Homebrew installs to /usr/local/lib instead — in that case you'll need to adjust the path or create a symlink:

mkdir -p /opt/homebrew/lib
ln -s /usr/local/lib/libhidapi.dylib /opt/homebrew/lib/libhidapi.dylib

Without this step, connect() will throw an ArgumentError explaining that the library couldn't be found.

Platform support: this package currently only works on macOS. Windows and Linux are on the roadmap (see below).

Installation #

dependencies:
  dualsense_api: ^1.0.0

Usage #

import 'dart:io';
import 'package:dualsense_api/controllers/dualsense_controller.dart';
import 'package:dualsense_api/dualsense_bindings.dart';

Future<void> main() async {
  final bindings = switch (Platform.operatingSystem) {
    'macos' => DualSenseBindings.macOS(),
    _ => throw UnsupportedError('Platform not supported yet'),
  };

  final controller = DualSenseController(bindings);

  if (await controller.connect()) {
    print('DualSense connected');

    // Bright cyan
    controller.setLedColor(0, 200, 255);

    controller.onInputChanged.listen((state) {
      print(state);
      if (state.isPsPressed) {
        controller.setLedColor(255, 0, 0);
      }
    });
  } else {
    print('No DualSense found. Is it connected via USB?');
  }

  // When you're done with it:
  // controller.dispose();
}

See example/ for a complete, runnable example.

API #

Class Responsibility
DualSenseBindings Loads libhidapi.dylib and exposes the C functions (hid_open, hid_read, hid_write, etc.) mapped to Dart.
DualSenseController Connects to the controller, runs the polling loop, and exposes onInputChanged (Stream<DualSenseState>) + setLedColor(r, g, b).
DualSenseState Immutable snapshot (Equatable) of the full physical state: sticks, triggers, buttons, D-Pad, battery, charging state, and audio jack.

DualSenseState is only emitted when something actually changes compared to the previous state — no manual deduplication needed in the UI.

Roadmap #

  • Windows support (loading .dll instead of .dylib).
  • Adaptive triggers (physical resistance / weapon-trigger simulation).
  • Stick drift visualization by normalizing axes to -1.0..1.0.

License #

MIT — see LICENSE.

0
likes
140
points
31
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Control a Sony DualSense (PS5) controller over USB on macOS via HIDAPI + Dart FFI: read sticks, triggers, buttons, battery and audio jack in real time, and command the lightbar color.

Repository (GitHub)
View/report issues

Topics

#ffi #gamepad #hid #macos #desktop

License

MIT (license)

Dependencies

equatable, ffi

More

Packages that depend on dualsense_api