gpiozero: the Raspberry Pi library that starts at the component
A simple interface to GPIO devices with Raspberry Pi
At a glance
- What is it?
- A Python GPIO library organised around LEDs, buttons and sensors rather than pin numbers, with a pin factory layer underneath and mock pins for testing on a desktop.
- Who is it for?
- The design decision that makes GPIO Zero pleasant is that the unit of the library is a component rather than a pin number, and everything else in the repository exists to protect that decision. Source tools let behaviour be described instead of sequenced, the pin factory keeps the vendor library out of user code, and mock pins make the whole thing testable away from hardware.
- 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 73 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 7, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A component API instead of a pin API
GPIO Zero is described in its own repository as a simple interface to GPIO devices with the Raspberry Pi, developed and maintained by Ben Nuttall and Dave Jones. That description undersells the design choice. The library is not organised around pin numbers or around registers. It is organised around components, and a component constructor takes the pin the part happens to be wired to.
The smallest complete program is four meaningful lines. You import LED and sleep, construct the LED on pin 17, then alternate on and off once a second forever. There is no setup function, no direction call, no pull-down configuration, no cleanup handler. The library infers what a part needs from the class you instantiated.
That matters more than it sounds. Most of what people find tedious about direct GPIO work is bookkeeping that has nothing to do with the behaviour they are trying to express. GPIO Zero pushes that bookkeeping down into device classes, so the code you write describes the circuit rather than the register writes needed to drive it. For a beginner this is the difference between a working first circuit and an afternoon spent on pin mode constants. For an experienced person it is the difference between a sketch that reads clearly and one that reads like a datasheet.
Three levels of the same idea
The README demonstrates three progressions, and they are worth reading as a single arc rather than three separate examples. The first is the imperative loop above, where you call on and off yourself. The second moves control to the hardware by assigning callbacks: a Button on pin 3 has its when_pressed attribute pointed at the LED on method and its when_released attribute pointed at off. Once that assignment is in place, the program contains no control flow at all. It constructs two objects, wires two attributes, and calls pause, which blocks forever while the callbacks do the work.
The third level is the declarative one, and it introduces the tools module. Here the wiring is not a callback but a value. A garden OutputDevice on pin 17 has its source attribute set to a combination expression built from booleanized and all_values. A LightSensor on pin 5 goes through booleanized with a threshold of 0 and a hysteresis of 0.1, a MotionSensor on pin 4 is combined with it through all_values, and the result is assigned as the garden's source. The garden switches on when the combined condition says so.
The distinction that carries through all three is between imperative control, reactive callbacks and a declarative description of a relationship between values. The source tools chapter in the documentation is where the third style is explained properly. Reading these three examples in order also communicates the library's intent well: you can stop at whichever level fits the problem, and the library does not force you upward.
Pin factories and the mock pin interface
GPIO Zero does not talk to hardware registers itself. It builds on a number of underlying pin libraries, and the choice between them is exposed as a pin factory. The README is explicit that a particular pin library can be selected either for a whole script or per device, according to what you need. That granularity is the interesting part. A single process can drive one LED through one backend and read a sensor through another, which matters when a vendor library has better support for input than output, or when one library cannot do remote GPIO and another can.
Because the backend sits behind a factory, the library can also offer a mock pin interface for testing. A mock pin accepts the same calls a real pin does and records what happened instead of touching hardware. That makes it possible to run the same program on a laptop, assert that the LED was switched on when the button was pressed, and get a real failure when the wiring between the two is wrong. The README points at the pin factory and mock pins sections of the API documentation for the details.
This is the layer most worth understanding before writing anything substantial. If a project is going to have tests, the question to ask is not whether mock pins exist but whether the program's design keeps pin access behind the factory. Code that reaches for a pin library directly cannot be tested that way, and GPIO Zero cannot enforce the boundary for you.
What is in the repository
The repository is small and its top level gives a fair impression of the scope. There is a gpiozero package, a separate gpiozerocli directory, a docs directory, tests, scripts, and the packaging and build files. The default branch is main, the licence is BSD-3-Clause, and the language is Python. Stars sit a little over two thousand with several hundred forks and roughly one hundred and eighty open issues.
The packaging file is as minimal as modern Python packaging gets. setup.py contains two meaningful lines:
from setuptools import setup
setup()Everything else moves to declarative configuration, which is what setup.cfg and tox.ini are for. The Makefile is where the workflow lives. It shells out to setup.py to work out the distribution name and version, derives a wheel name by substituting dashes for underscores in the distribution name, and then reads the generated egg-info SOURCES.txt to build a list of Python sources, filtering out egg-info noise. Documentation sources are enumerated separately with wildcards over the docs directory for images, graphs, message sequence charts, pinout files and reStructuredText. Output names are computed rather than hardcoded, including a universal py3-none-any wheel.
The Makefile also names four manual pages, which tells you the project ships command line tools as first-class parts of the package. The default target is a menu of phony options: install, develop, test, doc, doc-serve, doc-reqs, source, wheel, zip, tar, dist, clean, release and upload. That is a well maintained library rather than a weekend project, and the layout reflects someone who has been running the same commands for a while.
Installation, packaging and where it ships by default
Installation is the least interesting part of this library, mostly because it is already handled. GPIO Zero is installed by default in the Raspberry Pi OS desktop images, so on a normal desktop Raspberry Pi the import works before you install anything. On Raspberry Pi OS Lite, on other operating systems, or when you are running against remote GPIO or mock pins, the Installing chapter of the documentation covers it.
The dependency story follows from the pin factory design. Since the actual register access is delegated, the set of vendor libraries you need depends on the backend you select, which is one more reason the factory is set at the script or device level rather than fixed at import time.
Documentation is comprehensive and hosted at gpiozero.readthedocs.io, and the README names the chapters a contributor needs: Contributing and Development. The documentation source is in the repository alongside the code, which is why the Makefile bothers to enumerate doc assets by extension, including a .gpi pattern for pinout diagrams and a .mscgen pattern for message sequence charts. Readme rendering, manual pages and a .readthedocs.yaml configuration all point at a project where the documentation is treated as part of the deliverable.
One practical detail worth noting: the topics list includes zero-boilerplate alongside physical-computing, education and raspberry-pi. The education tag is not incidental. GPIO Zero came out of the same community that wanted classroom hardware to be teachable, and the imperative-to-declarative progression in the README reads like a lesson plan.
Asking questions and reporting problems
The README splits support into four channels depending on what you need. Feature requests and bug reports go to the issue tracker on GitHub. Questions and help are better suited to the GitHub discussion board, the Raspberry Pi Stack Exchange, or the Raspberry Pi forums. That split is worth respecting: a question that lands in the tracker tends to get closed without an answer, and the forums have a large body of already answered GPIO questions.
The contributor list in the README is long, over fifty names with links to their individual commit histories, which is a reasonable signal of how distributed the maintenance is. Contributors include people associated with the Raspberry Pi Foundation, university teaching, and accessibility work, and several of the names appear on documentation rather than on the library itself. Dan Jackson and Daniele Procida are the names most associated with the documentation effort.
So the practical summary of the repository is this: a component-oriented Python library, small enough to read in an afternoon, with a deliberate seam between user code and the vendor pin library. The library does not try to be the most feature-complete GPIO binding available. It tries to be the one you can hand to a beginner without a lecture first, and judging by the topic list and the shape of the README, it has held that line for a long time.
Editorial conclusion
The design decision that makes GPIO Zero pleasant is that the unit of the library is a component rather than a pin number, and everything else in the repository exists to protect that decision. Source tools let behaviour be described instead of sequenced, the pin factory keeps the vendor library out of user code, and mock pins make the whole thing testable away from hardware. If you are picking a GPIO library for a teaching project or a first robot, the zero-boilerplate label in the topic list is an accurate summary of what you get.
Frequently asked questions
How do I install GPIO Zero?
On Raspberry Pi OS desktop images it is already installed, so no action is needed. For Raspberry Pi OS Lite, other operating systems, remote GPIO or mock pins, follow the Installing chapter of the documentation at gpiozero.readthedocs.io.
Do I need to set the pin direction before using an LED?
No. Instantiating a component class such as LED(17) configures the pin the class needs. The direction, pull and drive settings are handled by the device class rather than by the script.
What is the difference between the callback style and the source style?
Callbacks assign behaviour to events, as when button.when_pressed points at led.on. The source style instead sets a device's source to a value produced by source tools, as when an OutputDevice's source is set to all_values(booleanized(light, 0, 0.1), motion).
Can I use GPIO Zero on a machine that is not a Raspberry Pi?
Yes, through the alternatives the pin factory layer provides, including remote GPIO and a mock pin interface. The mock interface is designed for testing and records pin activity without touching hardware.
How do I choose which underlying pin library is used?
Set the pin factory, which can be done for a whole script or per device. GPIO Zero is built on a number of underlying pin libraries and delegates register access to whichever one is selected.
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/gpiozero-gpiozero)