Documentation

Meridian User Guide

Everything you need to know to map, visualize, and document your system dependencies.


Workspaces

A workspace is the top-level organizational container in Meridian. Each workspace has its own systems, domains, dependency graph, team members, and upload history — completely isolated from other workspaces.

What is a workspace?

Think of a workspace as a project or an organization boundary. When you upload an inventory, resolve dependencies, and visualize a graph, all of that data lives inside a specific workspace. Teams typically create one workspace per platform, product, or business unit.

Each workspace has a unique slug that appears in the URL:/w/my-workspace/graph. All navigation within the app is scoped to the current workspace.

Creating a workspace

Navigate to /workspaces after signing in. Click New workspace. You will be prompted for:

  • Name — human-readable display name (e.g., “My Platform”)
  • Slug — URL-safe identifier, auto-generated from the name but editable (lowercase letters, numbers, and hyphens only, e.g., my-platform)
  • Description — optional short description shown on the workspace card

After creation you are redirected to /w/[slug]/dashboard and automatically assigned the OWNER role.

Roles & permissions

Every workspace member holds one of three roles. Roles control what actions a member can perform:

RoleView graph & systemsUpload inventoryCreate & edit docsManage membersChange settings
OWNERYesYesYesYesYes
EDITORYesYesYesNoNo
VIEWERYesNoNoNoNo
One owner per workspace
Each workspace has a single owner. Ownership can be transferred to another member in workspace settings.

Navigation & switching workspaces

The top header shows the name of the current workspace. Click it to open a dropdown that lists all workspaces you belong to. Select any workspace to switch to it immediately.

The header navigation bar contains the following pages for each workspace:

  • Dashboard — metrics, charts, and recent activity
  • Graph — interactive dependency graph
  • Systems — searchable list of all registered systems
  • Upload — inventory upload (EDITOR and OWNER only)
  • Settings — workspace settings and members (EDITOR and OWNER only)

Dashboard

The dashboard is the first page you see when you enter a workspace. It gives you a high-level overview of the health, structure, and recent activity of your platform.

Stat cards

Four metric cards at the top of the dashboard summarize the current state of your workspace at a glance:

CardWhat it shows
DomainsTotal number of business domains registered in the workspace
SystemsTotal number of systems (services, workers, jobs, etc.) in the workspace
DependenciesTotal number of resolved dependency edges between systems
HIGH + CRITICAL RisksCount of risk entries with severity HIGH or CRITICAL across all systems

Charts

Two horizontal bar charts show the distribution of your platform at a glance:

  • Languages distribution — number of systems per programming language. Helps identify the predominant tech stack and outliers.
  • Dependency types — count of resolved edges per dependency type (HTTP, Kafka, shared database, etc.). Shows which integration patterns are most common.

Top connected systems

A ranked table listing the systems with the most dependency connections (inbound + outbound combined). These high-coupling systems are often the most critical nodes in your architecture and deserve special attention when planning changes.

Click any system name to navigate directly to its detail page.

Risks & recent uploads

Two additional tables give you visibility into recent activity:

  • Recent risks — the latest 5 risk entries with HIGH or CRITICAL severity. Each row shows the risk title, the system it belongs to, and a color-coded severity badge.
  • Recent uploads — the last 5 inventory upload attempts, showing the filename, processing status (PENDING, PROCESSING, COMPLETED, FAILED), the number of systems affected, and the upload timestamp.

Inventory Upload

Meridian ingests your architecture as structured JSON files called inventories. Each file describes one or more systems — their services, databases, integrations, message topics, packages, and risks. After upload, Meridian automatically resolves dependency edges between systems and updates the graph.

Drag-and-drop upload

Navigate to Upload in the workspace header. The page displays a drop zone where you can drag and drop one or more .json files. You can also click the zone to open a file picker.

After selecting your files, Meridian will:

  1. Validate the JSON structure against the inventory schema
  2. Upsert domains and systems (create or update based on slug)
  3. Replace all nested components (services, databases, integrations, etc.)
  4. Re-run dependency resolution and update all edges in the graph
  5. Create an upload record with status COMPLETED or FAILED
Existing data is replaced on upload
Uploading a new inventory for a system that already exists replaces all its nested components (services, databases, integrations, risks, etc.). The dependency graph is fully recalculated after each upload. Previous graph snapshots are preserved for the time machine feature.

JSON schema reference

The inventory file must contain a top-level systems array with at least one entry. Each system requires a name and a slug. All other fields are optional but provide richer graph resolution and documentation.

jsonc
{
  "systems": [
    {
      // Required fields
      "name": "string",          // Human-readable system name
      "slug": "string",          // URL-safe identifier: ^[a-z0-9]+(?:-[a-z0-9]+)*$

      // Optional metadata
      "domainName": "string",    // Business domain (e.g., "Payments")
      "purpose": "string",       // Short description of what this system does
      "language": "string",      // Primary programming language (e.g., "TypeScript")
      "framework": "string",     // Framework name (e.g., "NestJS")
      "frameworkVersion": "string",
      "repositoryUrl": "string", // Valid URL to the source code repository

      // Services exposed by the system
      "services": [
        {
          "name": "string",      // Required
          "slug": "string",      // Optional, same pattern as system slug
          "type": "API | WORKER | CRONJOB | BACKGROUND_SERVICE",  // Required
          "port": 3000,          // Optional, positive integer
          "path": "string"       // Optional, e.g., "/api"
        }
      ],

      // Databases this system owns or connects to
      "databases": [
        {
          "name": "string",      // Required (e.g., "payments_db")
          "provider": "string",  // Required (e.g., "PostgreSQL", "MongoDB")
          "version": "string",   // Optional
          "orm": "string"        // Optional (e.g., "Prisma", "SQLAlchemy")
        }
      ],

      // Outbound integrations to other systems
      "integrations": [
        {
          "targetSystem": "string",  // Required - target system name or slug
          "type": "HTTP_API | DATABASE_DIRECT | GRPC | MESSAGE_QUEUE | EVENT_STREAM | FILE_TRANSFER | SDK | OTHER",
          "description": "string"   // Optional
        }
      ],

      // Message broker topics this system produces or consumes
      "messageTopics": [
        {
          "name": "string",      // Required (e.g., "payment.completed")
          "role": "PRODUCER | CONSUMER | BOTH",  // Required
          "broker": "KAFKA | RABBITMQ | SQS | SNS | OTHER",  // Required
          "metadata": {          // Optional
            "consumerGroup": "string",
            "exchange": "string",
            "routingKey": "string",
            "dlqEnabled": true,
            "retryPolicy": "string"
          }
        }
      ],

      // External and internal package dependencies
      "packages": [
        {
          "name": "string",      // Required (e.g., "stripe")
          "version": "string",   // Optional (e.g., "^14.0.0")
          "type": "INTERNAL | OPEN_SOURCE | TEST"  // Optional
        }
      ],

      // HTTP API endpoints exposed by the system
      "apiEndpoints": [
        {
          "path": "string",      // Required (e.g., "/payments/charge")
          "method": "string",    // Required (e.g., "POST")
          "description": "string" // Optional
        }
      ],

      // Known risks and technical debt
      "risks": [
        {
          "title": "string",     // Required
          "description": "string", // Optional
          "severity": "LOW | MEDIUM | HIGH | CRITICAL"  // Required
        }
      ]
    }
  ]
}

Complete example

The following example shows a complete inventory for a payments service with HTTP and gRPC outbound integrations, Kafka producer topics, a PostgreSQL database, external and internal packages, API endpoints, and two risks:

json
{
  "systems": [
    {
      "name": "Payments Service",
      "slug": "payments-service",
      "domainName": "Payments",
      "purpose": "Processes payment transactions and emits events to downstream systems",
      "language": "TypeScript",
      "framework": "NestJS",
      "frameworkVersion": "10.3.0",
      "repositoryUrl": "https://github.com/acme/payments-service",

      "services": [
        {
          "name": "payments-api",
          "slug": "payments-api",
          "type": "API",
          "port": 3001,
          "path": "/api"
        },
        {
          "name": "charge-worker",
          "slug": "charge-worker",
          "type": "WORKER"
        }
      ],

      "databases": [
        {
          "name": "payments_db",
          "provider": "PostgreSQL",
          "version": "15",
          "orm": "Prisma"
        }
      ],

      "integrations": [
        {
          "targetSystem": "orders-service",
          "type": "HTTP_API",
          "description": "Fetches order details before processing payment"
        },
        {
          "targetSystem": "fraud-service",
          "type": "GRPC",
          "description": "Real-time fraud scoring"
        }
      ],

      "messageTopics": [
        {
          "name": "payment.completed",
          "role": "PRODUCER",
          "broker": "KAFKA",
          "metadata": {
            "dlqEnabled": true,
            "retryPolicy": "exponential-backoff"
          }
        },
        {
          "name": "payment.failed",
          "role": "PRODUCER",
          "broker": "KAFKA"
        }
      ],

      "packages": [
        { "name": "stripe", "version": "^14.0.0", "type": "OPEN_SOURCE" },
        { "name": "@acme/shared-auth", "version": "2.1.0", "type": "INTERNAL" }
      ],

      "apiEndpoints": [
        { "path": "/payments/charge", "method": "POST", "description": "Initiates a payment" },
        { "path": "/payments/{id}", "method": "GET", "description": "Retrieves payment status" }
      ],

      "risks": [
        {
          "title": "No circuit breaker on orders-service call",
          "description": "If orders-service is slow, payments will queue up and degrade",
          "severity": "HIGH"
        },
        {
          "title": "Stripe API key stored in plain-text env var",
          "severity": "CRITICAL"
        }
      ]
    }
  ]
}

Graph View

The Graph page is the core of Meridian. It renders an interactive visualization of all systems in the workspace and the dependency edges between them, resolved from your inventory uploads. Navigate to Graph in the workspace header to open it.

Toolbar & filters

The toolbar at the top of the graph provides controls to filter and configure what is displayed. All filter states are persisted to the URL as query parameters, making filtered views fully shareable.

ControlDescription
SearchFilter nodes by system name in real time as you type
DomainMulti-select dropdown to show only systems belonging to selected domains
Dependency typeMulti-select with color-coded swatches to show only specific edge types (HTTP, Kafka, shared database, etc.)
LanguageMulti-select to filter systems by programming language
IsolatedToggle to show or hide systems that have no dependency connections (eye icon)
Flow animationToggle particle animations on messaging edges (Kafka, RabbitMQ, SQS). Uses a lightning bolt icon.
Layered layoutSwitch between free-form layout and a topological 3-layer layout (EDGE → BUSINESS_LOGIC → DATA_INFRA)
ClusterGroup nodes visually by business domain. At zoom levels below 0.4, domains automatically collapse into a single node.
Reset filtersClears all active filters (only visible when at least one filter is active)

A counter below the toolbar shows the number of visible systems and edges vs. the total: e.g., 12 / 24 systems · 8 / 31 dependencies.

Layout modes

Meridian supports three layout modes for the graph:

  • Free-form (default) — nodes are positioned automatically by a force-directed algorithm. You can drag nodes anywhere; positions are saved per layout mode in local storage.
  • Layered — activates a topological layout that places systems in three horizontal layers based on their declared layer field: EDGE (user-facing), BUSINESS_LOGIC (internal services), and DATA_INFRA (databases, queues, infrastructure). Useful for understanding architectural tiers.
  • Clustered — groups nodes inside domain containers. When you zoom out below 0.4×, individual nodes collapse into a single domain node to reduce visual noise. Click a collapsed domain node to expand it.

Node interactions

Each node in the graph represents a system. Nodes display the system name, domain badge, programming language, and service ports. Service types use abbreviated labels:

Service typeBadge label
APIAPI
WORKERWKR
CRONJOBCRON
BACKGROUND_SERVICEBG

Nodes support the following interactions:

  • Click — opens the System Detail Panel on the right side of the screen, showing the system metadata, services, databases, integrations, and risks
  • Highlight button — click the waypoints icon on a node to activate a highlight session: connected edges are highlighted and all unrelated nodes fade to near- invisible (opacity 0.08)
  • Risk badge — if the system has risks, a badge showing the risk count appears on the node
  • Drag — grab and move any node to reposition it; the new position is saved automatically

Edge types & colors

Every dependency edge is color-coded based on its type. Messaging edges (Kafka, RabbitMQ, SQS) also display flowing particle animations to indicate data flow direction.

TypeColorAnimatedDescription
HTTP_APIIndigo · #4f46e5NoREST or HTTP API calls between systems
KAFKA_TOPICGreen · #059669YesKafka topic relationships (producer → consumer)
RABBITMQ_QUEUEViolet · #A855F7YesRabbitMQ queue relationships
SQS_QUEUEYellow · #EAB308YesAWS SQS queue relationships
SHARED_DATABASEAmber · #d97706NoTwo systems connecting to the same database (same name + provider)
CROSS_DATABASE_QUERYRed · #dc2626NoDirect cross-database queries between systems
SHARED_PACKAGEPurple · #7c3aedNoTwo systems depending on the same internal package
GRPCCyan · #0891b2NogRPC calls between systems
FILE_DEPENDENCYGray · #6b7280NoFile system or artifact dependencies

A legend below the filters shows all currently visible edge types with their corresponding color swatches.

Edge interactions

Edges support two main interactions:

  • Click — opens a popup showing the source system, target system, dependency type, and the specific target service slug (e.g., which API service or message topic the edge targets)
  • Drag — click and drag any edge to adjust its path offset. Edges follow an orthogonal step path with rounded corners. Dragging adjusts the X offset (shifts the two vertical bends left/right) and Y offset (shifts the middle horizontal segment up/down). Offsets are saved per layout mode in local storage.

Hovering an edge reveals a semi-transparent glow, a midpoint dot, and faint depends on / consumed by labels near the source and target.

Time machine

The time machine slider at the bottom of the graph lets you travel back through the history of your graph as it was after each inventory upload. Drag the slider to a previous upload to see the state of the dependency graph at that point in time.

This is useful for understanding how your architecture evolved, spotting when new dependencies were introduced or removed, and reviewing the impact of past changes.

Snapshots are saved automatically
Meridian saves a graph snapshot after each successful inventory upload. The time machine only shows entries where at least one snapshot exists.

Press Cmd+K (macOS) or Ctrl+K (Windows/Linux) to open the command palette. Type any system name to search across all systems in the workspace. Selecting a result focuses the graph on that node and centers it in the viewport.

Highlight navigation

Activating the highlight mode on a node (via the waypoints button) starts a highlight session:

  • All edges connected to the highlighted node (inbound and outbound) remain fully visible
  • All unrelated nodes and edges fade to near-invisible (opacity 0.08)
  • A navigation bar appears at the bottom of the graph with Previous and Next arrow buttons to cycle through the connected systems one by one
  • The currently focused connected node is highlighted in blue; the source node is highlighted in green

Click the highlighted node again or press Escape to exit the highlight session and return to the normal graph view.

Systems

The Systems section lets you browse all services, workers, and jobs registered in your workspace. It provides two views: a searchable list of all systems and a detailed page for each individual system.

Systems list

Navigate to Systems in the workspace header. The page shows a table with all systems in the workspace, sorted alphabetically. Each row displays:

  • System name — links to the system detail page
  • Domain — the business domain the system belongs to
  • Language and Framework — the primary tech stack
  • Services count — number of services (APIs, workers, cron jobs)
  • Databases count — number of registered databases
  • Integrations count — number of outbound integrations declared
  • Documents count — number of Markdoc documents attached to the system

Click any row to navigate to the system detail page.

System detail tabs

The system detail page (/w/[slug]/systems/[systemSlug]) is divided into four tabs:

Overview

Shows the system metadata extracted from the inventory: programming language, framework and version, domain name, and the repository URL (clickable external link if provided).

Architecture

Displays the full inventory of technical components registered for the system:

ComponentFields shown
ServicesName, type (API / WORKER / CRONJOB / BACKGROUND_SERVICE), port, path
DatabasesName, provider, version, ORM
IntegrationsTarget system, integration type, description
Message topicsTopic name, broker, role (PRODUCER / CONSUMER / BOTH)
PackagesName, version, scope (INTERNAL / OPEN_SOURCE / TEST) — top 20 shown

Risks

Lists all risk entries declared in the inventory for this system. Each row shows the risk title, description, and a color-coded severity badge:

  • CRITICAL and HIGH — red (destructive)
  • MEDIUM — neutral (secondary)
  • LOW — outline

Documentation

Lists all Markdoc documents attached to the system, showing the title, author, and last updated date. EDITOR and OWNER members see a New Document button to create a new document inline.

Documentation

Meridian includes a built-in documentation system that lets teams write and maintain technical docs directly alongside their system inventory. Documents are written in Markdoc, a powerful Markdown-based authoring format that supports custom tags and structured content.

Creating documents

To create a new document for a system:

  1. Navigate to the system detail page (Systems → click a system)
  2. Click the Documentation tab
  3. Click New Document (visible to EDITOR and OWNER roles)
  4. Enter a title and a slug (URL-safe identifier, auto-generated from the title)
  5. Write the document content using Markdoc syntax in the editor
  6. Save the document
Editor role required
Only workspace members with the EDITOR or OWNER role can create and edit documents. VIEWER members can read all documents without restrictions.

Viewing documents with TOC

When you open a document, Meridian renders the Markdoc source into a clean reading view. The page includes:

  • Rendered content — fully formatted text with headings, tables, code blocks, lists, and callout boxes
  • Table of contents sidebar — automatically generated from the document headings (h2 and h3), displayed as a sticky sidebar on the right side of the document. Clicking a TOC entry scrolls to that section.
  • Author and date — shows the author name and last updated timestamp at the top of the document
  • Edit link — visible to EDITOR and OWNER members, navigates to the editor for that document

If the Markdoc source contains syntax errors, a validation warning is displayed at the top of the rendered view.

Editing documents

The document editor provides a text area with Markdoc syntax. Documents support standard Markdown features plus Meridian-specific custom tags:

TagDescription
{% callout type="note" title="..." %}Renders a highlighted callout box. Types: note, warning, error, check

Here is an example of a complete system document written in Markdoc:

markdown
# Service Overview

This document describes the **payments-service** architecture and its integration points.

## Dependencies

The service calls the `orders-service` via HTTP to fetch order details before processing payment.

{% callout type="warning" title="Rate limiting" %}
The orders API enforces a 1000 req/min rate limit. Ensure your retry logic uses exponential backoff.
{% /callout %}

## API Endpoints

### POST /payments/charge

Initiates a payment for a given order.

**Request body:**
- `orderId` (string) — the order to charge
- `amount` (number) — amount in cents
- `currency` (string) — ISO 4217 currency code

**Response:** Returns a `paymentId` and initial `status`.

## Events Emitted

| Event | Broker | When |
|-------|--------|------|
| `payment.completed` | Kafka | Payment successfully processed |
| `payment.failed` | Kafka | Payment declined or errored |