Tags · Module

Custom Structures

The catalog of UDTs and Add-On Instructions every generation module reads from. Browse the system defaults included with every account, or (on Pro and above) upload your shop's structures from an L5X and have the generators target them. Every edit is kept as a version you can diff and pin.

Pro + Free Updated Aug 8, 2026 7 min read
UDT + AOI
Both structure types
Versioned
Every revision diffable and pinnable
9
Tag categories
Pro+
Required to upload or create
The 2-minute path

These four steps produce an L5X ready for Studio 5000 import. The full guide below covers every option in detail.

  1. 1 Browse · Filter by scope, category, and type. System structures are read-only.
  2. 2 Add · Upload an L5X or build one in the editor, then bind members to generator slots. Pro+.
  3. 3 Version · Compare any two revisions and pin the one generation should use.
  4. 4 Consume · I/O Code, Alarm Code, and Parameter Code pick from the library automatically.

Overview

Custom Structures is the catalog of User-Defined Types and Add-On Instructions that PLCflow’s generation modules read from. When I/O Code emits a motor instance, it references the matching UDT from the library and calls the matching AOI. When Alarm Code emits an alarm, it references an ALARM-category UDT. When Parameter Code emits a setpoint, it references a PARAMETER-category UDT.

System structures are included on every account (UDT_MotorSimple, UDT_MotorVFD, UDT_ValveDiscrete, UDT_ValveAnalog, UDT_SensorAnalog, UDT_Setpoint, ALARM_UDT, and the matching AOI_* instructions) and cover the common device classes. Uploading your own structures from L5X, or building them in the editor, requires Pro. Free-tier accounts can browse and use the system structures but cannot add their own.

Step 1. Browse the library

Open Custom Structures from the sidebar. The page is a table with one row per structure, columns: Name, Category, Type, Members, Scope, Description, and row actions.

The Members count reads as members for a UDT and as parameters for an AOI, since that is what each type actually carries.

Three filters sit at the top:

  • Scope. Personal, or one of your Projects or Organizations. Project and Organization workspaces require a Geek plan; they are listed for everyone and locked below that tier. Personal structures are visible only to you. A Project or Organization structure is visible to everyone with access to that workspace, which is how a team shares one approved set.
  • Category. One of DI, DO, AI, AO, VALVE, MOTOR, VFD_MOTOR, ALARM, PARAMETER, or All. The category determines which generation module’s dropdown surfaces the structure.
  • Type. UDT, AOI, or All.

Small badges next to a name carry the details worth noticing at a glance:

  • A version badge such as v3/v5 means generation is pinned to revision 3 while revision 5 is the latest. See version history.
  • A link icon means an AOI is paired with a UDT, so generating it also emits the companion tag.
  • A warning triangle means a standalone AOI has parameters with nothing bound to them. Generated code would contain a broken placeholder until you open it and bind them.

Click any row’s Name to open the details dialog. For a structure you own this opens in edit mode. For a System structure it opens in view mode: you can read the structure and adjust default values on each member, but cannot rename or remove members.

Step 2. Add a structure

Pro and above. The Upload and New buttons are only available on the Pro plan and above. The system structures remain usable on the Free tier; you just can’t add your own.

Upload

Click Upload in the top-right. The dialog accepts a single .L5X file, and works for both structure types: PLCflow reads the file and detects whether it is a UDT or an AOI export. The type is shown back to you, and uploading a file as the wrong type is rejected rather than silently mangled.

In the dialog:

  1. Drop or browse for the .L5X file (UDT export, AOI export, or a program export containing either).
  2. Confirm the detected Type, or set it explicitly.
  3. Set the Category. It determines which generation module sees the structure.
  4. For an AOI, choose Paired or Standalone (see below).
  5. Optionally set a Name Override to rename the structure during import.
  6. Click Upload.

Paired and standalone AOIs

An AOI can be uploaded in one of two shapes:

  • Paired. Generating the AOI also emits a companion tag typed by a UDT. PLCflow detects the companion from the file, or you can pick a specific UDT of the same category. This is how the system instructions work: AOI_MotorSimple is paired with UDT_MotorSimple.
  • Standalone. Generating emits one AOI-typed tag and nothing else.

A standalone AOI takes its parameter values from bindings you set on the structure itself. Leave those unbound and the row shows a warning triangle, because the generated call would contain a placeholder instead of a real tag reference.

New

Click New to open the editor with a blank structure. The dialog has three sections:

  • Identity. Name (must be unique within scope), Category, Description.
  • Required Fields. Generator slots specific to the selected Category (see below).
  • All Members. The full member list: name, data type (BOOL, BIT, DINT, INT, SINT, REAL, STRING, TIMER, COUNTER), default value, description, required flag.

Click Add Member to append a row, then save when done.

Binding members to generator slots

Each Category has a set of generator slots the modules need filled. For example, a MOTOR-category UDT needs members bound to the “run command”, “run feedback”, and “fault” roles. The dialog shows these slots in a Required Fields panel with a dropdown next to each one; pick which of your members fills each slot. Required slots show an orange marker; optional ones are grey.

Validation runs on save: a required slot left unbound blocks the save with a message naming the missing slot. Members not bound to any slot are kept as internal and emitted as part of the structure but not driven by the generator.

Step 3. Edit existing structures

For structures you own, click the pencil icon on the row. The dialog opens in edit mode. You can rename members, change data types, add or remove members, rebind slots, and update defaults.

For System structures, the pencil is disabled. Clicking the Name opens the dialog in view mode. You can still save per-account default values for the system structure’s members, but the structure itself cannot be modified.

Click the trash icon to delete a structure you own. The confirmation dialog warns that tags referencing it will be orphaned. Saved generation sessions that reference the structure will fail to load cleanly until you fix the reference.

The star icon sets a structure as the default for its category and type, which is what generation reaches for when a row doesn’t name one explicitly.

Step 4. Version history

Every structure keeps its full revision history. Versions are recorded automatically when you edit a structure, and when you upload a new file over an existing one with the Upload new version action on the row.

Click the history icon on any row to open it. The dialog lists revisions newest first, each with a short summary of what actually changed in it, and works the way a pull request diff does: pick a base version and a compare version, and the diff below shows the change line by line.

History is available on System structures too, which is how you see what changed when PLCflow updates one.

Pinning the version generation uses

Each structure has one pinned revision, which is the one generation actually reads. By default it follows the newest: add a revision and the pin moves with it, so the common case needs no thought.

The Use button on any revision pins that one instead. Once you have pinned an older revision deliberately, later uploads no longer move it. That is what makes a controlled rollout possible: upload a revised UDT, diff it against what you have been shipping, and keep generating against the approved revision until you are ready to switch. When a structure is pinned to anything other than its latest revision, the row shows a v3/v5 style badge so the state is visible without opening anything.

Step 5. Using the structures

Every generation module reads structures of the matching category at run time:

  • I/O Code reads MOTOR, VFD_MOTOR, VALVE, AI, AO structures for each device row. The UDT column dropdown on each row in the editor lists every available structure for that device type. Free tier uses the system structures (UDT_MotorSimple, UDT_ValveDiscrete, and the rest); Pro+ uses your own uploads in addition.
  • Alarm Code reads ALARM-category UDTs. Default is ALARM_UDT; Pro+ accounts can pick custom alarm UDTs that share its role structure.
  • Parameter Code reads PARAMETER-category UDTs. Default is UDT_Setpoint; Pro+ accounts can pick custom setpoint UDTs with extra members (engineering units, scaling fields).

To change a structure, edit it here. The next generation run picks up whichever revision is currently pinned, which is the latest one unless you pinned an earlier one deliberately. Already-downloaded L5X files have the old structure baked in; re-generate to refresh.

Common pitfalls

  • Wrong Category on the structure. Categories are scoped per device class. A structure in the MOTOR category will not appear in the VALVE row’s dropdown. If your custom structure shows up in the library but not in the editor’s UDT column for the device you expected, this is usually why.
  • Required slot left unbound. The save button stays disabled until every required generator slot has a member bound. The dialog names the specific slot; pick a member from its dropdown and the validation clears.
  • A standalone AOI with unbound parameters. The row shows a warning triangle and the generated call carries a placeholder rather than a tag. Open the structure and bind every parameter, or upload the AOI as paired so the companion UDT supplies them.
  • Expecting an edit to reach generation while an old revision is pinned. If the row shows a v3/v5 badge, generation is still using revision 3. Open the history and click Use on the revision you want.
  • Renaming a member used by a saved session. Saved generation sessions capture the structure name plus the row’s reference. Renaming a structure or changing its shape can break a previously-saved session’s load. Re-save sessions after major changes.
  • Treating system defaults as immutable. Click a system structure’s name to open it in view mode and tweak member defaults. This customizes it for your account without duplicating it.

FAQ

How many structures can the library hold?

There is no hard limit. Most accounts have under 30. The scope, category, and type filters keep the list usable as the count grows.

Can I share custom structures across team members?

Yes. Save a structure to a Project or Organization scope instead of Personal, and everyone with access to that workspace sees it and can generate against it. Project and Organization workspaces require a Geek plan or above. Personal-scope structures stay visible only to you.

What's the difference between a UDT and an AOI here?

A UDT is a data structure: the tag shape a device gets. An AOI is an Add-On Instruction: the logic that runs against it. Most device types use both, paired together, so generating a motor emits a UDT_MotorSimple-typed tag and an AOI_MotorSimple call on the rung. The library holds both, and you can bring your own of either.

Does the library support nested UDTs (a member with type = another UDT)?

The editor’s data type dropdown is limited to Logix primitive types (BOOL, BIT, DINT, INT, SINT, REAL, STRING, TIMER, COUNTER). Nested UDT references come through on L5X upload (PLCflow preserves them), but you can’t choose another UDT as a member type when building from scratch in the editor.

Can I import structures from an Ignition JSON file?

Not directly. The upload dialog accepts .L5X only. For the Ignition JSON to Rockwell direction, the backend supports the conversion but the UI does not currently expose the JSON intake; reach out at [email protected] if you need it unblocked.

What happens to old generations when PLCflow updates a system structure?

Already-downloaded L5X files have the old structure baked in. New generations use whichever revision is pinned. Open the system structure’s version history to see exactly what changed between revisions, and pin an earlier one if your shop needs a frozen baseline.

What's next

Related modules

Was this helpful?

Honest feedback. We read all of it.

Try Custom Structures on real data

Free tier, no credit card. Bring a real spreadsheet, see what comes out.