#usb #macos #libusb #lsusb #system-profiler

bin+lib cyme

List system USB buses and devices; a modern cross-platform lsusb

19 releases (10 stable)

1.3.1 Feb 27, 2023
1.2.6 Jan 27, 2023
1.1.2 Dec 7, 2022
0.9.2 Dec 3, 2022
0.7.3 Nov 29, 2022

#175 in Command line utilities

Download history 70/week @ 2022-11-25 138/week @ 2022-12-02 4/week @ 2022-12-09 17/week @ 2022-12-16 14/week @ 2022-12-23 16/week @ 2022-12-30 50/week @ 2023-01-06 15/week @ 2023-01-13 6/week @ 2023-01-20 64/week @ 2023-01-27 46/week @ 2023-02-03 40/week @ 2023-02-10 122/week @ 2023-02-17 43/week @ 2023-02-24 6/week @ 2023-03-03 2/week @ 2023-03-10

173 downloads per month



      o   /---o
      o   \---o


Crates.io docs.rs

List system USB buses and devices; a lib and modern cross-platform lsusb that attempts to maintain compatibility with, but also add new features. Includes a macOS system_profiler SPUSBDataType parser module and libusb profiler for non-macOS systems/gathering more verbose information.

The project started as a quick replacement for the barely working lsusb script and is my yearly Rust project to keep up to date! Like most fun projects, it quickly experienced feature creep as I developed it into a cross-platform replacement for lsusb. As a developer of embedded devices, I use a USB list tool on a frequent basis and developed this to cater to what I believe are the short comings of lsusb; verbose dump is too verbose, tree doesn't contain useful data on the whole, it barely works on non-Linux platforms and modern terminals support features that make glancing through the data easier.

It's not perfect as it started out as a Rust refresher but I had a lot of fun developing it and hope others will find it useful and can contribute. Reading around the lsusb source code, USB-IF and general USB information was also a good knowledge builder.

The name comes from the technical term for the type of blossom on a Apple tree: cyme - it is Apple related and also looks like a USB device tree 😃🌸.

cli tree output


  • Compatible with lsusb using --lsusb argument. Supports all arguments including --verbose output using libusb. Output is identical for use with no args (list), almost matching for tree (driver port number not included) and near match for verbose.
  • Filters like lsusb but that also work when printing --tree. Adds --filter_name, --filter_serial, --filter_class and option to hide empty --hide-buses/--hide-hubs.
  • Improved --tree mode; shows device, configurations, interfaces and endpoints as tree depending on level of --verbose.
  • Controllable block data like lsd --blocks for device, bus, configurations, interfaces and endpoints. Use --more to see more by default.
  • Modern terminal features with coloured output, utf-8 characters and icon look-up based device data. Can be turned off and customised.
  • Can be used as a library too with system_profiler parsing module, lsusb module using libusb and display module for printing amongst others.
  • --json output that honours filters and --tree.
  • --headers to show meta data only when asked and not take space otherwise.
  • --mask_serials to either '*' or randomise serial string for sharing dumps with sensitive serial numbers.
  • Auto-scaling to terminal width. Variable length strings such as descriptors will be truncated with a '...' to indicate this. Can be disabled with config option 'no-auto-width' and a fixed max defined with 'max-variable-string-len'.
  • Targets for Linux, macOS, perhaps Windows...



Future Development/Enhancements

  • Packages for Linux distros.
  • lib Error type rather than std::io::Error.
  • Fully decode device class based base class and tables at USB-IF.
  • Support 'auto', 'always', 'never' or icon, colours, utf-8 etc.
  • More examples for lib usage.



  • Linux/Windows and pre-compiled targets require libusb 1.0.0: brew install libusb, sudo apt install libusb-1.0-0-dev or one's package manager of choice.
  • Linux pre-compiled and --features udev requires 'libudev-dev': sudo apt install libudev-dev or one's package manager of choice.

For pre-compiled binaries, see the releases.

From crates.io with a Rust tool-chain installed: cargo install cyme. To do it from within a local clone: cargo install --path ..

If wishing to use only macOS system_profiler and not obtain more verbose information, remove the 'libusb' feature with cargo install --no-default-features cyme

I also have a Homebrew tap, which will also install a man page, completions and the 'libusb' dependency:

brew tap tuna-f1sh/taps
brew install cyme

More package managers to come, please feel free to create a PR if you want to help out here.

Linux udev

To obtain device and interface drivers being used on Linux like lsusb, one must install 'libudev-dev' via a package manager and the --features udev feature when building. Only supported on Linux targets.

Alias lsusb

If one wishes to create a macOS version of lsusb or just use this instead, create an alias one's environment with the --lsusb compatibility flag:

alias lsusb='cyme --lsusb'


Will cover this more as it develops. Use cyme --help for basic usage or man ./doc/cyme.1. There are also autocompletions in './doc'.


For usage as a library for profiling system USB devices, the crate is 100% documented so look at docs.rs. The main useful modules for import are system_profiler, lsusb::profiler and usb


cyme will check for a 'cyme.json' config file in:

  • Linux: "$XDG_CONFIG_HOME or $HOME/.config"
  • macOS: "$HOME/Library/Application Support"
  • Windows: "{FOLDERID_RoamingAppData}"

One can also be supplied with --config. Copy or refer to './doc/cyme_example_config.json' for configurables. Tthe file is essentially the default args; supplied args will override these. Use --debug to see where it is looking or if it's not loading.

Custom Icons and Colours

See './doc/cyme_example_config.json' for an example of how icons can be defined and also the docs. The config can exclude the "user"/"colours" keys if one wishes not to define any new icons/colours.

Icons are looked up in an order of User -> Default. For devices: VidPid -> VidPidMsb -> Vid -> UnknownVendor -> get_default_vidpid_icon, classes: ClassifierSubProtocol -> Classifier -> UndefinedClassifier -> get_default_classifier_icon. User supplied colours override all internal; if a key is missing, it will be None.

Known Issues

  • sudo is required to open and read Linux root_hub string descriptors. The program works fine without these however, as will use 'usb-ids' like lsusb. What will be missing are 'name', 'manufacturer' and 'serial' descriptors for example. Use debugging -z to see what devices are missing this data. The env CYME_PRINT_NON_CRITICAL_PROFILER_STDERR can be used or 'print-non-critical-profiler-stderr' config key to print these to stderr. --lsusb --verbose will print a message to stderr always to match the 'lsusb' behaviour.
  • Version major BCD Device difference between libusb and macOS system_profiler: If the major version is large, libusb seems to read a different value to macOS. I don't think it's a parsing error but open to ideas.
  • libusb cannot read special non-user Apple buses; T2 chip for example. These will still be listed by system_profiler. The result is that when merging for verbose data, these will not print verbose information. Use --force-libusb to ignore them.
  • Tested with macOS 13 ->. I'm not sure when the -json flag was added to system_profiler; whether it exists on all macOS versions.


~169K SLoC