STRUC++
The open-source Structured Text compiler behind OpenPLC.
STruC++ compiles IEC 61131-3 Structured Text into clean, readable C++14. It ships with a built-in unit testing framework, an interactive REPL and a reusable library system, in a single binary.
- 29K+
- Downloads of the compiler
- 60+
- Releases since launch
- 85+
- Stars on GitHub
- Native
- Machine code, no interpreter at runtime
Why a new compiler
For two decades, virtually every open-source PLC project depended on a single compiler, limited to the second edition of IEC 61131-3 and generating macro-heavy C. When we rebuilt OpenPLC as v4, the compiler was the last piece left from the old stack. STruC++ is its replacement, written from scratch.
What makes it different
Readable C++, not macros
Function blocks become classes, interfaces become virtual methods and generics become templates. You can read the output, debug it and link it into an existing C++ project.
Unit tests in ST
The test runner is built into the compiler. Write TEST blocks with assertions, mocks, SETUP/TEARDOWN and simulated time, and run them on any machine with no PLC attached, ideal for CI pipelines.
Interactive REPL
Build a program with --build and step through it: set inputs, run cycles, inspect and force variables, and view the ST and the generated C++ side by side.
Zero runtime dependencies
The compiler is a single binary and the C++ runtime is header-only. Nothing else to install on the target.
Structured Text in, C++ out
A function block becomes a C++ class with its inputs and outputs as members and its logic in a call operator.
FUNCTION_BLOCK Counter
VAR_INPUT
enable : BOOL;
reset : BOOL;
END_VAR
VAR_OUTPUT
count : INT;
END_VAR
IF reset THEN
count := 0;
ELSIF enable THEN
count := count + 1;
END_IF;
END_FUNCTION_BLOCKnamespace strucpp {
class Counter {
public:
IEC_BOOL enable;
IEC_BOOL reset;
IEC_INT count;
void operator()();
};
void Counter::operator()() {
if (reset) {
count = 0;
} else if (enable) {
count = count + 1;
}
}
} // namespace strucppLanguage coverage
A broad subset of IEC 61131-3 Edition 3, plus common extensions used across the industry.
Data types
Every elementary type including 64-bit integers, strings and L-variants of time and date, plus arrays, structs, enums and subranges.
POUs and variables
PROGRAM, FUNCTION, FUNCTION_BLOCK and INTERFACE, with inputs, outputs, globals, constants, RETAIN and located variables.
Object orientation
Methods, properties with GET and SET, EXTENDS, IMPLEMENTS, ABSTRACT, FINAL, OVERRIDE and access modifiers.
Pointers and references
POINTER TO, REF_TO, REFERENCE_TO, ADR, dereferencing and dynamic allocation.
Standard library
Over 80 standard functions plus timers, counters, edge detectors and bistables. The OSCAT Basic library compiles out of the box.
Project model
CONFIGURATION, RESOURCE and TASK, with program scheduling.
Runs where you work
Command line
Standalone binaries for Linux x64 and ARM64, macOS Intel and Apple Silicon, and Windows x64.
In the browser
Also a JavaScript and TypeScript library with no native dependencies, for Node.js, browsers, Deno and Bun.
In VS Code
The STruC++ extension brings real-time diagnostics, autocomplete, go to definition and debugging to Structured Text.
On microcontrollers
The output targets C++14 so it builds with the toolchains Arduino boards ship with, down to avr-g++ 7.3.
Open source, and your programs stay yours
The compiler is licensed under GPL-3.0. The C++ runtime and standard libraries carry the STruC++ Runtime Library Exception, so the programs you compile can be distributed under any license.
Try STruC++
Download a release, compile your first ST file and run its tests, no PLC required.

