Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Mergeway Overview

Last updated: 2025-10-20

Mergeway is a lightweight CLI that keeps metadata honest by treating schemas as code. Instead of juggling spreadsheets or custom scripts, you describe entities in YAML/JSON, run a quick validation, and catch broken references before they reach production.

What the CLI Does

  • Stores entity definitions and relationships in version-controlled files.
  • Validates schemas and records so required fields and references stay consistent.
  • Generates simple reports you can attach to pull requests or issues.

Why Teams Use Mergeway

  • Fast feedback: One command surfaces missing fields, enum mismatches, or invalid references.
  • Git-native: Changes live in branches and pull requests, making reviews trivial.
  • Lightweight: No server component—just a binary that runs locally or in CI.

Where to Go Next

  1. Install Mergeway (or build from source).
  2. Follow the First Validation guide.
  3. Review the Concepts and Schema Format when you define entities.
  4. Browse through the CLI Reference handy for the command syntax.

Updates land in the Changelog. File GitHub issues for questions, bugs, or requests.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

Install Mergeway

Last updated: 2025-10-22

Pick the method that fits your setup. Each installs a single binary named mw.

Option 1 – Download a Release (macOS, Linux)

curl -L https://github.com/mergewayhq/mergeway-cli/releases/download/v0.11.0/mw-
$(uname | tr '[:upper:]' '[:lower:]')-amd64.tar.gz \
  | tar -xz
sudo mv mw /usr/local/bin/

Check the published SHA-256 checksum before moving the binary if you operate in a locked-down environment.

Option 2 – Go Install (for contributors)

go install github.com/mergewayhq/mergeway-cli@latest

This drops the binary in $GOPATH/bin. Prefer tagged versions in production.

Verify

mw --version

You should see something similar to:

Mergeway CLI v0.11.0 (commit abc1234)

If the command is missing, confirm that the installation path is on your PATH.

Move on to the Getting Started guide once the binary is available.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

Getting Started with Mergeway

Last updated: 2025-10-22

Goal: scaffold a workspace, define an entity, evolve the layout as requirements grow, and learn the core Mergeway commands end-to-end.

All commands assume the mw binary is on your PATH.

1. Scaffold a Workspace with Inline Data

mkdir farmers-market
cd farmers-market
mw init

mw init creates a mergeway.yaml entry file. Replace its contents with an inline entity that also carries a few inline records:

mergeway:
  version: 1

entities:
  Category:
    description: Simple lookup table for product groupings
    identifier: slug
    fields:
      slug:
        type: string
        required: true
      label:
        type: string
        required: true
    data:
      - slug: produce
        label: Fresh Produce
      - slug: pantry
        label: Pantry Staples

Try a few commands:

mw entity list
mw entity show Category
mw list --type Category
mw validate

At this stage everything lives in a single file—perfect for tiny datasets.

2. Move Records into External YAML Files

As the table grows, shift the data into dedicated files. Create a folder for category data and move the records there:

mkdir -p data/categories
cat <<'YAML' > data/categories/categories.yaml
items:
  - slug: produce
    label: Fresh Produce
  - slug: pantry
    label: Pantry Staples
  - slug: beverages
    label: Beverages
YAML

Update mergeway.yaml so Category reads from the new file:

mergeway:
  version: 1

entities:
  Category:
    description: Simple lookup table for product groupings
    identifier: slug
    include:
      - data/categories/*.yaml
    fields:
      slug:
        type: string
        required: true
      label:
        type: string
        required: true

Re-run the commands to see the effect:

mw list --type Category
mw get --type Category beverages
mw validate

3. Split Schema Definitions and Add JSON Data

Larger workspaces benefit from keeping schemas in their own files. Create an entities/ folder for additional definitions:

mkdir -p entities

Add a new Product entity that pulls from a JSON file using a JSONPath selector:

cat <<'YAML' > entities/Product.yaml
mergeway:
  version: 1

entities:
  Product:
    description: Market products with category references
    identifier: sku
    include:
      - path: data/products.json
        selector: "$.items[*]"
    fields:
      sku:
        type: string
        required: true
      name:
        type: string
        required: true
      category:
        type: Category
        required: true
      price:
        type: number
        required: true
YAML

Create the JSON data file the schema expects. Notice that one product references a household category that we haven't defined yet:

cat <<'JSON' > data/products.json
{
  "items": [
    {"sku": "apple-001", "name": "Honeycrisp Apple", "category": "produce", "price": 1.25},
    {"sku": "oat-500", "name": "Rolled Oats", "category": "pantry", "price": 4.99},
    {"sku": "soap-010", "name": "Castile Soap", "category": "household", "price": 6.75}
  ]
}
JSON

Finally, have mergeway.yaml pull in any external schemas:

mergeway:
  version: 1

include:
  - entities/*.yaml

entities:
  Category:
    description: Simple lookup table for product groupings
    identifier: slug
    include:
      - data/categories/*.yaml
    fields:
      slug:
        type: string
        required: true
      label:
        type: string
        required: true

Explore the richer workspace:

mw entity list
mw entity show Product
mw list --type Product
mw validate

mw validate now reports a broken reference because the household category doesn't exist yet:

phase: references
type: Product
id: soap-010
file: data/products.json
message: referenced Category "household" not found

Add the missing category to the YAML file and validate again:

cat <<'YAML' >> data/categories/categories.yaml
- slug: household
  label: Household Goods
YAML

mw validate

With the additional category in place, validation succeeds and both entities are in sync.

4. Export Everything as JSON

Collect the full dataset into a single snapshot:

mw export --format json --output market-snapshot.json
cat market-snapshot.json

You're Done!

Nice work—you’ve defined entities inline, moved data to YAML, added JSON-backed entities, and exercised the key Mergeway commands. You're ready to scale the workspace to your team’s needs.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

Concepts

Last updated: 2025-10-22

A Mergeway workspace is just a folder with a few predictable parts. Knowing the vocabulary makes the CLI output easier to read.

Building Blocks

  • Workspace: Folder tracked in Git that contains mergeway.yaml, schemas, and optional objects. All commands run from here.
  • Schema: YAML/JSON that defines fields and references. Each file describes one entity.
  • Object: Optional data instances stored under data/.
  • Reference: A link from one schema or field to another (type: ref). Mergeway validates referential integrity.

Validation Flow

  1. Mergeway loads mergeway.yaml to locate schemas and records.
  2. Schemas are parsed and checked for required fields, types, and references.
  3. Records (if present) are validated against their schemas.

For field syntax and configuration options, see the Schema Format.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

Schema Format

Last updated: 2025-10-22

Schemas can live entirely inside mergeway.yaml or be split across additional include files (for example under an entities/ folder) for readability. Likewise, object data may be defined inline or stored under data/. Pick the mix that matches your editing workflow—comments below highlight conventions for modular repositories without requiring them. See Storage Layout for heuristics on choosing a structure.

Configuration Entry (mergeway.yaml)

The workspace entry file declares the schema version and the files to load:

mergeway:
  version: 1

include:
  - entities/*.yaml
  • mergeway.version tracks breaking changes in the configuration format (keep it at 1).
  • include is a list of glob patterns. Each matching file is merged into the configuration. Patterns must resolve to at least one file; otherwise Mergeway reports an error.

Schema Files (optional includes)

A schema file declares one or more entity definitions. Store them in whichever folder makes sense for your workflow (many teams use entities/); the location has no semantic impact. The example below defines a Post entity:

mergeway:
  version: 1

entities:
  Post:
    description: Blog posts surfaced on the marketing site
    identifier: id
    include:
      - data/posts/*.yaml
    fields:
      id: string
      title:
        type: string
        required: true
        description: Human readable title
      body: string
      author:
        type: User
        required: true
    data:
      - id: post-inline
        title: Inline Example
        author: user-alice
        body: Inline data lives in the schema file.

For advanced scenarios you can expand identifier into a mapping:

mergeway:
  version: 1

entities:
  Post:
    description: Blog posts surfaced on the marketing site
    identifier:
      field: id
      generated: true
    include:
      - data/posts/*.yaml
    fields:
      # ...

When several objects live in one file, provide a JSONPath selector to extract them:

mergeway:
  version: 1

entities:
  User:
    description: Directory of account holders sourced from JSON
    identifier: id
    include:
      - path: data/users.json
        selector: "$.users[*]"
    fields:
      # ...

Strings remain a shorthand for path with no selector; Mergeway then reads the entire file as a single object (or uses the items: array if present).

Required Sections

KeyDescription
identifierName of the identifier field inside each record (must be unique per entity). Provide either a string (the field name) or a mapping with field, optional generated, and pattern. The identifier value itself can be a string, integer, or number.
includeList of data sources. Each entry can be a glob string (shorthand) or a mapping with path and optional selector property. Omit only when you rely exclusively on inline data. Without a selector, Mergeway treats the whole file as a single object.
fieldsMap of field definitions. Use either the shorthand field: type (defaults to optional) or the expanded mapping for advanced options.
dataOptional array of inline records. Each entry must contain the identifier field and follows the same schema rules as external data files.

Add description anywhere you need extra context. Entities accept it alongside identifier, and each field definition supports its own description value.

Inline Data

Inline data is helpful for tiny lookup tables or bootstrapping a demo without creating additional files. Define records directly inside the entity specification:

mergeway:
  version: 1

entities:
  Person:
    description: Lightweight profile objects
    identifier: id
    include:
      - data/people/*.yaml
    fields:
      id: string
      name:
        type: string
        required: true
        description: Preferred display name
      age: integer
    data:
      - id: person-1
        name: Alice
        age: 30
      - id: person-2
        name: Bob
        age: 42

Inline records are loaded alongside file-based data. If a record with the same identifier exists both inline and on disk, the file wins. Inline records are read-only at runtime—mw data update and mw data delete target files only.

Field Shorthand

When a field only needs a type, map entries can use the compact field: type syntax. These fields default to required: false and behave identically to the expanded form otherwise. Switch to the full mapping whenever you need attributes like required, repeated, or format.

Field Attributes

AttributeExampleNotes
typestring, number, boolean, list[string], UserLists are written as list[type]. A plain string (e.g., User) references another type.
requiredtrue / falseRequired fields must appear in every record.
repeatedtrue / falseIndicates an array field.
descriptionService owner teamOptional but recommended.
enum[draft, active, retired]Allowed values.
defaultAny scalarValue injected when the field is missing.

Keep schema files small and focused—one entity per file is the easiest to maintain.

Data Files (data/...)

Each data file must declare a type and provide the fields required by its entity definition:

type: Post
id: post-001
title: Launch Day
author: user-alice
body: |
  We are excited to announce the product launch.

You can store one object per file (as above) or provide an items: array to keep several objects together. Adding the type key is optional when the file already matches the schema’s include, but keeping it makes each file self-describing.

JSONPath selectors let you extract objects from nested structures—handy when you need to read a subset of a larger document. For example, selector: "$.users[*]" walks through the users array in a JSON file and emits one record per element. Mergeway validates that the selector returns objects; any other shape triggers a format error.

Identifier fields accept numeric payloads as well. For example, the following record is valid when the schema marks id as an integer:

type: Person
id: 42
name: Numeric Identifier

Good Practices

  • Prefer references (type: User) over duplicating identifiers.
  • Group files in predictable folders (data/posts/, data/users/, etc.).
  • Run mw validate after every change to catch problems immediately.

Need more context? Return to the Concepts page for the bigger picture.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

CLI Reference

Last updated: 2025-10-22

Every command shares a set of global flags:

FlagDescription
--rootPath to the workspace (defaults to .).
--configExplicit path to mergeway.yaml (defaults to <root>/mergeway.yaml).
--formatOutput format (yaml or json, default yaml).
--fail-fastStop after the first validation error (where supported).
--yesAuto-confirm prompts (useful for delete).
--verboseEmit additional logging.

Repository setup

Schema utilities

Object operations

Need a refresher on terminology? See the Concepts chapter.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw init

Last updated: 2025-10-22

Synopsis: Scaffold the directory layout and default configuration for a Mergeway workspace.

Usage

mw [global flags] init

No command-specific flags. Add the global --root flag if you want to scaffold somewhere other than the current directory.

Example

mkdir blog-metadata
cd blog-metadata
mw init

Output:

Initialized repository at .

mw init ensures a starter mergeway.yaml exists in the target directory. Add folders such as entities/ or data/ yourself once the project grows; keeping everything in a single file is perfectly valid. Re-run the command safely—it never overwrites existing files. The default configuration contains:

# mw configuration
mergeway:
  version: 1

entities: {}
  • mw validate — run after adding schema and data files.
  • mw config lint — verify configuration changes once you edit mergeway.yaml.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw validate

Last updated: 2025-10-22

Synopsis: Check schemas, records, and references, emitting formatted errors when something is wrong.

Usage

mw [global flags] validate [--phase format|schema|references]... [--fail-fast]
FlagDescription
--phaseOptional. Repeat to run a subset of phases. By default all phases run (format, schema, then references).
--fail-fastStop after the first error. Defaults to the global --fail-fast flag.

When you request the references phase, Mergeway automatically includes the schema phase so reference checks have the information they need.

Examples

Run the command from the workspace root (or add --root to point elsewhere).

Validate the current workspace:

mw validate

Add --format json when you need machine-readable output.

Output:

validation succeeded

Run validation after introducing a breaking schema change:

mw validate

Output when the Post schema requires an author but the record is missing it:

- phase: schema
  type: Post
  id: post-001
  file: data/posts/launch.yaml
  message: missing required field "author"

The command writes errors to standard output and still exits with status 0, so automation should check whether any errors were returned.

  • mw config lint — validate configuration without loading data.
  • mw list — locate the objects mentioned in validation errors.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw entity list

Last updated: 2025-10-22

Synopsis: Show every entity Mergeway discovered from your configuration.

Usage

mw [global flags] entity list

No command-specific flags. Add the global --root flag if you need to inspect another workspace.

Example

List entities for the examples/ workspace bundled with the repository:

mw --root examples/full entity list

Output:

Comment
Post
Tag
User

Entities are listed alphabetically.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw entity show

Last updated: 2025-10-22

Synopsis: Print the normalized schema for a given entity.

Usage

mw [global flags] entity show <entity>

No additional flags. Use --format json if you prefer JSON output, and add the global --root flag when working outside the workspace root.

Example

Show the Post entity in YAML form:

mw --root examples/full --format yaml entity show Post

Output (abridged):

name: Post
source: .../examples/full/entities/Post.yaml
identifier:
  field: id
filepatterns:
  - data/posts/*.yaml
fields:
  title:
    type: string
    required: true
  author:
    type: User
    required: true
  body:
    type: string


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw config lint

Last updated: 2025-10-22

Synopsis: Validate configuration files (including includes) without touching data.

Usage

mw [global flags] config lint

No additional flags.

Example

Run the command from the workspace root (or pass --root):

mw config lint

Output:

configuration valid

If the command encounters a problem (for example, an include pattern that matches no files), it prints the error and exits with status 1.

Run this command whenever you edit mergeway.yaml or add new entity definitions to catch syntax mistakes early.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw config export

Last updated: 2025-10-22

Synopsis: Emit a JSON Schema for one of your types.

Usage

mw [global flags] config export --type <type>
FlagDescription
--typeRequired. Type identifier to export.

Example

Run the command from the workspace root (or pass --root). Export the Post type as JSON Schema:

mw --root examples --format json config export --type Post

Output (abridged):

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "properties": {
    "author": {
      "type": "string",
      "x-reference-type": "User"
    },
    "title": {
      "type": "string"
    }
  },
  "required": ["id", "title", "author"],
  "type": "object"
}

Fields that reference other types include the x-reference-type hint.

Validate your workspace (mw config lint or mw validate) after editing type files to ensure the exported schema stays in sync.

  • mw entity show — view the full Mergeway representation of an entity.
  • mw validate — ensure data conforms to the schema you just exported.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw list

Last updated: 2025-10-22

Synopsis: List object identifiers for a given type, optionally filtered by a field.

Usage

mw [global flags] list --type <type> [--filter key=value]
FlagDescription
--typeRequired. Type identifier to query.
--filterOptional key=value string used to filter objects before listing their IDs. The comparison is a simple string equality check.

Example

Run the command from the workspace root. If you need to operate on another directory, add the global --root flag.

List all posts in the quickstart workspace:

mw list --type Post

Output:

post-001

Filter by author:

mw list --type Post --filter author=user-alice

Output:

post-001
  • mw get — inspect a specific object.
  • mw create — add a new object when an ID is missing.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw get

Last updated: 2025-10-22

Synopsis: Print the fields of one object.

Usage

mw [global flags] get --type <type> <id>
FlagDescription
--typeRequired. Type identifier that owns the object.
<id>Required positional argument representing the object identifier.

Use --format json if you prefer JSON output.

Example

Run the command from the workspace root. Use --root if you need to target another workspace.

Fetch the post-001 record as YAML:

mw --format yaml get --type Post post-001

Output:

author: user-alice
body: |
    We are excited to announce the product launch.
id: post-001
title: Launch Day
  • mw list — discover identifiers before calling get.
  • mw update — change object fields.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw create

Last updated: 2025-10-22

Synopsis: Create a new object file that conforms to an entity definition.

Usage

mw [global flags] create --type <type> [--file path] [--id value]
FlagDescription
--typeRequired. Type identifier to create.
--fileOptional path to a YAML/JSON payload. If omitted, data is read from STDIN.
--idOptional identifier override. Useful when the payload omits the id field.

Example

Run the command from the workspace root (or pass --root if you are elsewhere). Create a user by piping a YAML document and letting Mergeway write the file under data/users/:

cat <<'PAYLOAD' > user.yaml
name: Bob Example
PAYLOAD

mw create --type User --file user.yaml --id user-bob

Output:

User user-bob created

The command writes data/users/user-bob.yaml with the provided fields. Remove the temporary user.yaml file afterward and run mw validate to confirm the new object passes checks.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw update

Last updated: 2025-10-22

Synopsis: Modify an existing object. You can replace the object entirely or merge in a subset of fields.

Usage

mw [global flags] update --type <type> --id <id> [--file path] [--merge]
FlagDescription
--typeRequired. Type identifier.
--idRequired. Object identifier to update.
--fileOptional path to a YAML/JSON payload (defaults to STDIN).
--mergeMerge fields into the existing object instead of replacing it.

Example

Run the command from the workspace root (or add --root to target another workspace). Update a post title by merging in a tiny payload:

cat <<'PAYLOAD' > post-update.yaml
title: Launch Day (Updated)
PAYLOAD

mw update --type Post --id post-001 --file post-update.yaml --merge

Output:

Post post-001 updated

Without --merge, the payload replaces the entire object.

Run mw validate after significant updates to confirm references still resolve. Delete the temporary payload file once you are done with the update.



Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw delete

Last updated: 2025-10-22

Synopsis: Remove an object file from the workspace.

Usage

mw [global flags] delete --type <type> <id>
FlagDescription
--typeRequired. Type identifier.
<id>Required positional argument identifying the object to delete.

The command prompts for confirmation unless you pass the global --yes flag.

Place global flags (like --yes or --root) before the command name.

Example

Run the command from the workspace root (or add --root to target another workspace). Delete a user without prompting:

mw --yes delete --type User user-bob

Output:

User user-bob deleted
  • mw list — confirm an object’s identifier before deleting.
  • mw create — recreate an object if you delete the wrong one.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw export

Last updated: 2025-10-22

Synopsis: Export repository objects into a single JSON or YAML document.

Usage

mw [global flags] export [--output <path>] [entity...]
FlagDescription
--outputOptional path to write the exported document. Defaults to STDOUT.
entity...Optional list of type names to include. Omitting the list exports every entity defined in the workspace.

The export format matches the global --format flag (yaml by default).

Examples

Export every entity in the repository as YAML to the terminal:

mw export

Export only the User and Post entities as JSON into a file:

mw --format json export --output snapshot.json User Post

Each top-level key in the output map is the entity name; the value is an array of records sorted by ID.

  • mw list — inspect available identifiers before exporting.
  • mw get — fetch a single object instead of the full dataset.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)

mw version

Last updated: 2025-10-22

Synopsis: Display the CLI build metadata (semantic version, commit, build date).

Usage

mw [global flags] version

No additional flags.

This command does not touch workspace files; global flags like --root are ignored.

Example

mw --format json version

Output:

{
  "version": "0.1.0",
  "commit": "a713be5",
  "buildDate": "2025-10-22T18:25:03Z"
}

Values change with each build; use the command to confirm which binary produced a validation report or data change.

  • mw validate — include the CLI version in validation artifacts for traceability.


Generated at 2025-10-30 22:44:13 (commit: 3a1f254)