Announcing the Distilled OpenSearch SDK
Search, index, inspect, and administer OpenSearch clusters through 684 Effect-native operations.
Search systems sit on a demanding boundary: workloads are concurrent, responses can be large, cluster health changes under load, and transient failures are normal rather than exceptional. @kevinmichaelchen/distilled-opensearch brings 684 official OpenSearch REST operations into Effect with runtime schemas and explicit operational policy.
OpenSearch, at a glance
OpenSearch is an open-source search and analytics suite used for full-text search, observability, log analytics, vector search, and security analytics. Its REST API covers documents, indexes, mappings, queries, aggregations, snapshots, cluster administration, and a broad plugin ecosystem. The project maintains its machine-readable source of truth in opensearch-project/opensearch-api-specification.
OpenSearch
REST API reference
Official specification
Distilled implementation
Why Effect and Distilled?
OpenSearch work rarely ends with one request. An ingestion flow may create an index, bulk-write documents, wait for a refresh, verify cluster health, and retry only the failures that are safe to repeat. Effect gives that sequence one model for typed failures, timeouts, backoff, concurrency, cancellation, tracing, and dependency injection.
Distilled adds a reviewable API boundary. Inputs and outputs are backed by runtime schemas where the official contract is tractable; known HTTP statuses become typed errors; retry hints are preserved; secrets are redacted; and configuration is an explicit layer that tests can replace. The result is a better fit for long-lived search infrastructure than a bag of loosely related promise calls.
How we made the SDK
Use OpenSearch's source of truth
Mirror the published artifact
Generate the complete surface
Add cluster-aware runtime policy
No prose was scraped into a pseudo-spec, and no generated file is edited by hand. The SDK pins an exact source commit, applies reviewable RFC 6902 patches only when needed, and fails CI if regeneration drifts.
Code Examples
Set OPENSEARCH_URL and your cluster credentials, then install:
npm install @kevinmichaelchen/distilled-opensearch effectpnpm add @kevinmichaelchen/distilled-opensearch effectbun add @kevinmichaelchen/distilled-opensearch effectimport * as Effect from "effect/Effect";
import * as Layer from "effect/Layer";
import * as FetchHttpClient from "effect/unstable/http/FetchHttpClient";
import {
CredentialsFromEnv,
clusterHealth0,
indicesCreate0,
search2,
} from "@kevinmichaelchen/distilled-opensearch";
const OpenSearchLive = Layer.mergeAll(
FetchHttpClient.layer,
CredentialsFromEnv,
);
Search an index
Run a query-string search across an index pattern and return the most recent matching logs.
const searchRecentErrors = search2({
index: "application-logs-*",
q: "level:error AND service:checkout",
size: 25,
sort: "@timestamp:desc",
}).pipe(Effect.provide(OpenSearchLive));
Create an index
Create a versioned application-log index with explicit shard settings and a small mapping.
const createLogIndex = indicesCreate0({
index: "application-logs-2026.07",
settings: {
number_of_shards: 3,
number_of_replicas: 1,
refresh_interval: "5s",
},
mappings: {
properties: {
"@timestamp": { type: "date" },
level: { type: "keyword" },
message: { type: "text" },
},
},
}).pipe(Effect.provide(OpenSearchLive));
Wait for cluster health
Gate an ingestion or deployment workflow until the cluster reaches at least yellow health.
const waitForClusterHealth = clusterHealth0({
wait_for_status: "yellow",
timeout: "30s",
}).pipe(Effect.provide(OpenSearchLive));
The same package can create indexes and mappings, index or update documents, run Query DSL searches and aggregations, manage snapshots, inspect nodes, and call supported plugin APIs.
OpenSearch’s dotted operation IDs become ordinary TypeScript camelCase names, so cluster.health.0 is exported as clusterHealth0. Numeric suffixes remain because the official specification models each HTTP method and path form as a distinct operation; for example, search2 is the indexed GET /{index}/_search variant.
Available now
Read the OpenSearch SDK guide, inspect the implementation, browse the spec mirror, or install @kevinmichaelchen/distilled-opensearch.