Blog / How to Build a Custom Baluster Family for Revit Railings

How to Build a Custom Baluster Family for Revit Railings

A worked walkthrough of authoring a custom baluster family in Revit from the Metric Baluster template, then driving a stair railing with it, with timestamps.

M
Manish Simon
· 22 min read

Go deeper with Archgyan Academy

Structured BIM and Revit learning paths for architects and students.

Explore Academy →

Every Revit project reaches the moment where the railing stops being a background object. The stair is in the atrium, it is on the visual, and the architect has drawn something the out-of-the-box railing types cannot produce. At that point most teams do one of two things. They fake it with a curtain wall or in-place model and lose every schedule and every tag, or they push a system baluster to its limits and accept a railing that looks nothing like the design.

There is a third option, and it is far less work than it sounds. Revit ships a family template whose only job is to produce balusters, and a second one whose only job is to produce the rail profiles that run along the top. Author those two families once, and the railing becomes a properly parametric assembly that schedules, tags, hosts, and flexes like any other Revit content.

The walkthrough below follows a recorded build from the Archgyan Revit channel, linked at the exact moment each step happens. It produces a minimal U-section baluster that sits one-per-tread on an open stair, and a matching rectangular top rail. If family authoring is new to you, the Revit family creation fundamentals guide covers the theory underneath this, and the parametric door family and parametric window family walkthroughs cover sweeps and extrusions in more detail than a railing post has room for.

Start in the Metric Baluster template, not Generic Model

The build opens at File, New, Family and picks the Metric Baluster template. That choice happens in the first twenty seconds, and like every family template decision it is the one you cannot undo cleanly later.

A baluster template family belongs to the Railings category and appears in the Baluster Family list inside a railing type’s Baluster Placement dialog. Author the same geometry in Generic Model and it will not appear in that list at all. You will have a nice-looking object that Revit refuses to array along a railing path, and no setting anywhere in the family or the project will repair that. This is the single most common way a custom baluster build goes wrong, and it goes wrong before any geometry exists.

The other thing worth doing in the first minute is reading what the template already gives you. The reference planes that ship with the template are explained straight away: the planes at the top and bottom control how the 3D element gets cut so the baluster reads correctly when it lands on a stair rather than a flat landing. You are not meant to delete them or reposition them casually. You are meant to build against them.

Reference planes and dimensions before any geometry

The baluster in this build is a U-section that runs down one side, across, and back up. To make that shape flex, it needs a horizontal spine of reference planes to hang off.

Two new reference planes go in first, one left and one right, drawn with the RP shortcut or from the Create tab. Then dimensions go on with DI: left to centre, centre to right, an EQ equality constraint across the pair, and one overall dimension labelled to a new parameter called Width.

That EQ constraint is the part people skip, and it is the part that does the work. Without it, changing Width pushes only one side of the U outward and the section stops being symmetrical about its own centre. With it, the two halves stay locked to each other and the family flexes about the centre plane forever. Type a new Width, and both legs move.

A third reference plane goes in above the profile, offset roughly 150 from the top. This one is deliberately not parametric. It exists purely as the plane the void extrusion will cut back to, and making it a labelled parameter would add a dimension to the family types dialog that nobody will ever want to change.

The same treatment then happens in the floor plan view. Reference planes and dimensions go in for the section itself, producing two more parameters: Section Width and Section Depth. These control the thickness of the bar, not the span of the U, and separating them from Width is what lets you produce a delicate 6 mm blade and a chunky 12 mm one from the same family.

Strong references, weak references, and why the order matters

Dimension to reference planes, not to model edges. A dimension attached to the edge of a sweep is attached to something Revit is free to regenerate, and the moment the sketch changes the constraint breaks with a warning you will not read. A dimension attached to a named reference plane survives every geometry edit you make afterwards.

This is the same discipline the door and window builds use, and it is why the geometry step in all three is short. By the time the sweep is drawn, every dimension it needs to obey already exists.

Set your working values before you sketch

Before any 3D work, the family types dialog gets opened and the section values get set: Section Depth to 6 and Section Width to 25, because the template defaults draw a section far too heavy for the intended look.

That sequencing matters more than it appears. Sketching a sweep at one size and then flexing it hard to another is where families break, because the sketch lines pick up snapping constraints at the size you drew them. Setting the values first means the sketch is drawn at roughly the size it will live at, and the flex afterwards is a small adjustment rather than a violent one.

Treat those two numbers as this designer’s values, not as anything a code requires. Balustrade infill spacing, loading, and the gap rules that determine whether a design passes are set by the building regulation in force on your project, not by a family template. The family gives you the parameters. The compliance case is yours.

The sweep, and the snap that keeps it parametric

With the skeleton in place, the sweep gets created from the Create tab. A sweep needs two sketches, a path and a profile, and Revit asks for a work plane before either.

The path is sketched with the Line tool as a U: start at the top of one leg, down, across, and back up. The important detail is not the shape, it is what happens at each vertex. SI, the snap-to-intersection override, gets tapped before each click so the line endpoint lands exactly on the intersection of two reference planes rather than merely near it.

This is called out explicitly at the end of the path sketch, and it deserves the emphasis. A vertex that snaps to an intersection is constrained to those two reference planes. When Width changes, that vertex moves with them. A vertex that landed a hair off the intersection is constrained to nothing, and the family will look perfect until the first time somebody flexes it, at which point the U tears open. There is no visual difference between the two states in the sketch. The only way to know is to have snapped deliberately.

The profile is then sketched in the reference level plan view, a simple rectangle drawn from one reference plane intersection to another. Because the corners snapped to intersections, no padlock is strictly required, though locking anyway costs nothing and makes the intent readable to the next person who opens the family.

The result is a plain U section that already flexes from the family types dialog.

Cut the top with a void, not by shortening the sweep

The U needs its top cut back to that non-parametric plane set earlier. The instinct is to shorten the path sketch. That is the wrong move, because the path is what carries the parametric behaviour, and trimming it hard-codes a length into geometry that is supposed to flex.

A void extrusion does the job instead. The solid gets hidden temporarily with HH so the sketch is readable, then the void is drawn on the same work plane.

Pick Lines is used with the lock toggle switched on, which is the detail that makes the cut parametric rather than coincidental. Picking a line without the padlock copies its position once. Picking it with the padlock creates a constraint, so if the reference plane moves, the void follows. The picked lines then get trimmed with TR into a closed loop, and the sketch is finished.

Back in plan, the void’s extents get locked to the two side reference planes with the Align tool. Voids default to a depth that has nothing to do with your family, and an unaligned void will stop cutting the moment Section Width grows past it.

When you cannot select the void

Voids are invisible in most views once they have cut something, which makes them awkward to reselect. The workaround shown is a window select across everything, then Filter, then tick only the baluster void. Its shape handles then appear and can be dragged to the reference planes and locked.

This is worth committing to memory. Filter is the reliable way to isolate a void in a family, and it saves the hunt-and-tab-cycle that most people default to. A quick check in the 3D view confirms the cut has gone through.

Build the types before you load, not after

The family is saved and types are created before it leaves the family editor. The template default Width is far wider than the design needs, so it gets narrowed, and two named types get saved: a narrower one and a wider one, with the wider type also given a thicker section by changing Section Depth from 6 to 12.

Doing this in the family editor rather than in the project is a habit worth forming. Types created in the family travel with the file, so every project that loads it gets the same two options with the same names. Types created ad hoc inside one project exist only in that project, and six months later you have four models with four different sets of near-identical baluster types and no way to tell which is canonical.

Two types is also the right number to start with. It proves the family flexes, which one type never does, and it does not commit you to maintaining a catalogue before anyone has asked for one.

Loading in, and where the family actually appears

The family loads into a fresh project with Load into Project. The build uses a project started from none so the stair settings are unencumbered by template defaults, which is a reasonable way to test content in isolation.

The family shows up under Railings in the project browser, not under a category of its own. This surprises people who go looking for a Balusters branch. It is also the confirmation you want that the template choice was right: a baluster family that appears under Railings will appear in the Baluster Placement list. One authored in Generic Model appears under Generic Models and will not.

Configure the stair, then the railing

A stair goes in with the standard tool at a 3 m level-to-level height, which produces Revit’s default stair and default railing. Neither is what the design wants, so both get replaced.

The stair type gets duplicated and renamed before anything is edited, which is the non-negotiable step. Editing a system family type in place changes every instance of it in the model, including the ones somebody else placed this morning. Duplicate first, always.

In the duplicated type, the Run type is opened and risers are switched off, with tread thickness set to 40 and a steel material applied. That produces the open-riser stair the minimal design calls for. The supports are then switched off to remove the stringers running down each side.

Two of those are worth flagging on a real project. An open-riser stair is a design decision with a compliance dimension in many jurisdictions, particularly on escape routes and in buildings used by children. A stair with the supports switched off is a stair with no modelled structure, which is fine for a design-stage visual and misleading if the model is going to a structural engineer or a fabricator. Both are legitimate settings. Both need a note in the model so the next person knows they were deliberate.

Baluster Placement is where the family finally does something

The railing type gets duplicated and opened. The default type has a rail the design does not want, so the rail is removed and a top rail is switched on at 900 mm from the finished floor instead.

Rails and the top rail are different objects in Revit, and confusing them is a common source of frustration. Rails are the horizontal members defined in the railing type’s Rail Structure, arrayed at the heights you list. The top rail is a separate element with its own type, its own profile, its own extension rules, and its own ability to be selected and edited in the model. For a minimal design where there is one rail and it is the one you hold, the top rail is almost always the right object to use. A design that carries the horizontal members instead of the balusters is built from the other half of the same railing type, which is what the parametric mesh railing build does with ten rails in the Rail Structure and a circular wire profile.

Baluster Placement then opens, the start and end offsets are set to zero, and the setting that makes this whole build work gets switched on: Use Baluster Per Tread On Stairs, with the narrower baluster type selected.

That checkbox changes the placement rule from “space balusters evenly along the railing path” to “put exactly one on each tread.” On a stair it is nearly always what you want. Even spacing along a sloping path produces balusters that land at arbitrary points relative to the nosings, which looks wrong in elevation and looks worse on site. One per tread is regular, it reads as designed, and it survives the stair being edited, because the count follows the tread count automatically.

The rail profile is a second family, and a much shorter one

The top rail at this point is still using a default profile. Fixing that needs a profile family, and profile families are the quickest useful family you will ever author.

File, New, Family again, and the Metric Profile - Rail template gets picked rather than the plain Metric Profile one. The difference is that the rail variant arrives with its category already set to Railings and with the rail centre line and rail top reference planes in place, so the profile is positioned correctly relative to the path without you working out the offset. The plain profile template works too, it just leaves that alignment to you.

The construction mirrors the baluster: reference planes go in and get dimensioned parametrically, with the dimensions labelled to Width and Depth parameters. A rectangle is then drawn from intersection to intersection and locked.

Types get created before saving, with the first type at 6 mm depth by 50 mm width. That is a deliberately flat, blade-like rail that suits the minimal design. Name the family and its types so the dimensions are readable from the list, because the profile dropdown inside a top rail type shows names only. A profile called Type 1 tells the next person nothing.

The profile loads into the project, and gets applied through the railing’s type properties, into the Top Rail type, then the Profile field. It is two dialogs deep, which is why people miss it: the profile is not a property of the railing type, it is a property of the top rail type nested inside it.

Extending the rail past where Revit stops it

Revit terminates the top rail at the end of the railing path, which on a stair usually means it stops short of where a real handrail would return or continue to the floor.

The fix is to tab-select the top rail, use Edit Rail, then Edit Path, and simply draw a line extending the path down to where it should end. The rail regenerates along the new path with the same profile.

The tab-select is the part that stalls people. Clicking a railing selects the railing system. The top rail inside it is a sub-element, and pressing Tab with the cursor over it cycles the selection down to it. Once the top rail is selected, Edit Rail becomes available on the ribbon.

The other side of the stair is a manual job: copy or mirror across, then adjust. Everything else in this build regenerates automatically, but a hand-edited rail path is geometry you own from that point on, and it will not follow if the stair moves. On a design that is still changing, hold off on the manual extensions until the stair geometry has settled.

Do it in the right order the second time

Having proved the assembly works, the stair gets rebuilt from scratch with the correct types preselected: the minimal stair type chosen in the type selector, railings switched on and set to the custom railing type before the run is drawn.

Inside that railing selection dialog, the position option is set to Treads rather than Stringer. Treads places the railing on the tread edge, which is where an open-riser stair with no supports needs it. Stringer places it on a stringer that this stair type no longer has.

This is the practical takeaway from the whole exercise. Configure the types first, then draw. Drawing a stair and fixing the types afterwards works, but it leaves behind orphaned default types in the project and it costs you the manual railing rework every time.

Where each part of the design actually lives

Custom railings confuse people because the settings are spread across four different objects. This is the map.

What you want to changeWhere it lives
Baluster shape and sectionThe baluster family (Metric Baluster template)
Baluster size optionsFamily types inside the baluster family
How often balusters appearRailing type, Baluster Placement
One baluster per stepRailing type, Use Baluster Per Tread On Stairs
Handrail cross-sectionA profile family (Metric Profile - Rail)
Handrail heightRailing type, Top Rail, Height
Handrail cross-section in useTop Rail type, Profile
How far the handrail runsThe top rail’s own path, via Edit Rail
Open risers, tread thicknessStair type, Run type
StringersStair type, Supports

If you can answer “which of these ten rows is this?” before you start clicking, custom railings stop being frustrating. Almost every dead end in Revit railings is somebody editing the right value on the wrong object.

Where this bites on a real project

The video builds this in an empty project. A live model adds friction the demo does not have time for.

Railings on landings behave differently. Use Baluster Per Tread On Stairs only governs the sloping runs. Landings have no treads, so the balusters there fall back to the spacing pattern defined above the checkbox. If you set that pattern up carelessly because the stair looked right, the landings will look wrong, and you will find it in a rendering rather than in plan.

Curved and multi-storey stairs strain a per-tread rule. On a spiral or a tight winder, one baluster per tread means balusters that fan out at the outer edge and crowd at the inner. That is geometrically correct and often visually unacceptable. Check it in 3D on the actual stair, not on a straight test run.

Not every railing in the model wants this type. Balcony and roof edge railings are usually a different design and definitely a different compliance case. Duplicating your stair railing type for them because it is already loaded is how a stair detail ends up on a roof parapet.

The family will get edited by somebody who did not build it. Which means the parameter names carry the documentation. Width, Section Width and Section Depth are readable. W1, W2 and D are not.

Team conventions worth setting once

Custom content only pays off if the team can find it and trust it. Four conventions cover most of the risk.

  1. Name families by what they are, not by who made them. A baluster family named for its section and its shape is findable by anyone. A family carrying somebody’s initials as a prefix sorts to a strange place in the browser and stops meaning anything the moment they leave.
  2. Put the key dimensions in the type name. For profiles especially, the dropdown that consumes them shows nothing but the name. A profile type named for its depth and width is self-documenting at the exact moment you need it.
  3. Store loadable content in one library, not in the project. The families in this build are saved to a library folder before loading. That is what lets the next project reuse them instead of somebody exporting them back out of a model.
  4. Record the compliance decisions somewhere the model does not. Open risers, missing stringers, and infill spacing are design and code decisions. The Revit type name will not remind anybody in eighteen months that they were deliberate. A line in the project’s BIM execution plan or model notes will. Our Revit project template and office standards guide covers where that lives.

Common mistakes and what each one looks like

The baluster never appears in the Baluster Placement list. The family was authored in the wrong template. Generic Model geometry will not array along a railing. Rebuild from Metric Baluster and copy the sketches across; it is faster than any workaround.

The baluster looks right until somebody flexes Width, then it tears open. A path vertex did not snap to a reference plane intersection. Reopen the sweep path, delete the offending line, and redraw it with SI at each end.

The void stops cutting when the section gets bigger. The void’s extents were never aligned and locked to the side reference planes. Select the void via Filter, drag its handles out to the planes, and lock them.

One side of the U moves and the other does not. The EQ constraint is missing from the pair of dimensions about the centre plane. Add it and reflex.

The balusters land at odd points on the stair. Use Baluster Per Tread On Stairs is off, so the even-spacing pattern is governing. It is a single checkbox in Baluster Placement.

The handrail is the wrong shape and the profile list has nothing useful in it. Either the profile family was never loaded, or it was authored in a template whose category is not Railings. The Metric Profile - Rail template sets that category for you.

Editing the railing type changed railings elsewhere in the model. The system family type was edited instead of being duplicated first. Undo, duplicate, rename, then edit.

Not shown in the video, but worth knowing

Three things a fourteen-minute build cannot reach.

Materials by parameter. The baluster in this build takes the material from its type. Adding a material parameter to the family, so the material can be swapped per type or per instance, is a small edit and makes the family far more reusable across projects with different palettes.

Shared parameters if the baluster needs to schedule. Family parameters are local to the family. If the baluster’s dimensions or a code need to appear in a project schedule or in an exported IFC, they have to be shared parameters. Our Revit shared parameters and schedules guide covers that setup.

Baluster posts are a separate list. The Baluster Placement dialog has a Posts section below the main pattern, governing the start, corner and end posts. This build leaves them alone. On a design where the corner condition matters, that lower half of the dialog is where you set it.

Where to take this next

If you want design references before you author anything, the roundup of 50 baluster designs for staircases and the staircase design collection are the idea end of the same subject. This post is the build end.

If the family authoring itself is the part you want to get faster at, the sweep, void and constraint techniques here are the same ones the door and window walkthroughs use on different categories, and the family creation fundamentals guide sets out the reference-plane discipline underneath all three.

And if you would rather work through Revit family authoring as a structured path instead of a series of one-off builds, the Archgyan course library covers families, detailing and coordination as one subscription, taught from the workflows a working BIM coordinator actually runs.

Level up your skills

Ready to learn hands-on?

  • Project-based Revit & BIM courses for architects
  • Go from beginner to confident professional
  • Video lessons you can follow at your own pace
Explore Archgyan Academy
← Back to Blog