# LCM: a message bus for real-time systems, without a hub

> Lightweight Communications and Marshalling is a set of libraries and tools for publish and subscribe messaging and type safe marshalling, aimed at real-time systems where bandwidth and latency matter. Peers talk to each other directly over UDP multicast, there is no broker and no daemon, and the repository carries five build systems and bindings for six languages.

**lcm-proj/lcm** — Lightweight Communications and Marshalling

- Repository: https://github.com/lcm-proj/lcm
- Stars: 1,212 · Forks: 431
- Language: Java
- License: LGPL-2.1
- Published: 2026-10-19 · Updated: 2026-10-19 · Language: en
- Canonical page: https://hysenlabs.com/projects/lcm-proj-lcm

## No hub, no daemon, no database

LCM stands for Lightweight Communications and Marshalling, and it is a set of libraries and tools for message passing and data marshalling, targeted at real-time systems where high-bandwidth and low latency are critical.

The feature list is short and one line in it is the design in miniature. There is no centralized database or hub, and peers communicate directly. There are no daemons. There are few dependencies. Alongside that sit low-latency inter-process communication, an efficient broadcast mechanism using UDP Multicast, type-safe message marshalling, and user-friendly logging and playback.

So the architecture is a bus in the network sense rather than in the broker sense. A component publishes a typed message onto a topic, and every peer subscribed to that topic receives it, with the operating system multicast doing the fan out. There is no server to run, which for a robot that has to boot in under a second or for a laptop that goes to sleep is a real property rather than a simplification, and it also means there is nothing to authenticate against and nowhere to store a message that was published while a peer was down.

The toolchain around the transport is the other half of the product. LCM ships a logger that records traffic to a file, a log player that replays it, a log filter, a spy that shows what is on the bus, and sink and source utilities. The Python packaging lists all of them as console scripts, and the examples directory includes an lcm-spy example, so the tooling is meant to be used rather than merely shipped.

The licence is LGPL-2.1, which is the weak copyleft, and the project was last pushed to on 2026-09-24 with the release v1.5.3 published the same day.

## The type definition is the contract, and the generator is the compiler

LCM's type safety comes from a definition file and a code generator rather than from a serialisation format negotiated at runtime. You describe a message type, and lcmgen produces the marshalling and unmarshalling code, and the bindings for the language you are using, from that single description.

That is the same idea as protobuf or FlatBuffers, and the difference in emphasis is the target. LCM is aimed at systems where the message has to be marshalled quickly enough that the cost of the format is visible in the profile, and where the same type definition has to be compiled into half a dozen languages because the components of a robot are written in different ones.

The repository layout makes the structure clear. The lcm/ directory holds the core library, lcmgen/ the generator, and then there is a directory per binding: lcm-java/, lcm-python/, lcm-lua/, lcm-dotnet/ and lcm-go/, with lcm-lite/ as a reduced implementation. The logging and inspection tools are grouped under lcm-logger/, and liblcm-test/ holds the test harness.

The examples directory shows the languages in use, with c, cpp, csharp, go, java, lua, matlab and python directories alongside a types directory, which is where the message definitions live.

The practical consequence for a build is that the generation step is part of the build, not something you run by hand. The message type is an interface between components written in different languages, and if the definition and the generated code drift apart, the failure appears as a marshalling mismatch at runtime rather than as a compile error.

## Five build systems, because LCM is embedded in other things

The list of build systems in the repository is unusual, and it is the clearest statement of what kind of project this is.

There is BUILD.bazel with a.bazelignore and a MODULE.bazel for the Bazel module system, and a lcm-bazel/ directory. There is CMakeLists.txt with CMakePresets.json and a cmake/ directory, plus lcm-cmake/ and m4macros/. There is meson.build with meson_options.txt, and lcm-pkgconfig/ for the pkg-config metadata that a Unix install needs. There is vcpkg.json for consumption through vcpkg. And there is pyproject.toml, which builds the Python package through scikit-build-core, so the same source tree produces a wheel.

```toml
[project.scripts]
lcm-gen = "lcm:run_gen"
lcm-logger = "lcm:run_logger"
lcm-logplayer = "lcm:run_logplayer"
lcm-logplayer-gui = "lcm:run_logplayer_gui"
lcm-logfilter = "lcm:run_logfilter"
```

The Python packaging is configured carefully, which is a hint about the maintainers. The wheel expands macOS universal tags, the CMake defines switch the pkg-config install off and the pip build on, and cibuildwheel is set up to build wheels for musllinux and for the experimental manylinux armv7l image, with the per-image package installs spelled out. The pytest configuration is strict, with strict markers, strict config, xfail strict and filterwarnings set to error, so a warning in the test suite fails the run.

There is also a docker/ directory and a format_code.sh script, and the top-level build files sit next to a.clang-format, so the formatting rules are in the repository rather than in a contributor's editor.

## The platform matrix, and the two languages nobody is maintaining

The README lists what is supported and what is not, and the second list is the more interesting one.

The platforms are GNU/Linux, with Ubuntu 22.04 and 24.04 and Fedora 42 named, macOS 14 and 15, and Windows 2019 and 2022. The languages are C, C++, Java, Lua, MATLAB and Python 3.7 and later.

Then there is a section for unmaintained languages, and it contains two: Go and C#/.NET. The wording is precise about what that means. Pull requests for these languages are still welcome, and if you are interested in maintaining them, please let us know.

That is a better way to say it than a silent deprecation, and it tells you something useful about the project. The core library and the generator are maintained, the mainstream bindings are maintained, and the two bindings that lost their maintainers are still there in the tree, in the examples and in the build files, waiting for someone to take them on.

Note what is not in the list. There is no mention of delivery guarantees, of authentication, of encryption, of a persistent store, or of traffic shaping. The features list is low-latency communication, multicast broadcast, type-safe marshalling, logging and playback, and the absence of a hub, daemons and dependencies. That absence is the honest description of what LCM is and is not.

The Python package is where the version information is clearest, since pyproject.toml declares version 1.5.3 with a Development Status of 4 - Beta and a requirement of Python 3.7 or later.

## Active again, with stability as the stated goal

The roadmap section at the top of the README is the part of the documentation that tells you what the maintainers intend, and it is unusually careful in its wording.

It says the LCM project is active again, that the current long-term plan is to focus on stability and maintenance patches to fix longstanding issues, and that longer term the project is open to evolution of LCM to have additional features, as long as backwards compatibility is enforced. It ends by saying the maintainers are very open to community feedback and involvement on new features.

Three things follow from that. The first is that the recent release activity is not a burst of new features but a maintenance cadence: v1.5.1 in December 2024, v1.5.2 in October 2025 and v1.5.3 in September 2026, with the last one published on the same day as the last push to the repository.

The second is the compatibility promise. A project that has been dormant and has come back with a stability-first plan is telling you that the wire format and the API will not move under you in a minor release, and that when features do arrive, they will be additive. For an embedded format that lives in a robot's source tree and in a colleague's simulator on the other side of the world, that promise is the product.

The third is that the contribution bar for new features is now not the point. The interesting work, on this reading, is the maintenance patches and the issues.

## Conclusion

LCM fits a robotics or sensor research team that wants typed messages on a shared network segment without standing up a broker, and that values a code generator producing native bindings in the language of each component. It does not fit a system that needs delivery guarantees, authentication or a message store, since the transport is multicast UDP and the project describes no such features, and it does not fit a Go or .NET team, since those bindings are unmaintained. Verify three things before you commit: that the platforms you deploy on are in the supported list, since the matrix names specific distribution and macOS and Windows versions, that multicast routing works on your network, because that is the assumption the whole design rests on, and that the code generation step is in your build, since the type definitions and the generated bindings have to be regenerated together when a message type changes.

## FAQ

### What is LCM and how does it move messages?

LCM is a set of libraries and tools for message passing and data marshalling in real-time systems. It uses a publish and subscribe model over UDP Multicast, with peers communicating directly: there is no centralized database or hub, and no daemons to run. The transport is low latency and the message marshalling is type safe, with code generated from type definitions.

### Which languages does LCM support?

C, C++, Java, Lua, MATLAB and Python 3.7 and later are supported. Go and C#/.NET are listed as unmaintained, where pull requests are still welcome and the maintainers ask to be told if you want to take them on. The repository holds a directory per binding, with lcm-go/ and lcm-dotnet/ still present in the tree.

### How do I build LCM?

The repository carries several build systems, with Bazel through BUILD.bazel and MODULE.bazel, CMake through CMakeLists.txt and CMakePresets.json, Meson through meson.build, vcpkg through vcpkg.json for Windows, and pip through pyproject.toml using scikit-build-core. The documentation has separate pages for installing LCM and for building it from source.

### What tools come with LCM?

The Python package exposes the command line tools as console scripts, including lcm-gen for code generation, lcm-logger to record traffic, lcm-logplayer and lcm-logplayer-gui to replay it, lcm-logfilter, lcm-spy to watch the bus, plus lcm-sink and lcm-source. The examples directory includes an lcm-spy example.

### Is LCM still being developed?

Yes. The README says the project is active again, with the current long-term plan focused on stability and maintenance patches for longstanding issues, and openness to new features as long as backwards compatibility is enforced. The recent releases are v1.5.1 from 2024-12-23, v1.5.2 from 2025-10-23 and v1.5.3 from 2026-09-24, with the repository pushed to on the same day as the last one.

## Sources

- [Issues](https://github.com/lcm-proj/lcm/issues)
- [lcm-proj/lcm on GitHub](https://github.com/lcm-proj/lcm)
- [License: LGPL-2.1](https://github.com/lcm-proj/lcm/blob/master/LICENSE)
- [README](https://github.com/lcm-proj/lcm/blob/master/README.md)
- [Releases](https://github.com/lcm-proj/lcm/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/lcm-proj-lcm
