OnlyCLI vs Stainless CLI: Which OpenAPI CLI generator fits your stack?

Both OnlyCLI and Stainless can turn API descriptions into command-line tools. They solve related problems with different philosophies:

  • OnlyCLI is an open-source, standalone generator. You point it at any OpenAPI 3.x document; it emits a native Go/Cobra project you own, build, and ship—no hosted platform required.
  • Stainless is a commercial platform oriented around SDK ecosystems. Its CLI is typically produced alongside language SDKs (for example Go) from Stainless-managed configuration and workflows, not as a fully isolated “spec in, binary out” loop.

This page compares capabilities so you can decide when each approach makes sense.


How each tool fits in your workflow

OnlyCLI: spec-first, self-contained

OnlyCLI reads YAML or JSON OpenAPI 3.x from a path or URL, generates a CLI project, and you compile a single binary. The output includes HTTP client code, subcommands aligned with your spec, and standard Go tooling for distribution. For LLM agents, the stable command tree and --help text are the primary discovery surface; you can layer a hand-written SKILL.md if you want a compact onboarding doc.

Stainless: platform-first, SDK-centric

Stainless targets teams that want maintained SDKs plus a CLI in one pipeline. Configuration and generation are tied to Stainless’s model (including repository and edition settings). The CLI wraps generated SDK behavior and ships with platform features such as an interactive explorer, auto-generated man pages, and Homebrew distribution.


Feature comparison: OnlyCLI vs Stainless CLI

Feature OnlyCLI Stainless CLI
License MIT (open source) Commercial platform / subscription
Dependencies Standalone generator; generated CLI is plain Go + modules CLI generation is tied to the Go SDK target and Stainless config
Input Any OpenAPI 3.x (file or URL) Stainless configuration + workflow (not “drop any spec” in isolation)
Output formats Shared with Stainless: json, pretty, yaml, jsonl, raw. Only on OnlyCLI: table, csv. Shared with OnlyCLI: json, pretty, yaml, jsonl, raw. Only on Stainless: interactive explore.
GJSON transform Yes (--transform, GJSON syntax; tidwall/gjson) Yes (--transform, GJSON syntax)
Auto-pagination Multiple schemes with automatic detection from response headers and body: Link (rel="next"), cursor-based, cursor-URL, offset, and page-number pagination (--page-limit). Multiple schemes (page number, cursor, cursor URL, offset) with lazy loading; explicit scheme configuration in Stainless config.
Streaming Yes — --stream for SSE (text/event-stream) and NDJSON responses Yes — streaming endpoints handled similarly to auto-pagination
OAuth2 When the spec defines OAuth2: auth login with device flow or client credentials (--client-id, optional --client-secret) Supported via platform/SDK auth patterns
@file body input Yes: --data @path.json, --data @- for stdin SDK/CLI patterns vary; not the same flag surface as OnlyCLI
Nested request args Yes: body fields map to dotted JSON paths (e.g. metadata.labels) Nested flags / resource-oriented args (e.g. --name.full-name)
Multi-profile Yes: config + --profile, config use-profile Profile / environment patterns depend on generated project
Dry-run Yes (--dry-run: print method, URL, headers, body preview) Varies by generated CLI
Retry Yes (--max-retries with backoff + Retry-After) Platform / client may include retries
HTTP/2 Yes (ForceAttemptHTTP2 on the transport) Go-based clients commonly use HTTP/2 where available
Compression Requests advertise gzip, deflate; responses can be gunzipped Typically supported in generated stacks
Shell completions OpenAPI enum flags get Cobra completion callbacks; wire shell scripts via Cobra docs as needed Bash, zsh, fish, PowerShell (documented)
Interactive TUI No dedicated explorer Explore-style interactive mode
SDK generation CLI only (no multi-language SDK emit) SDKs + CLI as part of the product
Man pages Can be produced from Cobra help via your docs pipeline; not bundled by OnlyCLI itself Auto-generated for each CLI tool; included in Homebrew distribution
Homebrew / install GitHub releases + install.sh; GoReleaser builds archives; Homebrew tap is up to your release story Stainless automates distribution including Homebrew with man pages

GJSON and output formats: Both tools support the same --transform flag with GJSON syntax and the same core output formats (json, pretty, yaml, jsonl, raw). OnlyCLI adds table and csv; Stainless adds the interactive explorer (see the table above).

Where Stainless leads

Stainless’s CLI generator has invested heavily in areas that matter for production SDK ecosystems:

  • SDK ecosystems: Multi-language SDKs plus a CLI from one managed pipeline—not a CLI-only generator.
  • Interactive TUI: Explore-style interactive mode for browsing resources and operations.
  • Man pages: Stainless auto-generates man pages for each CLI tool and bundles them in Homebrew distributions. OnlyCLI can produce man pages via Cobra’s doc generation, but this is not automated.
  • Homebrew distribution: Stainless automates release packaging including Homebrew with man pages; OnlyCLI typically uses GitHub releases, install.sh, or GoReleaser—Homebrew taps are up to you.

Where OnlyCLI leads

  • Table and CSV output: OnlyCLI includes --format table and --format csv for array-of-objects responses—useful for spreadsheets, awk pipelines, and quick terminal inspection. Stainless does not offer these formats.
  • Open source: MIT license, no vendor lock-in, no subscription.
  • Any-spec portability: Point at any public or private OpenAPI 3.x URL and get a CLI. No platform account or configuration file required.
  • Go template output: --template with Go text/template for fully custom formatting.

When to choose OnlyCLI

  • You want MIT-licensed code and no vendor lock-in.
  • You already have (or only care about) standard OpenAPI 3.x—including public specs from GitHub, vendor bundles, or CI-generated documents.
  • You need a dedicated binary per API for developers, CI/CD, or LLM agents (stable --help and flags; optional SKILL.md you maintain).
  • You want multi-scheme auto-pagination with runtime auto-detection and streaming (--stream for SSE and NDJSON) without a commercial SDK platform.
  • You care about CLI ergonomics: table, csv, Go templates, @file bodies, and dry-run without adopting a full SDK platform.

When to choose Stainless

  • You want official SDKs (Go, and other targets) and a CLI from one managed pipeline.
  • You prefer a hosted / commercial solution with Stainless handling updates, editions, and repository integration.
  • Your team values an interactive explorer (TUI-style) for browsing resources and operations, plus auto-generated man pages and Homebrew distribution.
  • You prefer explicit pagination scheme configuration in Stainless config over runtime auto-detection from API responses.
  • You are already standardizing on Stainless config rather than raw spec-only workflows.

Code comparison: the same API with both approaches

Below, the goal is identical: a Petstore-style POST /pets that accepts JSON { "id": 1, "name": "doggie", "tag": "nice" }. The invocation style differs because OnlyCLI generates flags from your OpenAPI requestBody schema, while Stainless uses its resource-oriented CLI layout tied to the generated SDK.

OnlyCLI: generate from OpenAPI, then call the binary

# 1) Generate a CLI project from the spec
onlycli generate \
  --spec https://petstore3.swagger.io/api/v3/openapi.json \
  --name petstore \
  --out ./petstore-cli

cd petstore-cli && go mod tidy && go build -o petstore .

# 2) Call the operation (example matches typical OpenAPI pet schemas)
./petstore pets create --id 1 --name doggie --tag nice --format pretty

You can also pass a full JSON body from disk:

echo '{"id":1,"name":"doggie","tag":"nice"}' > body.json
./petstore pets create --data @body.json

Stainless: configure targets, generate via Stainless, then use the shipped CLI

Stainless does not mirror “single onlycli generate --spec URL” one-to-one; you add a cli target (and typically a go SDK target) in your Stainless configuration, run Stainless generation in your normal pipeline, then install the produced binary. Conceptually:

# stainless.yaml (illustrative — real keys depend on your Stainless edition / docs)
organization: your-org
project: petstore

targets:
  go:
    package_name: petstore
    production_repo: github.com/your-org/petstore-go
  cli:
    binary_name: petstore
    # CLI wraps the Go SDK; resource/method names follow Stainless output

After generation and build (per Stainless CLI documentation):

# Illustrative invocation shape (exact subcommands come from generated output)
petstore pets create --name.full-name doggie

Takeaway: OnlyCLI optimizes for direct OpenAPI -> your repo -> go build. Stainless optimizes for Stainless-managed SDK + CLI with explorer, man pages, and platform integration. Both support auto-pagination (multiple schemes) and streaming; OnlyCLI auto-detects pagination from responses, while Stainless relies on configured schemes and lazy loading.


Further reading


Summary

If you need… Lean toward
Open source, any OpenAPI 3.x, table/csv output, Go templates, pagination auto-detection OnlyCLI
Multi-language SDKs, interactive explorer, auto-generated man pages, Homebrew distribution, explicit pagination config Stainless

Both can produce professional CLIs with GJSON transforms, core output formats (json, pretty, yaml, jsonl, raw), auto-pagination, and streaming. The decision is whether your center of gravity is a standalone spec-driven binary you own (OnlyCLI) or a commercial SDK + CLI platform (Stainless).