Rack Maker

Docs
Catalog

Authoring parts

Write a catalog entry in the catalog editor, from a quick device to a full part with sockets, checks and expressions; attach model files and add listings.

Two ways to add hardware

  • Model a device opens the device modeler. It is the easiest way to add a device you own: it builds the entry, and its 3D model, from measurements and a photo.
  • New part opens the catalog editor, described here. Use it for anything else (shelves, trays, mounts, brackets, panels, racks) or when you want full control over an entry's definition.

Both buttons are at the top of the catalog. You need to be signed in.

The catalog editor

The editor at /catalog/new has four parts:

  • New device: the quick way in. Give a Name, a Namespace (your handle), a Description, and the Width, Depth and Height in mm. This fills in the definition for a box-shaped device that stands on shelves and trays. The id is shown below the form, made from the namespace and the name.
  • Definition: the entry as JSON. Edit it directly for anything the quick form doesn't cover, or paste a whole entry. The card's title says valid, or how many issues there are, and each issue is listed with the field it is about.
  • Preview: the entry in 3D with its default values, updated as you type.
  • Model file: upload a GLB or STL to draw the part with (contributors only; see Model files).

Save draft keeps the draft in your namespace. Submit for review saves it and sends it for review in one go. Both are available once the definition is valid. To change a saved draft later, use Edit on its row on the entry's page. See Entries and revisions.

The catalog editor.

Start from an existing entry

The quickest way to write a part is to copy one that is close. Every entry's page has a Definition card with its full JSON. Copy it into the editor, change the id to your namespace, set rev to 1, and adjust from there. Keep the original's attribution and add yours.

A worked example

A printed 1U tray for a 10″ rack, holding one mini PC:

{
    "id": "alice/mini-pc-tray",
    "rev": 1,
    "kind": "part",
    "name": "Mini PC tray (1U)",
    "category": "tray",
    "params": [{ "key": "depth", "label": "Depth", "kind": "length", "default": 160, "min": 80, "max": 220 }],
    "derived": {
        "units": 1,
        "faceH": { "expr": "U19 - 1.25" },
        "devH": { "expr": "on.deck.count > 0 ? on.deck.h : 0" }
    },
    "envelope": { "w": 250, "d": { "expr": "depth" }, "h": { "expr": "faceH" } },
    "plugs": [
        {
            "id": "ears",
            "provides": "rail/10in/eia",
            "frame": { "at": [125, 3, 0] },
            "occupies": { "kind": "linear", "span": { "expr": "max(1, round(units * U19 / host.pitch))" } }
        }
    ],
    "sockets": [
        {
            "id": "deck",
            "label": "Deck",
            "accepts": [{ "iface": "surface/flat" }],
            "frame": { "at": [18, 3.6, 3] },
            "shape": { "kind": "surface", "w": 214, "d": { "expr": "depth - 6" } },
            "capacity": 1
        }
    ],
    "geometry": {
        "kind": "generator",
        "id": "core/faceplate-tray@1",
        "args": { "faceH": { "expr": "faceH" }, "plateD": { "expr": "depth" } }
    },
    "constraints": [
        {
            "id": "height",
            "level": "error",
            "title": "Device fits under the next tray",
            "when": { "expr": "on.deck.count > 0" },
            "assert": { "expr": "devH + 3 <= faceH" },
            "message": "{fixed(devH, 1)} mm device in a {fixed(faceH, 1)} mm (1U) tray",
            "blocksFabrication": true
        }
    ],
    "fabrication": { "method": "fdm", "material": { "default": "PETG" } },
    "license": "CC-BY-SA-4.0",
    "attribution": [{ "name": "alice", "role": "author" }]
}

What each part of it does:

  • The plug ears says the tray mounts on 10″ EIA rails. Its frame is the point that lands on the rails' socket: the middle of the faceplate, 3 mm back. Its span uses the host's pitch, so it takes one position on a whole-U rack and two on the half-U RackMate T0.
  • The socket deck accepts anything that stands on its feet (surface/flat). Devices dropped on it are placed by x and y in millimetres, and can be centred across it.
  • derived values are worked out once per part in a project, and anything below can read them. on.deck.h is the height of whatever sits on the deck, or 0 when it is empty.
  • The constraint shows up in the project's checks. With blocksFabrication, a failing check holds back the STL export until the user overrides it.
  • geometry draws the tray with one of the app's built-in generators. Without geometry, a part is drawn as its envelope box.

Entry reference

FieldWhat it is
id, rev<namespace>/<slug> in lowercase, and the revision number (see Namespaces)
kindpart (one thing) or assembly (made of other entries)
name, description, tagswhat people see and search for
categoryrack, frame, rail, shelf, tray, mount, printed, device, power, fastener, panel, accessory or material
paramsvalues users can edit in the inspector: length, angle, count, number, boolean, enum, string; measurable adds a "measured" toggle
derivedcomputed values (expressions)
envelopethe bounding box w × d × h in mm, from the part's own origin (left, front, bottom); parts only
plugs / socketshow parts attach (below)
constraintschecks: level (error, warning or info), when, assert, message or failMessage, order, blocksFabrication
kpisheadline numbers for the project's summary row: value, detail, tone (ok, warn or bad)
propsfacts such as mass, power, heat, airflow and ports
geometryhow it is drawn: envelope (a box), generator (a built-in generator and its arguments), mesh (an uploaded model file; fit: "envelope" scales it to the envelope) or composite
fabricationmethod (fdm, sla, laser, cnc or bought), material, estimate (filament and print time), and for printable parts the generator and its export values
bomhow it appears in the BOM: self (the default for parts), children (list its parts instead), all (both: a shelf and its screws) or none
collisionnone leaves the part out of the overlap check (rails inside posts, parts that hook over an edge)
childrenfor assemblies: each child's ref (id and rev), its params, where it goes (at or mate), repeat, when and locked
licensealways CC-BY-SA-4.0 for catalog entries
attributionwho made or measured the entry: name, role (author, contributor, measured or forked-from), url (their page), source (where the facts come from), permission (where the author allowed the use)

When you save, you are added to attribution as a contributor if you aren't there already.

Sockets and plugs

A part's plug fits another part's socket when the plug's interface id matches one of the socket's accepts patterns. A pattern ending in /* matches any id that begins with it: rail/10in/* accepts rail/10in/eia.

A socket has a frame (where it is on its part), a shape and the interfaces it accepts. The shapes are:

  • linear: positions along an axis (pitch, count, origin0). Rails are linear, running up the rack. A plug's occupies.span says how many positions it takes, and overlaps are reported.
  • surface: a w × d area. Parts on it are placed by x and y in mm.
  • grid: nx × ny cells at pitchX and pitchY (pegboards, hole grids).
  • point: exactly one place.

capacity limits how many parts a socket takes. An accept may add a where expression, for example to accept 19″ parts only when the rack's standard is 19in.

The interfaces in use today:

InterfaceWhat it is
rail/10in/eia10″ rails with the EIA-310 hole pattern. Panels up to 254 mm wide. The rack gives pitch: a whole U on most racks, half a U on the RackMate T0.
rail/19in/eiathe same pattern on 19″ rails: 482.6 mm panels
rail/deskpi-tl1RackMate TL1 rails, with holes evenly spaced in thirds of a U. Not EIA-310: TL1 parts don't fit generic 10″ rails, and the other way round.
caddy/deskpi-tl1-topthe TL1 top plate between the carry handles
post-leg/deskpi-tl1the rear leg of a TL1 post, which the cable comb clip grips
surface/flata flat deck that carries something standing on its feet: shelves and trays offer it, every device uses it
post/wire-shelving-1ina wire shelf's collars on 1″ round posts, clamping at any 1″ groove
fan/80mman 80 mm fan lying on a floor grille

Two parts should fit only when they really do. If your part is mechanically different from what an interface describes, don't reuse that interface.

Racks that are only a model file

A rack can be drawn entirely by an uploaded GLB or STL. Give the entry an envelope and declare its rail socket yourself: the rails' frame sits on their centre line, just in front of the flanges, at the bottom of U1. The entry cbnsndwch/rack-19in-12u-mesh is an example to copy.

Expressions

Wherever a number, a true/false value or a text is allowed, you can write an expression instead, as { "expr": "…" }. Text fields (title, message, detail) take expressions in curly-brace holes, like the message in the example above.

  • Operators: + - * / %, comparisons, && || !, a ? b : c, and text in single quotes.
  • Functions: min, max, abs, floor, ceil, round(x[, decimals]), clamp(x, lo, hi), sqrt, sin, cos, tan and atan2 (in degrees), hypot, near(a, b, tol), fixed(x, decimals) (as text), and ulabel(pos, perU) (a rail position as a U label).
  • Constants: U19 (44.45 mm, one rack unit) and PI.
  • Names:
    • a bare name is the part's own param, derived value, exposed value, envelope size (w, d, h) or name;
    • parent.x is the enclosing assembly, root.x the project's top part, and host.x the part whose socket this one is mounted on;
    • child.<id>.x reads a child of an assembly (the first one, when it is repeated);
    • on.<socket>.x reads the first part on a socket, or 0 when it is empty;
    • on.<socket>.count, top, used, overlaps, tallest and n.<category> summarise a socket (tallest is the height of the tallest part on it);
    • mate.pos is this part's position on its socket.

A mistake in an expression doesn't break a project. It shows up in the project's Problems card, naming the entry and the field it came from. Loops between values are reported the same way.

Printable parts

A part whose fabrication names a printable generator can be exported as an STL from a project. The printable generators are built into the app, so you can use the ones that exist but not add your own. See Exports and printing.

Model files

A model file draws a part from a 3D file instead of a generator or a box. Uploading one needs contributor access.

  • Formats: GLB (binary glTF) or STL. glTF is read Y-up with the front facing +Z; STL is read Z-up, in millimetres.
  • Size: up to 15 MB.
  • Scale: files come in any unit, so Scale the model to fit the part's size is on by default. It scales the model evenly to fit the entry's envelope, centred and standing on its floor.

In the Model file section of the catalog editor, choose the file, then fill in where it comes from:

FieldNotes
Who made the modelI made it or Someone else made it
LicenceCC0 1.0, CC BY 4.0, CC BY-SA 4.0, CC BY 3.0, CC BY-SA 3.0, MIT or Apache 2.0
Title, author, source pagerequired when someone else made it; the author defaults to you when you made it
Author pageoptional: a link to the author's profile
Model sitewhen someone else made it: where you found it, such as Sketchfab or Printables
Changes madeoptional: what you changed from the original (Creative Commons licences ask for this)
Acknowledgementsoptional: the credit or licence notice the author asks for, thanks, upstream notices

Tick I may share this file under this licence, and the credits above are complete, then Upload and attach. The file becomes the entry's geometry. Save the draft to keep it.

Only upload files you may share under one of those licences. For anything else, link to the page it is on (in the entry's description, for example) instead of uploading it.

The same file uploaded twice is stored once. Upload your own file again to correct its licence or credits. If someone else uploaded it first, their upload and credits are used.

Each model file's licence and credits appear on the entries that use it and on the Credits page. See Licences and credits.

Listings

Listings say where to get a part: online shops and physical stores, each with a dated price and stock report. They feed the BOM & quote. Anyone can see them on an entry's Where to get it card; adding them needs contributor access.

To add one, fill in the form at the bottom of Where to get it:

  • Online shop or Physical store, and the shop or store's name.
  • For a shop, the product page (required). For a store, its address or city (required), and optionally its page.
  • Optionally a price with its three-letter currency (such as USD or EUR), the pack size (items per purchase), and the stock: in stock, few left or out of stock.

Then Add listing. Later, contributors can add a New price or report the stock on any listing. Prices and stock reports are dated, and a price older than 90 days is marked as stale.

Checklist before submitting

  • Dimensions come from a datasheet, a drawing or calipers. Say which in the description, or in a parameter's hint.
  • The interfaces you use describe how the part really mounts.
  • The part behaves in a project: it mounts, its checks read sensibly when they pass and when they fail, and it doesn't collide with its neighbours when it shouldn't. Your draft works in your own projects, so try it there first.
  • Model files are yours to share, or carry an allowed licence with full credits. Otherwise link to them instead of uploading.

Limits

  • An entry's definition can be up to 128 KB.
  • You can make up to 120 catalog changes (saving, submitting, deleting) in 10 minutes.
  • Contributors can upload up to 30 model files an hour.

On this page