OpenSearch is a fork, and the client library is the friction

The server APIs are compatible at the fork point and the official clients started refusing to talk to anything that is not Elasticsearch.

// the official client, from 7.14, checks the product
// header and refuses:
//   "The client noticed that the server is not
//    Elasticsearch and we do not support this unknown
//    product"

// so a fork needs its own client
composer require opensearch-project/opensearch-php

// the API surface is nearly identical; the namespace,
// the connection pool and the auth handling are not.

The product check is a deliberate incompatibility rather than a technical one, and it is the single largest migration cost — every place that constructs a client, every test double, every configuration key. The query DSL is unchanged at the fork point and diverges afterwards, so a codebase that only builds queries as arrays is much easier to move than one using a query builder from the client library. That is an argument for the thin abstraction that is usually over-engineering.