The open text format for truss models. The Project code panel, the format, and every field.
Last updated 2026-10-11
Project code is your truss written as text (JSON). It's what you get when you copy on the canvas, and what the Project code panel shows. This guide explains the panel and the format. For what to do with it, see:
Open Project code from the panel on the right. It shows your whole model as text, and follows your changes on the canvas.
The document is one JSON object with these keys: units, nodes, members, supports, nodalLoads, materials,
sections, and an optional dimensions. Nothing else is allowed — Truzme keeps more than this behind the scenes
(view settings, background images, uploaded assets), but none of that appears here.
A document may also start with an optional $schema key: the link to this format, so the text says what it is
wherever it's pasted. Code copied from the canvas starts with it. Truzme ignores it when you press Apply, and
drops it when you paste into the Project code panel.
Writing AI prompts with your own instructions, for a course or a research study? Link the format itself. Unlike the format guide, it has no instructions for the AI — only a description of every field below:
idEvery entity has a small integer id. Anything that points to another entity — a member's endpoints, a support's or
load's node, the section and material assigned to a member — does so with that id. Ids only need to be unique
within their own array, so a node id: 1 and a section id: 1 don't collide.
unitsEvery category the document uses, all required:
length — node coordinates: m, cm, mm, ft, insectionLength — section dimensions: mm, cm, inforce — loads: kN, N, kg, kip, lbfmaterialStrength — modulus and strength: MPa, N/mm², GPa, ksi, psiarea — section area and, indirectly, its moment of inertia: mm², cm², in², ft²density — material density: kg/m³, lb/ft³This block is authoritative on import: Apply reads the units declared here — not whatever Truzme is currently
displaying — and converts every number accordingly. length and sectionLength are different categories on
purpose: a node coordinate and a section dimension are rarely the same scale.
nodes{ id, x, y } — x/y are coordinates in units.length. x increases to the right, y increases upward —
the standard math convention, not screen coordinates. A node above and to the right of the origin has positive x
and positive y.
members{ id, from, to, section, material } — from/to are node ids for the member's two ends; section/material are
ids into the sections/materials arrays.
supports{ id, node, x, y, angle } — node is the restrained node's id; x/y are booleans, true meaning translation is
fixed in that direction.
angle is optional: it turns the support, in degrees, counterclockwise, and its x and y directions turn with it. A
roller with "y": true and "angle": 30 stands on a surface tilted 30°, so it holds the node only across that surface.
On a pin it only changes how the support is drawn. Leave it out for 0.
nodalLoads{ id, node, x, y, mode } — node is the id of the loaded node; x/y are signed force components in
units.force. mode is optional and only changes how the arrow is drawn, not the analysis. Leave it out for "push",
where the arrow points at the node. Use "pull" for a load hanging from the truss, e.g. on a bottom chord node: the
arrow then starts at the node and points away, so it isn't drawn across the members.
materials{ id, name, EModulus, fMax, density, color } — modulus and max stress, both in units.materialStrength; density in
units.density. color is optional (a hex string, e.g. "#1D4ED8") — leave it out and an existing material keeps
its current color, a new one gets a default. Include it to set or change a material's color.
materials and sections can't be empty arrays — every model needs at least one of each, even one with no members
yet. Apply rejects a paste that has none of either.
sections — a union of five shapesEvery section has id, name, sectionType (which decides which other fields are required), and an optional
color — same rule as a material's color: leave it out to keep whatever a matching id already has, include it to
set one.
solid_round — d (diameter)pipe — outerDiameter, thicknessrectangle — w, hhollow_rectangle — w, h, thicknesscustom — area, Imin (nothing to derive these from, so they're given directly)All dimensions are in units.sectionLength; area and Imin on a custom section are in units.area and its
matching inertia unit (mm² area → mm⁴ inertia, in² → in⁴, and so on).
For the four standard shapes, Truzme computes area and Imin on import from the input dimensions — you only ever
provide those dimensions, never the derived values, so there's one source of truth. The exported text doesn't show
computed area or inertia for standard shapes; check the Utilization panel in Truzme for those.
dimensions — optionalThe measurement lines you draw with the Dimension tool (not to be confused with a section's own w/h/d
dimensions above). Leaving the key out is the same as an empty list: no dimension lines.
{ id, from, to, kind, anchor } — from/to are node ids, same convention as a member's from/to. kind is
"horizontal", "vertical", or "angle". anchor is a point ({ x, y }, in units.length) the line is drawn
through — it's the point you click when placing a dimension with the tool.
When you ask an AI for a design with a specific span or height, it's worth asking it to add a dimension line confirming that measurement — the format guide tells it to do this on its own whenever a prompt states one.
Your display preferences (not to be confused with the units block above, which is part of the public document),
background images, uploaded asset files, and Truzme's internal bookkeeping don't appear here — none of it describes
the structure, so none of it needs to go through an AI.
A three-node, three-member truss: a pin support and a roller, one downward load at the apex, a custom color on the material and section, and a dimension line confirming the 4 m base span.
{
"units": {
"length": "m",
"sectionLength": "mm",
"force": "kN",
"materialStrength": "MPa",
"area": "mm²",
"density": "kg/m³"
},
"nodes": [
{ "id": 1, "x": 0, "y": 0 },
{ "id": 2, "x": 4, "y": 0 },
{ "id": 3, "x": 2, "y": 3 }
],
"members": [
{ "id": 1, "from": 1, "to": 2, "section": 1, "material": 1 },
{ "id": 2, "from": 1, "to": 3, "section": 1, "material": 1 },
{ "id": 3, "from": 2, "to": 3, "section": 1, "material": 1 }
],
"supports": [
{ "id": 1, "node": 1, "x": true, "y": true },
{ "id": 2, "node": 2, "x": false, "y": true }
],
"nodalLoads": [{ "id": 1, "node": 3, "x": 0, "y": -10 }],
"materials": [{ "id": 1, "name": "Steel", "EModulus": 210000, "fMax": 235, "density": 7850, "color": "#1D4ED8" }],
"sections": [
{
"id": 1,
"name": "40×40×3",
"sectionType": "hollow_rectangle",
"w": 40,
"h": 40,
"thickness": 3,
"color": "#9D57DE"
}
],
"dimensions": [{ "id": 1, "from": 1, "to": 2, "kind": "horizontal", "anchor": { "x": 2, "y": -0.75 } }]
}color and dimensions are both optional — see the schema reference above if you want to leave them out.
Ask an AI to move node 3, add a fourth node, or swap the section on member 2 — it only has to keep ids consistent and never invent an id that isn't defined.
Apply matches ids. When you press Apply in the panel, an id that already existed in your model keeps the same entity across the round-trip — its place in undo history, its selection state, and its color unless the pasted entity sets a new one. Only ids you didn't have before get created as new entities, and ids that are missing from the pasted code are removed. This is why an AI editing your project code should send back the whole model, keep existing ids stable, and only introduce new ones for things it's actually adding.
Units convert automatically. The numbers you paste are read in whatever units the pasted units block declares,
then converted to Truzme's internal representation — you don't need to match your current display units before
pasting.
Project code was developed in collaboration with a research team at Penn State University, USA, who needed a text format an AI could read and write — so a truss design could be generated and revised in a chat and then loaded straight back into Truzme.
See Who uses Truzme for more about their work with Truzme.
Thanks to Ali Tarlani Beris for starting the conversation.
Free to implement in any tool. Please name it "Truzme Project code" and link to this page. How to do it: Connect your app. Details: License.
Text and figures: CC BY-NC-ND 4.0. Free to use in class with a link to this page. Details: License.
Back to guides