Skip to contentRoadmapStar

The .roadmap.json file format

A roadmap is one JSON file holding a schema version, a document id and title, a list of properties, a list of items, and a list of saved views. Field ids are readable slugs rather than opaque keys, unknown fields survive a load and save unchanged, and a file with a newer schema version opens read-only.

A roadmap made here is a single file with a double extension — platform-2026.roadmap.json. The operating system reads only the final .json, so it opens in any text editor and any JSON viewer with no special handling, while roadmap makes it recognisable in a downloads folder.

The tables below are generated from the same schema the editor validates against, so they cannot drift from the format the application actually reads.

What a reader may rely on

Unknown keys survive
A key this reader does not recognise is preserved through a load and a save, byte for byte. Nothing in a roadmap file is ever silently dropped.
Ids are readable and stable
Property and option ids are slugs generated once from the label and never changed afterwards, so `"stage": "now"` still means something in three years.
Dates are ISO 8601
A date value is `YYYY-MM-DD`. Whether it is drawn as a day, a month or a quarter is a display setting, not a change to the value.
A newer file opens read-only
A reader that meets a `schemaVersion` it does not know still shows the roadmap and still exports it. Only editing is switched off.
Hiding is presentation
A property missing from a view's visible fields is hidden in that view and still present in the file. Sharing the file shares everything in it.

A complete minimal file

{
  "schemaVersion": 1,
  "id": "rm_k3n8fq2p",
  "title": "Platform 2026",
  "createdAt": "2026-10-01T09:00:00.000Z",
  "updatedAt": "2026-10-01T09:00:00.000Z",
  "properties": [
    { "id": "title", "label": "Name", "type": "text", "role": "title" },
    { "id": "stage", "label": "Stage", "type": "select",
      "options": [{ "id": "now", "label": "Now", "color": "blue" }] },
    { "id": "start", "label": "Start", "type": "date", "role": "startDate" },
    { "id": "end",   "label": "End",   "type": "date", "role": "endDate" }
  ],
  "items": [
    { "id": "c7m2xp9d", "parentId": null,
      "values": { "title": "Card payments", "stage": "now",
                  "start": "2026-10-01", "end": "2026-12-31" } }
  ],
  "views": [
    { "id": "v_all", "name": "All items", "type": "table",
      "filter": { "conditions": [] }, "sort": [],
      "colorBy": { "source": "none" }, "order": {},
      "table": { "columns": [{ "propertyId": "title", "width": 320 }] } }
  ]
}

The machine-readable JSON Schema is at /roadmap.schema.json, generated from the same source as the tables below.

Every field

Document

FieldTypeRequiredNotes
schemaVersionintegerYesThe format version this file was written against. A reader that understands an older version opens the file for viewing and export, with editing disabled. It is never rejected.
idstringNoThe document's own id, `rm_` and eight characters. Regenerated when a template or starter is opened, so two copies are never the same document. Optional on import: a file without one is given a new id when opened.
titlestringNoThe roadmap's name. Also the basis of the download filename, slugified. Optional on import: a file without one opens as `Roadmapstar roadmap`.
createdAtstringNoISO 8601 timestamp. Written once. Optional on import: a file without one is given the time it was opened.
updatedAtstringNoISO 8601 timestamp of the last edit. Optional on import: a file without one is given the time it was opened.
propertiesProperty[]YesThe fields every item may carry, in the order they were defined. The registry belongs to the document, not to the application.
itemsItem[]YesThe roadmap's items, flat. Hierarchy is expressed by `parentId`, not by nesting.
viewsView[]YesSaved views over the same items. Each carries its own filter, sort, grouping and visible fields.

Property

FieldTypeRequiredNotes
idstringYesA readable slug generated once from the label — `Risk level` becomes `risk_level` — and never changed afterwards, including when the label is renamed. A collision takes a numeric suffix.
labelstringYesWhat the field is called on screen. Free to change; the id does not follow it.
type"text" | "longtext" | "number" | "select" | "date" | "url" | "checkbox"YesThe value type. `longtext` holds a markdown subset; `select` requires `options`.
role"title" | "startDate" | "endDate" | "stage" | "milestone"NoMarks the property the application should use for a structural job — the item's name, its dates, its stage, or its milestone flag. At most one property per role.
optionsSelectOption[]NoFor `select` only: the allowed values, each with its own id and colour.
multiplebooleanNoFor `select` only: when true, an item may hold several options, stored as an array of option ids. Absent means one.
configobjectNoPer-type settings. For a date, `display` chooses whether a value is drawn as an exact date, a month or a quarter.

SelectOption

FieldTypeRequiredNotes
idstringYesA readable slug, generated from the label at creation and immutable after — so `"stage": "now"` stays meaningful in the file.
labelstringYesWhat the option is called on screen.
color"slate" | "blue" | "teal" | "green" | "amber" | "orange" | "red" | "violet"YesOne of eight named swatches. The name carries the meaning; the colour only carries the grouping.

Item

FieldTypeRequiredNotes
idstringYesEight characters, unique within the document. A duplicate is regenerated on load and the change is reported.
parentIdstring | nullNo — nullThe parent item's id, or null for a top-level item. A missing or cyclic parent is reset to null on load and reported.
dependsOnstring[]NoIds of items this one follows. A self-reference, a missing target or a link that would close a cycle is dropped on load and reported.
values{ [propertyId: string]: string | number | boolean | null | string[] }No — {}The item's values, keyed by property id. A select with `multiple` holds an array of option ids. A value whose property was deleted stays in the file.

View

FieldTypeRequiredNotes
idstringYes`v_` and eight characters.
namestringYesThe view's tab label.
type"table" | "board" | "timeline"YesWhich renderer draws this view. The type-specific block below it is kept when the type changes, so switching back restores the old configuration.
filter{ conditions: Condition[] }No — {"conditions":[]}Conditions, combined with AND. An empty condition list means every item.
sortSort[]No — []Sort levels in priority order. An empty list leaves the manual order from `order`.
groupByPropertyIdstringNoThe property whose value groups items — board columns, timeline lanes, table sections. Items with no value form their own visible group.
density"compact" | "default" | "comfortable" | "presentation"NoThe size the view draws itself at. Held on the view, outside the type block, so it survives a type change.
showLegendbooleanNoDraw a key for the colour-by property.
colorByanyNo — {"source":"none"}Where item colour comes from: nothing, or the swatches of a select property's options.
order{ [propertyId: string]: string }No — {}Manual item order, as fractional index strings keyed by item id. Only consulted where no sort applies.
tableTableSettingsNoTable-specific settings. Present for a table view, and kept after a type change.
boardBoardSettingsNoBoard-specific settings.
timelineTimelineSettingsNoTimeline-specific settings.

Condition

FieldTypeRequiredNotes
propertyIdstringYesThe property being tested.
operator"is" | "is_not" | "contains" | "not_contains" | "is_empty" | "is_not_empty" | "eq" | "neq" | "gt" | "lt" | "gte" | "lte" | "before" | "after" | "on_or_before" | "on_or_after" | "is_checked" | "is_unchecked"YesWhich comparison to make. The available operators depend on the property's type.
valuestring | number | boolean | nullNoThe value compared against. Absent for the operators that need none, such as `is_empty`.

Sort

FieldTypeRequiredNotes
propertyIdstringYesThe property to sort on.
direction"asc" | "desc"YesAscending or descending.

TableSettings

FieldTypeRequiredNotes
columnsobject[]YesThe visible columns, in order, each with its width in pixels. A property absent from this list is hidden in this view — and still present in the file.

BoardSettings

FieldTypeRequiredNotes
cardPropertiesstring[]No — []Properties drawn on a card beneath its name.
hiddenGroupsstring[]No — []Option ids whose column is not drawn at all.
columnOrderstring[]No — []Column keys in the order their columns are drawn. Empty is the registry's option order.
subGroupByPropertyIdstringNoA second property, drawing lanes across the columns.
collapsedSubGroupsstring[]No — []Lanes drawn as their header alone.
cardColor"strip" | "fill" | "top"NoHow loudly a card wears its colour. Absent draws a strip.
columnHeaderStyle"panel" | "plain"NoAbsent draws a recessed panel header attached to its cell.
showCountsbooleanNoCounts on the column and lane headers. Absent is true.
columnWidthnumberNoMinimum column width in pixels, clamped 140 to 420. Absent is 180.
columnColors{ [columnKey: string]: Swatch }NoA swatch per column, on this board alone, keyed by column key. A column absent from the map is drawn neutral.

TimelineSettings

FieldTypeRequiredNotes
startPropertyIdstringYesThe date property a bar starts at.
endPropertyIdstringYesThe date property a bar ends at. An item with a start and no end is drawn as a point.
milestonePropertyIdstringNoA checkbox property; a true value draws a diamond instead of a bar.
zoom"week" | "biweek" | "month" | "quarter" | "half" | "year"No — "quarter"The axis resolution, from a week to a year per column.
axisLabels"dates" | "weeks"NoWhether axis columns are labelled with dates or week numbers.
highlightWeekendsbooleanNoShade Saturdays and Sundays behind the lanes.
showGridlinesbooleanNoVertical rules at each axis column.
anchorstringNoThe date the visible window opens at. Absent frames the items.
laneOrderstring[]No — []Group keys in the order their lanes are drawn.
hiddenLanesstring[]NoGroup keys whose lane is not drawn at all, and whose items do not appear in this timeline.
laneColors{ [laneKey: string]: Swatch }NoA swatch per lane, on this timeline alone, keyed by lane key. A lane absent from the map is drawn untinted.
collapsedLanesstring[]No — []Lanes drawn as their label alone.
showDependenciesbooleanNoDraw dependency arrows in this view. Absent is true.
shift"overlap" | "gap" | "none"NoHow dependants are rescheduled when a date changes. Absent overlaps them.
axisBandbooleanNoA coarser band above the column labels — quarters over months, months over weeks. Absent is false.
laneBandingbooleanNoAlternate lane backgrounds, so a wide row stays readable across. Absent is false.
showTodaybooleanNoDraw the Today line and its caption. Absent is true.
barHeightnumberNoBar height in pixels, overriding the density's, clamped 16 to 64. Absent uses the density.
barLabels"inside" | "outside" | "hidden"NoWhere a bar's name is drawn. Absent draws it inside.
barDatesbooleanNoAppend the bar's dates after its name. Absent is false.
laneLabelStyle"text" | "chip"NoDraw the lane label as its swatch chip instead of display type. Absent is text.
avoidWeekendsbooleanNoKeep shifted items off Saturdays and Sundays. Absent is false.
visiblePropertiesstring[]NoWhich properties a bar and its detail show. Absent shows everything but links and notes.

Questions

Why publish the format at all?

Because a file format nobody can read is not a file you own. The specification is what makes the document readable without this editor, now or in five years.

What happens to fields a reader does not recognise?

They are preserved verbatim through a load and save. Nothing in a roadmap file is ever silently dropped, including values referencing a property that was deleted.

Can I write my own roadmap file by hand?

Yes. The ids are readable slugs, so a file is understandable in a text editor and reviewable in a diff. An invalid file reports the line that is wrong.

Is the format versioned?

Yes, by an integer schemaVersion at the top of the document. A file declaring a version newer than the reader understands opens for viewing and export, with editing disabled.

Open the editorMake a roadmap and download the file. Or read the templates, which are all real files.

Last updated