markdown.style

HomeArchitecture documents from Markdown

Use cases

Architecture documents, one file

A design note mixes prose, a diagram, a decision table, configuration and references. One Markdown document holds all five, styled and exported together.

Open this example in the editorStart with your own

Five parts, one document

An architecture note is rarely just paragraphs. It has a context section, a diagram of how the pieces connect, and a table comparing the options that were considered. It also has a block of configuration and a decision with references back to the numbers that shaped it. Markdown covers all of it: headings and prose, a table, a fenced code block, footnotes, and a task list for what is still open. In the worked example below, the diagram has six boxes, the table compares three approaches, and the config block sets a worker's queue name and retry count.

A diagram that draws itself

A mermaid fence holds the diagram as plain text, a flowchart of boxes and arrows in this example. The editor draws it in the browser as an SVG, not at build time, so the source stays easy to diff and edit. It follows the theme: light themes get Mermaid’s neutral palette, dark themes its dark one, and the diagram is redrawn if you switch themes. Every export carries the same drawing that showed in the live preview. This page loads that drawing script, the one content page that does, since every other example keeps its Markdown free of diagrams so the build stays simple.

Tables and config blocks

The options-considered table is a plain GitHub-flavoured Markdown table: a header row, then one row per option. A verdict column lets a reader skim straight to the outcome. The configuration section is a fenced yaml block, which gets the same syntax highlighting as the other supported languages, so keys and values read apart.

Worked example

A short architecture note for a CSV ingestion service: context, a flow diagram, an options table, a config block, a decision with footnotes and open questions.

# CSV Upload Ingestion Service

## Context

Branch offices currently email CSV inventory counts to a shared inbox, and someone
pastes each one into a spreadsheet by hand. Volume has grown past what one person can
keep up with: about 3,500 files a day, with a peak of 4,200 during month-end counts.
This note proposes a small service. It accepts the same CSV files over an upload API,
queues them, and writes the rows into Postgres with no one in the loop.

```mermaid
flowchart LR
  Client[Branch uploader] --> API[Upload API]
  API --> Store[(Object storage)]
  API --> Queue[[csv-ingest-queue]]
  Queue --> Worker[Ingest worker]
  Worker --> DB[(Postgres)]
```

The upload API writes the file to object storage first, then drops a small message
on the queue with the storage key. The queue never carries the CSV body, only a
reference to it, so message size stays well under any queue provider's limit.

## Options considered

| Option | Latency | Failure isolation | Verdict |
|---|---|---|---|
| Synchronous insert on upload | Immediate | One bad row fails the whole request | Rejected |
| Queue plus worker pool | Seconds, typically under five | Retries per file, one bad file does not block others | Chosen |
| Nightly batch job | Up to 24 hours | Easiest to build, worst for same-day counts | Rejected |

## Configuration

The worker pool reads its settings from a small YAML file, checked into the same
repo as the worker code:

```yaml
worker:
  queue: csv-ingest-queue
  concurrency: 8
  batch_size: 25
  visibility_timeout_seconds: 120
  max_retries: 3
  dead_letter_queue: csv-ingest-dlq
```

## Decision

We will validate each file in the upload handler, queue one message per file, and
let a worker pool write rows to Postgres in batches of 25.[^1] A malformed row is
logged and skipped rather than failing the whole file, so a store with one bad
line still gets its other counts recorded.[^2]

## Open questions

- [x] Keep the CSV body out of the queue message, carry only the storage key
- [ ] Decide whether a run of malformed rows pages someone or waits for the morning digest
- [ ] Set a maximum file size on the upload API; it is currently unbounded
- [ ] Write a runbook entry for replaying files off the dead-letter queue

[^1]: Batch size of 25 matches the ingest database's connection pool without adding a second pool.
[^2]: Rejected files stay in object storage for 30 days so a branch can fix and resubmit.

Rendered in the Mono theme. Open it in the editor to change the theme or the text.

Footnotes carry the reasoning

A decision paragraph often leans on a number or a policy that does not belong in the main sentence. Write it as [^1] and the definition at the bottom, and the rendered page turns it into a small numbered link the reader can follow. The sample above uses two, one for a sizing choice and one for a retention policy.

Mono, and when to reach for something else

Mono sets everything in monospace, IBM Plex Mono, with uppercase headings and a wider column so long config lines and code do not wrap. It suits a document that already lives in a monospace editor: technical notes, runbooks and data-heavy pages with wide tables all fit. Slate is a plainer choice for a note with many tables. Carbon is a dark theme built for pages with a lot of code, and both are switchable from the same document.

A reviewable PDF

"Print or save as PDF" opens the browser’s own print dialog, and picking "Save as PDF" there turns the note into a review copy. That gives reviewers a file they can comment on without opening the editor themselves, generated from the exact document on screen. Mono is already a light theme, so nothing changes for print. Any of the site’s dark themes convert to dark text on white when printed.

Questions

Does the diagram survive the exports, or only the preview?

Yes. Download .html re-renders the document and grafts the diagram’s SVG into the export; Copy styled HTML clones the live preview, diagram included.

Does a dark theme such as Carbon still print well?

Yes. Carbon is dark on screen but prints as dark text on white, so a "Print or save as PDF" run stays readable on paper.

Where do the footnotes end up on the page?

Each [^1] becomes a numbered link, and the definitions collect at the bottom of the document under a footnotes section, in order.

Does the yaml block get syntax highlighting?

Yes. yaml is one of the highlighted languages, alongside bash, python, sql, typescript and others, so keys and values are coloured.