ReadMe CLI (@readme/cli)

Lint your docs, validate OpenAPI files, sync reference pages, preview locally, and set up CI checks from the terminal with @readme/cli.

@readme/cli is the command-line tool for ReadMe projects that use bi-directional sync. It runs against the cloned docs repository on your machine or in CI, and it doesn't upload anything: publishing happens when you merge. It does three jobs. It lints your pages before they reach the hub, it validates your OpenAPI documents, and it keeps your API Reference in step with those documents by creating a Markdown page for every endpoint you add and removing the page for every endpoint you delete. If you sync an OpenAPI document through Git, run oas:sync after every change to it.

If your project pushes content to ReadMe with rdme instead of syncing a repository, this isn't your CLI. See rdme CLI and GitHub Action Reference.

Prerequisites

  • A ReadMe project with Bi-Directional Sync enabled. Sync is available on Starter, Pro, and Enterprise (checked against readme.com/pricing on September 16, 2026).
  • A local clone of the synced repository, checked out to the branch that holds your docs. ReadMe writes each docs version to a Git branch with the same name, so a project on version v1.0 syncs to a branch called v1.0, and the repository's main branch may be empty. After checkout, ls should show a docs/ folder, a reference/ folder, or both.
  • Node.js and npx. Most commands read the project from the repository, so run them from inside the clone.

Running the CLI

No install step is required:

npx @readme/cli help

Every command below is run as npx @readme/cli <command>. The examples omit the prefix.

Commands

CommandWhat it doesRuns where
lintChecks frontmatter, slugs, links, content, and structure across the repository. See Lint for the full list.Local or CI
lint --fixRuns lint and rewrites the deterministic findings in placeLocal
oas:validate <file>Validates an OpenAPI document and exits non-zero on errorsLocal or CI
oas:syncCreates or updates API Reference pages from the OpenAPI documents in the repositoryLocal
devStarts a local preview server with hot reload. Beta.Local
dev --port 3000Same, on the port you chooseLocal
setup:githubWrites a GitHub Actions workflow that runs lint on every pull requestLocal, once
setup:github --blacksmithSame workflow, on Blacksmith runnersLocal, once
setup:gitlabGitLab CI equivalent of setup:githubLocal, once
setup:bitbucketBitbucket Pipelines equivalentLocal, once
setup:circleciCircleCI equivalentLocal, once
setup:rwxRWX equivalentLocal, once
versionsLists the project's versions and branchesLocal or CI
helpPrints the command listAnywhere

Global Flags

FlagEffect
--no-checkSkips the check that the current directory is a ReadMe docs repository
-v, --versionPrints the CLI version
-h, --helpPrints help for the command

Lint

lint is the command the setup:* workflows install. It reads every page in the repository and reports findings by file and line.

AreaWhat lint checks
FrontmatterInvalid YAML, unknown properties, misspelled properties
SlugsDuplicate slugs, badly formed slugs
ContentEmpty pages, invalid MDX-ish, broken recipes, content that won't be shown (for example, body text on a redirect page), missing MDX components
StructureFolder structure, sidebar nesting limits, missing or stale _order.yaml
npx @readme/cli lint

A clean run exits 0. Findings print with the file path, the rule, and the line, and the process exits non-zero, which is what fails a pull request check.

lint --fix corrects the findings that have exactly one right answer, such as frontmatter formatting, and leaves the rest for you. Run it locally before pushing, then commit the result.

📘 lint and the AI Linter are different tools. lint checks structure and validity in the repository. The AI Linter checks prose against your style rules on the published hub. A page can pass one and fail the other.

Validate and Sync OpenAPI Documents

oas:validate takes a path to a JSON or YAML OpenAPI document:

npx @readme/cli oas:validate openapi/openapi.yaml

It exits 0 on a valid document. Put it in CI ahead of lint so a broken spec fails before it reaches the reference.

oas:sync reads the OpenAPI documents in the repository and creates a Markdown page for every endpoint in the document, updates pages whose endpoint changed, and deletes pages whose endpoint was removed, one page per operation, with frontmatter linking each page to its spec. Run it after adding or changing a spec, then commit the generated pages.

npx @readme/cli oas:sync

For the full workflow from spec to a synced Try It! console, follow Keep Your API Docs Synced With OpenAPI.

Preview Docs Locally

dev serves your Guides and API Reference from the files in your clone, and reloads the browser the moment you save a file. You see the rendered page before it becomes a commit, without waiting for a branch preview.

  1. From inside the clone, on your version's branch, start the server:
npx @readme/cli dev

The first run downloads the CLI. When the server is up, it prints:

Dev server is running!
Changes to your files will auto-reload.
→ https://localhost:4523
  1. Open http://localhost:4523. It lands on your first Guides page, with Docs, Reference, and Recipes tabs in the header and a dev server BETA badge.
  2. Open any file under docs/ in a text editor, change a word, and save. The browser reloads with the change as soon as the file is written; there's no build step.
  3. Stop the server with Ctrl+C.

To run on a different port:

npx @readme/cli dev --port 3000

What Renders Locally

The dev server is in beta. It has your files and nothing else, which is why it starts in a second and also why some of the hub doesn't render.

SectionLocal dev serverHub
Guides, including MDX and custom components defined in the repositoryFull renderFull render
API Reference endpoint pagesMethod, path, and response codes from the OpenAPI document, with a notice that the full reference renders in ReadMeRequest and response schemas, code samples, authentication, Try It!
Try It!Not availableAvailable
Personalized Docs and My RequestsNot availableAvailable to logged-in developers
RecipesFalls back to raw source with an "Error rendering MDX" messageFull render
Changelog, Custom Pages, theme, navigation, Ask AINot renderedRendered

Try It! needs your API and the reader's credentials, Personalized Docs needs the reader's identity, and Ask AI needs the hub's index. For those, push to a branch and use the branch preview ReadMe builds at /your-branch/update/ where the full hub renders. The local server is for the edit-save-look loop before that push.

Set Up CI

setup writes a workflow file that runs lint on every pull request. Run it once, from the repository root:

npx @readme/cli setup

It detects your CI platform from the repository, tells you which one it found, and asks you to confirm before writing anything. To skip detection, name the platform directly. Each one writes a different file:

CommandPlatformFile Written
setup:githubGitHub Actions.github/workflows/readme-lint.yml
setup:githubGitLab CI.gitlab-ci.yml
setup:bitbucketBitbucket Pipelinesbitbucket-pipelines.yml
setup:circleciCircleCI.circleci/config/yml
setup:rwxRWX Mintmint/readme-lint.yml
FlagEffect
--blacksmithUse Blacksmith runners. GitHub Actions only.
-y, --yesSkip the confirmation prompt
npx @readme/cli setup:github --blacksmith
npx @readme/cli setup:gitlab -y

Commit the generated file. From the next pull request, lint runs as a check. Edit the generated file to add oas:validate or other steps.

A github-actions bot comment titled ReadMe Docs Lint on a pull request, with a table of files and their error or warning messages and a tip to run npx @readme/cli lint --fix locally.

The comment lint posts on a pull request when it finds errors or warnings.

Components

components works with MDX components from the terminal: browse the component library, install one into your repository, or generate a new one. It's in beta.

npx @readme/cli components --help
FlagEffect
-f, --forceRefetch the component library from GitHub instead of using the 24-hour cache
--model nameModel used by new to generate a component: haiku, sonnet, or opus. Default sonnet.
-y, --yesOverwrite existing files without prompting

For what a component is and how it's used in a page, see Custom Components.

Troubleshooting

This doesn't look like a ReadMe docs repo. We couldn't find a /docs or /reference folder. You're on a branch with no docs content, usually main in a repository where ReadMe syncs to a version-named branch. Run git branch -a, check out the branch named after your docs version, and try again. If every branch is empty, the ReadMe project has no pages yet; add one in the editor, then git pull. Don't use --no-check to get past this for dev or oas:sync, because they have nothing to work with without those folders. It's fine for oas:validate on a file outside a docs repository.

lint passes locally and fails in CI. The CI job is on a different commit. Confirm the workflow checks out the pull request's head and that you pushed after running lint --fix.

oas:sync didn't pick up my spec. Confirm the file is in the repository's OpenAPI folder and that oas:validate passes on it. An invalid document is skipped.

The dev server port is already in use. Another process has 4523. Start with a different one: npx @readme/cli dev --port 3001.

A Recipes page on the dev server shows raw MDX, or an endpoint page shows only the method, path, and response codes. Both are expected in the current beta. See What Renders Locally.

  • Whether oas:validate and oas:sync take a path argument, and which folder oas:sync reads from. The table and examples assume a path for validate and no argument for sync.
  • Exact wording of the project-check error message quoted in Troubleshooting. Replace with the real string.
  • Whether setup:* commands overwrite an existing workflow on re-run. I wrote that they don't; confirm or delete the sentence.
  • Node.js minimum version, and whether a global install (npm install -g @readme/cli) is supported and worth documenting alongside npx.
  • What dev renders and doesn't. The "Try It! and Personalized Docs render differently or not at all" sentence is an inference from it being a local server; confirm with the CLI team or cut to "some features are unavailable locally."

Did this page help you?