Facedancer 3: emulating USB devices from Python
Implement your own USB device in Python, supported by a hardware peripheral such as Cynthion or GreatFET
At a glance
- What is it?
- Facedancer 3 is a Python module that turns a hardware board such as Cynthion or GreatFET into a programmable USB device controller, with fine grained control over misbehaviour and a MITM mode for protocol analysis. It suits hardware security researchers, and it needs GNU/Linux plus a supported board, which rules out a lot of laptops.
- Who is it for?
- Adopt Facedancer 3 when you have a supported board and a real question about how a host controller behaves, because the fine grained control over USB misbehaviour and the MITM mode are things a software fuzzer cannot give you, and the 3.0 rewrite gives you a modern Python API to write them in.
- Can I use it commercially?
- Yes. BSD-3-Clause 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 154 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A board that pretends to be the device under test
Facedancer boards are simple hardware devices that act as remote controlled USB controllers. Put the right software on one and the board impersonates a USB device to whatever is plugged into it. The Facedancer 3 software repository is the Python side of that arrangement: it lets you write USB device emulations in Python and, in the words of the README, the control is fine grained enough to cause all kinds of USB misbehaviour.
Two audiences show up in the project description. The first is anyone who wants to build a device that does not exist yet, a prototype peripheral for a driver you are writing or a device you want to test against a host without buying the real thing. The second is the security side, where the same hardware is used to fuzz USB host controllers, to see how a host reacts to a device that answers in unusual or hostile ways.
This repository is the next generation of the software, descended from the original GoodFET based Facedancer. Version 3 adds support for multiple boards and a set of features the earlier version did not have, and it is packaged as a normal Python module you install with pip. The authors credit a long list of contributors, and the code is published under a BSD licence with a `Development Status :: 5 - Production/Stable` classifier in the package metadata.
The BACKEND variable decides which board you are talking to
The first thing the documentation tells you to do is set the BACKEND environment variable, which tells the software which type of Facedancer board you are using. If it is not set, the software tries to guess based on what is connected, and the documentation is blunt about that fallback: it does not always make the best guesses, so you are probably better off setting it yourself.
The supported list is a plain enumeration of names you assign to the variable:
export BACKEND=greatfetThe boards behind those names are the Cynthion USB Test Instrument with `BACKEND=cynthion`, the GreatFET One with `BACKEND=greatfet`, the NXP LPC4330 Xplorer board also under `BACKEND=greatfet`, the CCCamp 2015 rad1o badge with a GreatFET loadable also under `BACKEND=greatfet`, all GoodFET based Facedancers including the common Facedancer21 with `BACKEND=goodfet`, the RPi plus Max3241 Raspdancer boards with `BACKEND=raspdancer`, and the HydraDancer and HydraUSB3 boards with `BACKEND=hydradancer`.
That the Xplorer board and the rad1o badge share the greatfet backend is not an accident, it reflects that they present the same interface to the software. The important consequence for a first-time user is that the backend name is about the programming interface, not the model of the board.
Running an example on GNU/Linux with pip
Installation is a single command, and the module is imported like any other Python package:
pip install facedancerThe project metadata adds the constraints you need to know before you start. Python 3.10 or later is required, and the runtime dependencies are pyusb, pyserial, prompt-toolkit, libusb1 and hid-parser. The version number is not written into the metadata; it is derived from git tags by setuptools-git-versioning, starting at 3.0.0, which means installing from a source checkout gives you a version derived from the commit you are on.
A first real use is running one of the bundled examples. The documentation points you at the `examples` directory for the new syntax and at `legacy-applets` for the core scripts in the old syntax, and the invocation is a direct script run:
export BACKEND=greatfet
./examples/rubber-ducky.pyThe example directory also contains `minimal.py`, `template.py`, `imperative.py`, `coroutine.py`, `ftdi-echo.py`, `mass-storage.py`, `usbproxy.py`, `hackrf-info.py` and a test file, so the range of what a script looks like is visible in the repository itself.
One platform detail decides whether any of this works for you. The documentation states that actual Facedancer 3 does not work on Windows, citing some issues in pyusb, and only GNU/Linux.
MITM mode puts a proxy between the device and the host
The headline feature of the 3.0 codebase is the ability to MITM, spelled out in the README as Meddler-In-The-Middle, USB connections. This replaces the original USBProxy project by one of the authors, and the ASCII diagram in the documentation shows the arrangement: a proxied device on one side, a host computer running the Facedancer software in the middle, and the Facedancer device acting as a USB controlled controller on the other, with the target USB host at the far end.
The point of the topology is that the software sits between two real parties and can observe or change traffic that would otherwise pass straight through. The documentation is specific about when this matters: it is especially useful when you do not control the software running on the target device, for example on embedded systems or games consoles. Protocol analysis and live manipulation of USB packets are the two named uses.
The README also admits the state of this feature honestly. It says the feature is complete, but could use more documentation, and that pull requests are welcome. Complete but thinly documented is a fair description of a subsystem that is newer than the rest of the project.
There is also a roadmap under development for what comes next, including high speed, USB 2.0, device emulation on devices with USB 2.0 PHYs, and on the fly generation of USB device controllers in gateware. Boards that could be supported soon are any Linux computer with gadgetfs support, such as the Pi Zero or Beaglebone Black, and anything supporting USB over IP.
Hardware restrictions decide which board you need for MITM
Not every board can do every job, and the documentation is unusually precise about the boundaries, which makes them easy to plan around.
Endpoint limits come first. Hardware restrictions prevent the MAX3420 and MAX3421 boards from emulating more complex devices, because there is a limitation on the number and type of endpoints that can be set up. The LPC4330 boards, such as the GreatFET, have fewer such limitations. The consequence is direct: if your emulation needs several endpoints of a given type, a GoodFET or Raspdancer board is the wrong purchase and a GreatFET or Hydra board is the right one.
The MITM capability has its own hardware boundary, and it is the one to check first if protocol analysis is your goal. The MAX3420 and MAX3421 boards, which are the goodfet and raspdancer backends, currently cannot be used as USBProxy-nv MITM devices. All modern boards, the greatfet and hydradancer backends, should be fully functional. So the boards that are the most limited for plain device emulation are also the ones that cannot do MITM at all.
There is a final hardware caveat on the newer boards. The HydraDancer and HydraUSB3 boards do not currently support host mode, which limits them to device side work.
Version 3 dropped every legacy script, and 2.9.x is still installable
The most disruptive thing about Facedancer 3 is not a feature, it is a rewrite. The documentation states that 3.0 is a ground up rewrite of the original emulation core and does not support legacy scripts. If you are using scripts or training content that depend on features or APIs deprecated in the 3.0.x line, the documentation gives you the escape hatch: install the latest 2.9.x release with a version cap.
pip install "facedancer<=3"The legacy applets and examples live on the v2.9.x branch of the same repository, so the older code is still reachable even though the main branch has moved on. That is a good sign for anyone with an existing script collection, since the transition can be staged rather than done in one jump.
The two syntaxes are visible in the repository layout. Examples written in the new syntax are under `examples`, and the core scripts in the old syntax are under `legacy-applets`, which means a single clone carries both generations. The presence of a `CHANGELOG.md` at the top level, alongside the `docs/` folder that feeds Read the Docs, means the API differences between the two lines are meant to be looked up rather than guessed at.
The practical cost of the upgrade is migration work in your own scripts, not a maintenance burden on the library. The 3.1.3 release was published on 2026-05-22, the same day as the last push to the main branch, with 3.1.2 in December 2025 and 3.1.1 in August 2025.
A BSD licensed research tool with a maintained release line
The licence is the simplest part of the picture. The package metadata declares a BSD licence and the classifier reads `License:: OSI Approved:: BSD License`, and the repository carries a LICENSE file at the top level. A BSD licence is permissive and imposes no copyleft obligation on code that links to it, though this article does not give legal advice and the file itself is what counts.
The activity level is healthy for a hardware project. The last push to the main branch was on 2026-05-22, matching the 3.1.3 release, and the two releases before it, 3.1.2 and 3.1.1, landed in December 2025 and August 2025. The repository also carries a CODE_OF_CONDUCT.md, a Release.make script at the top level, and a `test/` directory, which suggests release and test steps are part of the routine rather than ad hoc.
The build system is setuptools with a PEP 517 backend, requiring setuptools 64 or newer, wheel, and setuptools-git-versioning, with the package directory mapped explicitly so that the `facedancer` package resolves to the `facedancer` source directory. Documentation is published at facedancer.readthedocs.io.
Editorial conclusion
Adopt Facedancer 3 when you have a supported board and a real question about how a host controller behaves, because the fine grained control over USB misbehaviour and the MITM mode are things a software fuzzer cannot give you, and the 3.0 rewrite gives you a modern Python API to write them in. Do not adopt it as a drop-in for your old scripts, since 3.0 is a ground up rewrite with no legacy script support, and do not plan around Windows, where the documentation says it does not currently work. Before you buy hardware, check the backend list against the board you own and confirm the endpoint limits of MAX3420 and MAX3421 boards if you intend to use MITM mode.
Frequently asked questions
How do I install Facedancer and run my first USB emulation script?
Install it with `pip install facedancer`, set the BACKEND environment variable to the board you are using, for example `export BACKEND=greatfet`, and run one of the scripts in the examples directory such as `./examples/rubber-ducky.py`. Python 3.10 or later is required, and the project currently only works on GNU/Linux.
Which Facedancer boards support MITM and USB protocol analysis?
The documentation states that the MAX3420 and MAX3421 boards, which are the goodfet and raspdancer backends, currently cannot be used as USBProxy-nv MITM devices, while all modern boards under the greatfet and hydradancer backends should be fully functional. The HydraDancer and HydraUSB3 boards do not currently support host mode.
Do my old Facedancer scripts work with version 3?
No. Facedancer 3.0 is a ground up rewrite of the emulation core and does not support legacy scripts, and the older applets and examples live on the v2.9.x branch of the repository. If you need the old behaviour, the documentation shows `pip install "facedancer<=3"`.
What is the BACKEND environment variable for?
The BACKEND variable tells the software which type of Facedancer board you are using, for example greatfet, goodfet, hydradancer, raspdancer or cynthion. If it is not set the software tries to guess from the connected hardware, and the documentation notes that it does not always make the best guesses.
Official sources
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.
[](https://hysenlabs.com/projects/greatscottgadgets-facedancer)Was this useful?