Library / SDK
pymodbus-dev/pymodbus avatar
pymodbus-dev/pymodbus

pymodbus counts five parts and lists four, and a patch release is allowed to change behaviour

A full modbus protocol written in python

2,776 stars1,073 forksPythonNOASSERTION

At a glance

What is it?
pymodbus is a pure-Python Modbus stack with a client, a server and a browser-based simulator, and its README is unusually direct about versioning, forks and non-standard hardware. The rough edges are in the details: a part count that does not match its own list, a semver disclaimer next to a patch release that may alter behaviour, and a documentation extra that stops at Python 3.12 while the classifiers claim 3.14.
Who is it for?
pymodbus fits a Python team that needs to talk to standard Modbus hardware or emulate it, and it does not fit a project that relies on dependency resolution treating a patch bump as inert. Pin the exact version, read API_changes.rst before moving between minor releases, and expect to read the source when a vendor device deviates from the standard.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 4 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 4, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The parts list announces five items and delivers four

The section headed Pymodbus in a nutshell opens by saying the project consists of 5 parts. Four are then listed. The client connects to your favourite devices, the server lets you create your own, the simulator is an html based server simulator, and the examples show both simple and advanced usage. The mismatch is small but it is the first thing a reader meets, and it is not corrected anywhere else in the file. The framing is otherwise accurate: the client, server and simulator triple is what the rest of the document describes, with the examples directory as the fourth entry and no fifth concept to find.

A patch release is documented as free to change behaviour

The versioning rules are stated with unusual precision and then disclaimed. Releases follow the pattern X.Y.Z, where Z means no API changes, just bug fixes and smaller enhancements, Y means API changes, bug fixes and bigger enhancements, and X means major changes in the API or in how the library is used. The upgrade table then qualifies the Z rule: going from 3.12.0 to 3.12.2 needs no changes, and the remark on that line is that fixing bugs can lead to different behaviours or returns. Going from 3.10.0 to 3.12.0 may need smaller changes to the calls, and 2.5.4 to 3.0.0 may need major changes in the application. Underneath all of it is the line that pymodbus does NOT follow the semver.org standard, which is why two files are pointed at for every upgrade.

Two pip commands, and a blunt note about the forks in the wild

The install path is short. The library is on pypi.org and the source is on github.com, with pip for people who want to use it and git clone for people who want to help:

code
pip install pymodbus

Serial support is an extra, so it is its own command:

code
pip install pymodbus[serial]

The manifest asks for Python 3.10.0 or newer and the prose says 3.11 is preferable, and a growing number of Linux distributions now ship the library in their standard installation. What is unusual is the fork paragraph. The file says plainly that a number of projects have forked pymodbus, either to freeze a version in time or to add functionality, that the additions were not rejected since all changes are welcome but the codeowners decided, and that support cannot be offered to those users because the project does not know what was changed or what state the forked code is in.

The simulator is a web interface meant to be reached over the internet

The simulator is the least conventional part of the stack. It is an html based server simulator with a web interface, where you configure the structure of a real device and monitor traffic online, and one of its stated features is letting distributed team members work on a virtual device using the internet. It can also simulate broken requests and responses and simulate error responses, with the parenthetical that those are hard to provoke in real devices. The manifest wires it up as a console script named pymodbus.simulator pointing at pymodbus.server.simulator.main, and pulls aiohttp through a simulator extra, with the floor set to 3.8.6 below Python 3.12 and 3.14.1 at 3.12 and above. Nothing in the visible text mentions authentication, TLS or a bind address for that web interface.

The synchronous server API is an async implementation underneath

Both programming styles are offered, and the relationship between them differs by component. The client exposes an asynchronous API and a synchronous API for applications, with a setup and call sequence the file measures in six lines of code, plus utilities to convert Python data types to and from multiple registers. The server is described as an asynchronous implementation for high performance, with synchronous API classes offered for convenience that run async internally. It can emulate real-life devices, carries a full server control context holding device information and counters, uses different backend datastores to manage register values, offers a callback to intercept requests and responses, and its work on RS485 is limited so it can run in parallel with other devices.

Standard devices are covered and non-standard ones are not

The scope statement comes early: pymodbus follows the standard Modbus and has only limited support for non-standard devices. The specification itself is named as Modbus_Application_Protocol_V1_1b3.pdf, available from modbus.org. Within that standard the coverage is broad. Transports cover serial RS-485, TCP, TLS and UDP, and the frame list names socket, RTU, RTU-over-TCP, TCP and ASCII, which is five entries for what a user experiences as a small number of connection types. Custom function codes are supported, so an extension point exists even where a device deviates, and the library claims no third-party dependencies at all apart from optional pyserial.

The manifest hides its version and its docs extra stops at Python 3.12

Two things in the packaging metadata pull in opposite directions. The version is not written down at all, since version is listed among the dynamic fields, so it is filled in at build time from somewhere else in the tree. The license, by contrast, is stated twice, as BSD-3-Clause with a BSD License classifier, while the repository license metadata reads NOASSERTION and a LICENSE file sits in the root. The documentation extra is the sharper inconsistency: it asks for recommonmark and for Sphinx 7.3.7 or newer only on Python below 3.12, while the classifiers claim support for 3.13 and 3.14 and the README says the test matrix runs 3.10 through 3.14. The declared Home page URL is also a repository link rather than the documentation site.

The root carries build and dist directories next to the gitignore

The top-level listing includes build/ and dist/, the conventional names for compiled output and for the packaged wheel, sitting alongside .gitignore. The rest of the tree explains how the project works: a .devcontainer directory, a check_ci.sh script at the root, a githooks directory, a doc/ directory beside a .readthedocs.yml, and the documentation set itself, API_changes.rst, AUTHORS.rst, CHANGELOG.rst, CODE_OF_CONDUCT.md, CONTRIBUTING.rst, MAKE_RELEASE.rst, MANIFEST.in, SECURITY.md and CODE_OF_CONDUCT.md. The README is reStructuredText rather than Markdown, complete with image directives and role syntax. The examples directory holds a certificates folder for the TLS transport, several client and server variants including sync and async pairs, a simulator script, a message parser, a custom message example and its own py.typed marker alongside the one the library ships, plus a package test tool for checking an install.

Editorial conclusion

pymodbus fits a Python team that needs to talk to standard Modbus hardware or emulate it, and it does not fit a project that relies on dependency resolution treating a patch bump as inert. Pin the exact version, read API_changes.rst before moving between minor releases, and expect to read the source when a vendor device deviates from the standard. Treat the simulator as a development tool that reaches for the internet by design, and confirm what your device speaks before assuming the client will drive it.

Frequently asked questions

how to install pymodbus

With pip install pymodbus from PyPI, or pip install pymodbus[serial] if you need the serial interface, which pulls in pyserial. Python 3.10.0 or newer is required and the README says 3.11 is preferable. Contributors are pointed at git clone instead.

pymodbus sync vs async

Both are offered. The client has an asynchronous API and a synchronous API, while the server is an asynchronous implementation for high performance with synchronous classes provided for convenience that run async internally.

Does pymodbus follow semantic versioning?

No, and the README says so explicitly. Under its own X.Y.Z rules a Z release has no API changes, though the upgrade example notes that bug fixes can lead to different behaviours or returns. API_changes.rst and CHANGELOG.rst are the files to read when upgrading.

What devices can pymodbus talk to?

It follows the standard Modbus protocol with only limited support for non-standard devices, while still allowing custom function codes. Transports include serial RS-485, TCP, TLS and UDP, with socket, RTU, RTU-over-TCP, TCP and ASCII frames.

What license is pymodbus released under?

The packaging metadata declares BSD-3-Clause with a BSD License classifier, and a LICENSE file sits in the repository root, while the repository license metadata itself reads NOASSERTION.

Official sources

  1. Issues
  2. pymodbus-dev/pymodbus on GitHub
  3. README
  4. 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/pymodbus-dev-pymodbus.svg)](https://hysenlabs.com/projects/pymodbus-dev-pymodbus)