A browser-based track plan editor and renderer for the PIKO A-Track H0 model railway system.
▶ Try the live demo — nothing to install.
Layouts are described as JSON — a list of paths, each a sequence of track pieces — and the renderer chains them together using the exact catalog geometry, so a plan either closes or it doesn't. No dragging pieces until they look about right.
The bundled Station Set example — PIKO track set 55320 added to sets A + B: an oval with an inner passing loop around one end and a siding off the first turnout.
- Catalog-driven geometry — every piece is defined by its legs (line / arc, radius, angle)
in
catalog.json; positions and headings are derived, never hand-placed. - Drag & drop editing with connector snapping, plus an inline JSON editor for precise work.
- Branching paths — a path can start from any connector of any element on another path, which is how sidings, passing loops and yards are expressed.
- Turnout state visualisation, side labels, snap points, element colours.
- Undo / redo (
Ctrl+Z/Ctrl+Y), pan, zoom, grid and scene rotation. - Import / export — save and load layouts as JSON, export the scene as SVG, load a replacement catalog at runtime.
- Worked examples from the official PIKO track sets (see below).
npm installnpm run devThen open the URL Vite prints. Other scripts:
npm run buildbuild type-checks and emits a single self-contained HTML file into release/, alongside the
catalog.json and examples.json that are fetched at runtime. Those three files are the whole
application — copy them anywhere and open index.html.
Pushing to rel deploys them to the live demo via
.github/workflows/pages.yml.
{
"name": "Basic Oval",
"startPos": [0, 0],
"startDir": 0,
"startAngle": 0,
"paths": [
{ "name": "Main", "id": "main", "from": null,
"elements": ["G231", "R2", "R2", "R2", "R2", "R2", "R2",
"G231", "R2", "R2", "R2", "R2", "R2", "R2"] }
]
}An element is "ID", or "ID;entry;exit" to enter and leave by named connectors — "R2;B;A"
traverses an R2 curve backwards (turning the other way), and "WL;B;A" makes a turnout trailing
rather than facing. Sides are A/B for plain track and A/B/C (plus D) for turnouts,
where A is the point end.
A path's from is "pathId[index];side" — the connector on an already-placed element that this
path grows out of. "main[13];C" starts a branch at the diverging leg of the 14th element of
main.
All dimensions come from PIKO's published figures. Two properties of the system drive almost everything:
| Quantity | Value |
|---|---|
| Module length | G239 + G231 = 470.00 mm |
| Parallel track spacing | 61.88 mm |
The spacing shows up in several independent places, and they all have to agree: G62 is
61.88 mm; consecutive curve radii differ by 61.88 mm (R1 360 → R2 421.88 → R3 483.75 →
R4 545.63); a turnout plus a counter-curved R9 offsets by 2 × 907.97 × (1 − cos 15°) =
61.876 mm; and a G239 taken at 15° rises 61.876 mm.
The published radii are themselves rounded, which leaves about 0.01 mm of irreducible slop
(R3 − R2 = 61.87 vs R2 − R1 = 61.88). Closure errors larger than that indicate a real
problem, not floating point.
BWL/BWR are modelled as two arcs leaving the shared point end A — R2 through to C,
R3 diverging to B, both turning 30° — which puts their two exits 32.03 mm apart. That matches
the shape of the real piece, but it does not reproduce PIKO's own 55340 track plan, where the
by-pass ends up a full track spacing (61.88 mm) from the main line. The Parallel Set example
below is 16.58 mm short of closing because of it.
Forcing the exits 61.88 mm apart instead is not the fix: the leg then has to bow away and back to leave and arrive tangentially, and renders as a wishbone rather than a turnout. The correct model is still open — most likely the diverging leg is not a constant-radius arc, or does not turn the full 30°. Two measurements off a real BWL/BWR would settle it: the distance between the two exit faces, and whether those faces are parallel or splayed.
No other piece is affected, and no other example uses a curved turnout.
Bundled under Examples in the toolbar, reproducing the official PIKO track sets. Footprints are as printed in PIKO's own track flyer:
| Example | Set | Footprint | Closes |
|---|---|---|---|
| Simple Circle | — | 88 × 88 cm | 0.0000 mm |
| Basic Oval | 55300 Track Set A | 110 × 88 cm | 0.0000 mm |
| Station Set | 55320 Track Set C, added to A + B | 182 × 88 cm | 0.0000 mm |
| Freight Station | 55330 Track Set D, added to A | 205 × 88 cm | 0.0000 mm |
| Parallel Set | 55340 Track Set E, added to A | 182 × 95 cm | 16.58 mm open |
The first four use exactly the pieces their sets contain and match the printed floor areas. The Parallel Set is the exception — see the curved-turnout issue above.
src/ application source (TypeScript, no framework)
catalog.json piece geometry
index.html entry point
public/ served as-is; catalog.json and examples.json are fetched at runtime
release/ build output (git-ignored)
geometry.md A-Track dimensions reference
An independent hobby project. Not affiliated with or endorsed by PIKO Spielwaren GmbH. "PIKO" and "A-Track" are trademarks of their respective owner; dimensions are quoted from publicly published catalog data for interoperability.
