Engineering

The best open source EtherCAT libraries, and what to use when

You have picked EtherCAT. The hardware is on the bench, the coupler is blinking at you, and now you have to choose a master stack.

So you search. You'll quickly get four names that stand out. However, all four are very different and for different reasons.

We went through this properly last year, for a product that puts a coding agent on the industrial PC itself. Here is what we found, including the part where the best library lost.

Short answer

Your situationUse
You control the machine, the kernel and the buildIgH EtherLab
You are already a C shop and want something smallSOEM
You ship a single binary onto hardware you do not controlethercrab
You cross-compile to musl or Arm and want no C in the treeethercrab
You need FoE firmware transfer, EoE, or cable redundancyIgH EtherLab
Your chain includes a modular coupler with backplane IOIgH, or ethercrab with the module configuration written by hand

The rest of this is why.

The four EtherCAT master libraries worth knowing

IgH EtherLab. C, roughly twenty years old, and the most capable of the four by a wide margin. CoE, EoE, FoE and VoE mailboxes. Native EtherCAT NIC drivers plus a generic one. RTAI, Xenomai and PREEMPT_RT support. EEPROM and SII tooling. It claims IEC/PAS 62407 conformance and it has a long field record behind it. If you are reading a list like this hoping someone will just tell you which one is best, it is this one.

SOEM. Also C, much smaller, BSD-like licence with a linking exception. Easy to read, widely deployed, and a perfectly reasonable default if you are already a C shop.

ethercrab. Pure Rust, MIT or Apache-2.0, std and no_std. The youngest of the four by a long way. It is what we shipped.

The ethercat crate. Rust bindings onto IgH. It inherits everything IgH gives you, and everything IgH costs you.

There is also acontis EC-Master, which is commercial and therefore a different conversation. We did not evaluate it.

How you ship decides your EtherCAT library

Not "which is best". "How are you shipping this?" The answer changes completely across three cases.

You control the whole machine, including the kernel and the build. IgH is excellent, the licence is a non-issue, and you should take the mature stack. Genuinely, stop reading and go and use it.

You are shipping a binary onto someone else's hardware. IgH wants an out-of-tree kernel module. A single file you copy onto a controller can't carry one, and an update pipeline that replaces a binary can't install one. That is what ended it for us.

The licence is a second and smaller question, and it's worth being precise because it gets repeated wrongly. libethercat is LGPL 2.1, and LGPL 2.1 does allow static linking. IgH's own 1.5 manual says the library is licensed that way specifically to permit it, and ships libethercat.a for the purpose. The 1.6 manual changes that sentence to dynamic linking. Either way the obligation is the same one LGPL always carries: whoever you give the binary to has to be able to relink it against their own build of the library. That is a real thing to take on for a single distributed file. It is not the blocker people assume.

You are cross-compiling to musl, or to Arm, or both. A C dependency turns your build into a cross-compilation project. That cost is not paid once. It is paid every release, by whoever is on call.

We are the second and third cases at the same time. That single distribution decision knocked out IgH, knocked out the crate that binds to IgH, and knocked out SOEM's bindgen path. What was left that could still do CoE was ethercrab.

None of that is a quality judgement. We rejected the best library in the list on packaging grounds. If your packaging is different, you should reach a different answer.

What we found using ethercrab

Everything below was checked against ethercrab 0.7.1, the current release as of September 2026, by reading the crate source rather than the documentation.

It gives you the wire, not the device. ethercrab is a master implementation. It does not read ESI at all. So a product code comes back as 0x044c2c52 and stays that way. You need the vendor's ESI file to get a name out of it.

We wrote our own ESI reader for four fields: vendor id, vendor name, product code and device name. There is a full ESI parser on crates.io. We did not take it. We needed four fields and it models the entire specification.

Its automatic configuration only ever reads. ethercrab discovers the PDO mapping a device is already reporting and builds the process image from that. It does not write a mapping. There is not a single SDO write in its configuration path.

For a simple terminal that describes itself in EEPROM, this is fine and you will never notice.

Why ethercrab could not map our modular coupler

For a modular coupler it is not fine. Some couplers have no fixed process image: the IO sits on a vendor backplane bus behind the EtherCAT node, and what the device exposes depends on which modules are fitted. EtherCAT has a mechanism for this. The master writes a Configured Module Ident List at object 0xF030 to tell the coupler what is behind it, then assigns the PDOs explicitly. Until that happens, the modules are not selected and their IO is not in the process image.

ethercrab has no concept of modules. Search the 0.7.1 source for that object, for 0xF050, or for the words "module ident", and you get nothing.

So it comes up clean. The device enumerates. It reaches PRE-OP. Nothing errors. The process image is built correctly out of what an unconfigured coupler reports, which is not the IO you wanted. Everything is green and the backplane is not there.

Here is the bit that got me. ethercrab parses the ESI flags that mark exactly this case. There are flags for a PDO that comes from a module, that depends on a slot, that is overwritten by a module. They are all defined, all named after their ESI attributes, and then the flags field is commented out of the struct and nothing reads it. The library has the full vocabulary for modular devices and no implementation behind it.

It is not a dead end, and it is not something EtherCAT makes impossible. IgH does it. The vendor tools do it. SDO writes are public in ethercrab, and upstream's answer to configurable mapping is to write the assignment by hand in the PRE-OP hook. Their front page shows you how. You can drive a modular coupler with it. You just have to write the module configuration yourself, and nothing will tell you that is the piece you are missing.

And it is young, and its changelog says so. Version 0.7.0, released in March 2026, fixed reading a device's status code from the correct register when a state transition fails, and returning the real CoE abort code instead of a generic one. Those are bugs a twenty-year-old stack fixed a long time ago. That is what adopting a pre-1.0 library looks like, and you should see it before you commit. As of 0.7.1 it also implements CoE only, so no firmware transfer over FoE and no tunnelled Ethernet over EoE, and it has no cable redundancy. If you need any of those, go back to IgH.

Starting an EtherCAT master resets the segment

On EtherCAT there is no such thing as a harmless read. Bringing up a master broadcasts every device on the segment back to INIT, blanks all sixteen FMMUs and all sixteen sync managers, blanks the distributed clock configuration, and overwrites every configured station address. On a running machine that is not a read. That is a stop, and it discards the plant master's configuration on the way out.

That is not a quirk of any one implementation. It is what EtherCAT is: one master per segment, the master owns the wire, and there is no client seat to sit in. Modbus and OPC UA let you dial a device that is already serving other people and ask it a polite question. EtherCAT has no equivalent, and anyone carrying Modbus intuition across will eventually stop a line with something they thought was a read.

It is why our EtherCAT tools are split in two. Broadcast and auto-increment register reads, which change nothing, are the ordinary path. Anything that takes the bus is compiled out by default and sits behind a permission tier that cannot be waived.

The limitation people test first, so here it is up front: those tools observe a segment. Your application is still the master.

So, what did you pick

If you are shipping a machine you own end to end, take IgH and do not overthink it. If you are shipping software onto hardware you do not control, the kernel module and the licence will decide it for you before the feature tables get a vote.

Oasis CLI is free, runs on the machine rather than your laptop, and works with your own local models. It is at /oasis-cli if you want a look.

More from the blog

See it on your own hardware

Talk to us about a private cloud deployment for your team.

Talk to Sales

← All posts