Open-source project
dotnet-bluetooth-le/dotnet-bluetooth-le avatar
dotnet-bluetooth-le/dotnet-bluetooth-le

Plugin.BLE: one Bluetooth LE surface for Xamarin, MAUI and MvvmCross apps

Bluetooth LE plugin for .NET (Xamarin/MAUI), supporting Android, iOS, macOS, Windows

957 stars332 forksC#Apache-2.0

At a glance

What is it?
dotnet-bluetooth-le packages a Bluetooth LE plugin for .NET mobile and desktop apps, publishing a plain Plugin.BLE library and a separate MvvmCross binding for Android, iOS, macOS and Windows. The tree is actively worked on, but the API reference lives in doc/usage.md rather than in the README.
Who is it for?
Plugin.BLE fits .NET developers who already ship on Xamarin or MAUI and want scanning, connecting, service and characteristic discovery, and read, write and notify operations behind one API instead of four platform stacks. It does not fit engineers on plain .NET or on a platform outside the four listed, and it does not fit teams unwilling to read doc/usage.md for permissions and API limits.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 3 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One Bluetooth LE API across Android, iOS, macOS and Windows

Writing BLE code by hand in .NET means writing it again for each platform: Android's own stack, CoreBluetooth on Apple devices, and a Windows path on top of that. dotnet-bluetooth-le exists to collapse that repetition into a single plugin whose shape is the same on Android, iOS, macOS and Windows, with MAUI added alongside the older Xamarin targets.

Who it is for is fairly specific: teams building mobile or desktop applications in Xamarin or MAUI who need to talk to Bluetooth Low Energy peripherals and want to avoid maintaining one implementation per operating system. The plugin is loosely based on the BLE implementation of Monkey Robotics, and the project links the Bluetooth Core Specification, the Android BLE guideline and the iOS CoreBluetooth best practices as background reading for the platforms it wraps.

The scope is BLE only. Classic Bluetooth is not part of what this plugin claims to cover, and the four listed platforms are the whole supported surface. Anyone expecting a general purpose Bluetooth stack for .NET desktop services will find the package aimed squarely at the app side of the stack.

The vanilla package and the MvvmCross package ship separately

The repository publishes two NuGet packages and they are not interchangeable. Plugin.BLE is the plain library for Xamarin or MAUI, and MvvmCross.Plugin.BLE is the MvvmCross binding. The README makes the vocabulary explicit, noting that with the term vanilla it means the non-MvvmCross version, and that the vanilla package can be used without MvvmCross if you download it.

That split is the main decision a new user has to make, and it is easy to get wrong because the naming is close. If your application already uses MvvmCross for view models and bindings, you want MvvmCross.Plugin.BLE. If it does not, pulling in the MvvmCross package buys you nothing and adds a dependency the project does not otherwise need.

Both packages are published with a stable channel and a beta channel, so a team that wants to try a pre-release build can, and a team on a shipping app can stay on stable. The source tree reflects this split as well, with separate projects under Source/ for the two packages, one named Plugin.BLE and the other MvvmCross.Plugins.BLE.

The support table sets hard version floors per platform

The README carries a support and limitations table that is the most decision-relevant part of the documentation, because the platform requirements are not symmetrical. Xamarin.Android lists version 4.3 and Xamarin.iOS lists 7.0. Xamarin.Mac requires 10.9 (Mavericks), and the plugin requires 2.1.0 or later for that target. Xamarin.UWP lists versions 1709 to 10.0.16299 and requires 2.2.0 or later.

The MAUI row for Android, iOS, Mac and WinUI has no specific operating system version, but it does carry a floor of 3.0.0 for the plugin itself. Read those two columns as different things: the first is the operating system version the platform binding targets, and the second is the minimum plugin release that supports that target.

The floor values are also historical markers. Xamarin.UWP and the older Xamarin.Android and Xamarin.iOS bindings are listed as still supported, but the active part of the project is clearly the MAUI row given the MAUI version requirement. A new application on MAUI should start at 3.0.0, and the published releases sit above that, with 3.3.0-beta.2 available as a pre-release line alongside 3.2.1 and 3.1.1.

The sample scanner is the only worked example in the tree

The repository includes a sample Xamarin.Forms application described as a basic bluetooth LE scanner, and the README enumerates exactly what it does: check the BLE status, discover devices, connect and disconnect, discover services, discover characteristics, see characteristic details, and read, write and register for notifications of a characteristic.

That list is a good summary of the plugin's actual surface area. It is worth noticing what is absent. There is no background scanning, no bonding or pairing workflow, no device cache and no connection parameter tuning in that enumeration, and the README does not claim any of them. The project's useful links do point at iOS CoreBluetooth background modes documentation, but a link is not a feature statement, and the sample app itself is a foreground scanner.

For a new user, the sample app is the intended starting point. The README asks readers to look at the code and use it as a starting point to learn about the plugin and play around with it, and the table of contents points to further reading in doc/usage.md under API Usage, Important remarks and API limitations, and Best practice.

Packing the NuGet packages is a two step Cake and nuget flow

The README documents how the packages are produced, and the flow is short enough to describe precisely. The build step uses a Cake script. Open a console, change to the folder dotnet-bluetooth-le/.build and run cake.

shell
cake

Packing then runs nuget pack once per project, one for the vanilla library and one for the MvvmCross library.

shell
nuget pack ../Source/Plugin.BLE/Plugin.BLE.csproj
nuget pack ../Source/MvvmCross.Plugins.BLE/MvvmCross.Plugins.BLE.csproj

Both commands are relative to that .build folder, which is why the source paths start with ../Source. The repository root also carries global.json, which pins the SDK version used by the build, and a cleanup.sh script at the top level.

This is the path for people who want to produce a package from source, for example to build against a local branch. Most consumers do not need it, since the stable and beta packages are already on NuGet, and the README links both channels for Plugin.BLE and MvvmCross.Plugin.BLE. A contributor, though, follows the flow above, since the project asks that pull requests be based on the currently open development branch, and development work happens on a branch named after the milestone.

The API reference lives in doc/usage.md, not in the README

The README is an index rather than a manual. Everything a developer needs to write code is under doc/usage.md, with sections for Installation, Permissions, API Usage, Important remarks and API limitations, Best practice and Extended topics. There is also a release notes file at doc/changelog.md that the support and limitations section links to.

This is the honest limitation of the project as a source of truth. Permissions in particular are a per-platform concern, and the README does not restate which permissions each platform demands or what happens when they are missing. The same goes for the API limitations, which the project clearly considers significant enough to give its own section and to list under Extended topics.

So the practical reading order is short. Start at doc/usage.md#installation for the package reference, then read doc/usage.md#permissions before writing the first scan call, then work through doc/usage.md#api-usage against the sample app. Anyone who wants the behavioural details of error handling or platform quirks will not find them in the README, and the project does not pretend otherwise.

Apache 2.0 with a milestone branch contribution flow

The project is licensed under Apache 2.0, with the licence file at the root of the repository and a link to it in the README. For commercial .NET teams that is a familiar and permissive grant, and it removes the question that usually slows down adoption of a native interop library.

On the maintenance side, the repository is not archived and the last push was on 2026-10-19, so the tree is receiving current work. The published releases tell a slightly different story: 3.1.1 on 2026-05-17, 3.2.1 on 2026-05-14, and the pre-release 3.3.0-beta.2 on 2026-05-11. Releases therefore come with a beta track that runs ahead of stable, and the fixes that land after a stable tag are visible on the main branch rather than in a tag.

The contribution rule is worth internalising before opening a pull request, since the project states that development happens on a branch named after the milestone and asks that pull requests be based on the currently open development branch rather than on the default branch.

Editorial conclusion

Plugin.BLE fits .NET developers who already ship on Xamarin or MAUI and want scanning, connecting, service and characteristic discovery, and read, write and notify operations behind one API instead of four platform stacks. It does not fit engineers on plain .NET or on a platform outside the four listed, and it does not fit teams unwilling to read doc/usage.md for permissions and API limits. Verify first that your target OS version clears the platform floor in the support table, then confirm in doc/usage.md how the plugin reports adapter status and handles platform permissions on the one platform you care about most.

Frequently asked questions

Which platforms does Plugin.BLE support?

The plugin covers Xamarin.Android, Xamarin.iOS, Xamarin.Mac, Xamarin.UWP and MAUI on Android, iOS, Mac and WinUI. The support table lists version requirements per platform, and MAUI requires plugin version 3.0.0 or later.

Should I use Plugin.BLE or MvvmCross.Plugin.BLE?

Plugin.BLE is the plain Xamarin and MAUI package and can be used without MvvmCross. MvvmCross.Plugin.BLE is the MvvmCross binding, intended for applications that already use MvvmCross for view models and bindings.

Where do I find the installation and permission instructions for Plugin.BLE?

The README is an index and points to doc/usage.md, which holds the Installation, Permissions, API Usage, Important remarks and API limitations, Best practice and Extended topics sections. Release notes are kept separately in doc/changelog.md.

Does the Plugin.BLE sample app show how to notify on a characteristic?

Yes. The sample Xamarin.Forms scanner can check BLE status, discover devices, connect and disconnect, discover services and characteristics, show characteristic details, and read, write and register for notifications of a characteristic.

How do I build the Plugin.BLE NuGet packages from source?

Open a console, change to the dotnet-bluetooth-le/.build folder and run cake, then pack each project with nuget pack for Plugin.BLE.csproj and MvvmCross.Plugins.BLE.csproj. The repository root also contains global.json, which pins the SDK version used by the build.

Official sources

  1. dotnet-bluetooth-le/dotnet-bluetooth-le on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/dotnet-bluetooth-le-dotnet-bluetooth-le.svg)](https://hysenlabs.com/projects/dotnet-bluetooth-le-dotnet-bluetooth-le)