elasticsearch-js
The official Node.js client for Elasticsearch, giving JavaScript and TypeScript apps a typed, fully-featured way to talk to an Elasticsearch cluster.
Repository Health
Technical Analysis
@elastic/elasticsearch is the official Node.js client maintained by Elastic for talking to Elasticsearch clusters. It wraps the full Elasticsearch REST API in a single Client class, with every endpoint (search, index, bulk, ingest pipelines, ES|QL, security, and more) exposed as a typed method generated directly from Elasticsearch’s API specification, so the client stays in lockstep with server releases.
Under the hood it delegates connection management, retries, sniffing, and serialization to its companion @elastic/transport package, while this package layers on Elasticsearch-specific ergonomics: cloud ID and API key authentication, OpenTelemetry-based observability, child clients for per-request overrides, and a set of helper utilities (scrollSearch, msearch, bulk, and an Apache Arrow-backed ES|QL helper) that turn common multi-request patterns into single async calls or iterators.
Because versioning tracks the Elastic Stack rather than semver-for-semver-sake, the client publishes a version for every major/minor line of Elasticsearch (7.x, 8.x, 9.x) and documents exactly which server versions each client major is compatible with, plus a supported aliasing trick for running multiple client versions side by side in one project.
What You Get
- A fully typed
Clientclass covering the entire Elasticsearch REST API (index, search, ingest, security, ES|QL, and more), generated from Elasticsearch’s own API spec so method signatures track server capabilities - Pluggable connection pooling (
WeightedConnectionPool,CloudConnectionPool) and an optionalSniffingTransportfor cluster node discovery, both inherited from@elastic/transport - Built-in auth support for basic auth, API keys, bearer tokens, and Elastic Cloud IDs, so connecting to self-managed or Cloud clusters needs only a config object
- Helper utilities (
scrollSearch/scrollDocuments,msearch,bulk, and an ES|QL-to-records/Arrow helper) that wrap multi-step Elasticsearch interaction patterns into single async iterables or promises - First-class TypeScript types for every request/response shape, plus dual CJS/ESM builds so the client works in both module systems out of the box
- OpenTelemetry-based observability hooks and a child-client API for overriding headers or options on a per-request basis without mutating the parent client
Common Use Cases
- Indexing and searching application data (logs, product catalogs, documents) from a Node.js backend against a self-hosted or Elastic Cloud cluster
- Bulk-loading or re-indexing large datasets using the
bulkhelper, which batches documents and handles retries/backpressure automatically - Building analytics or reporting features on top of ES|QL queries, using the ES|QL helper to get typed records or an Apache Arrow table back from a query
- Paginating through large result sets with
scrollSearch/scrollDocumentsinstead of hand-rolling scroll-context management - Running many independent searches efficiently in one round trip via the
msearchhelper, useful for dashboards that need several queries per page load
Under The Hood
Architecture
The package centers on a single Client class (src/client.ts) that composes a Transport, a Serializer, and a ConnectionPool implementation imported from the companion @elastic/transport package, then mixes in a generated API surface (src/api/) that attaches one typed method per Elasticsearch endpoint. A SniffingTransport subclass (src/sniffingTransport.ts) swaps in cluster-discovery behavior when sniffing is enabled, and a separate Helpers class (src/helpers.ts) wraps the raw client in higher-level async iterables (scrollSearch, msearch, bulk, ES|QL) that internally just call back into the same Client instance. Because the low-level HTTP/connection concerns live entirely in @elastic/transport, changing that core abstraction would ripple through every client method, but this package’s own responsibility is narrow and well-separated: typed endpoint surface plus convenience helpers on top of a transport it does not implement itself.
Tech Stack
The client is TypeScript-first (98%+ of the codebase), built via tsc into dual CJS (lib/) and ESM (esm/) outputs from tsconfig.json/tsconfig.esm.json, and depends directly on @elastic/transport (its own connection pooling and retry engine) plus tslib for helper runtime support. apache-arrow is an optional peer dependency, loaded lazily via a require inside loadArrow() in helpers.ts, only when the ES|QL Arrow helper is actually used. Tooling includes ESLint (via neostandard), c8/tap for coverage-gated testing, and a renovate.json for automated dependency updates, with the engines field pinning a Node.js >=22 requirement.
Code Quality
Tests live under test/unit, test/integration, test/esm, and test/fuzz, using the tap test runner with c8 coverage thresholds enforced in the test npm script (96% statements, 90% branches, 96% lines, 91% functions) — a notably strict, explicitly enforced bar rather than an aspirational one. Unit tests are organized per-module (client.test.ts, sniffingTransport.test.ts, helpers/scroll.test.ts, helpers/bulk.test.ts, helpers/msearch.test.ts, helpers/esql.test.ts), and the suite spins up real HTTP servers via a shared buildServer test utility rather than mocking at the network boundary, giving reasonably realistic coverage of connection and retry paths. Types are strict throughout, and CI runs a nodejs.yml workflow plus a separate integration-test pipeline on Buildkite.
API Design
The public surface favors a single Client constructor accepting cloud ID, API key, or basic-auth options directly, keeping getting-started boilerplate minimal, while every generated endpoint method mirrors Elasticsearch’s own request/response naming so users familiar with the REST API transfer that knowledge directly. The helper layer (scrollSearch, bulk, msearch, ES|QL) exists specifically to remove boilerplate around multi-request Elasticsearch patterns that would otherwise require manual state tracking (scroll IDs, batching, backpressure), turning them into async iterables or promise-returning calls consistent with idiomatic Node.js usage.
Used by 10 apps in this directory
Budibase
Low Code Platforms · No Code Platforms
Build AI agents, automations, and internal apps on a single open-source platform with full self-hosting control.
Flowise
Developer Tools · Automation · No Code Platforms
Drag-and-drop visual builder for AI agents, RAG pipelines, and multi-agent systems—deploy anywhere in minutes.
Huly Platform
Project Management · Team Chat · Collaboration
Open-source all-in-one workspace that replaces Linear, Jira, Slack, and Notion for product and engineering teams.
Infisical
Security · Devops
The open-source platform for secrets, certificates, privileged access, and AI agent security — all in one self-hostable system.
Kibana
Analytics · Monitoring
Your open source window into the Elastic Stack — query, visualize, and act on data stored in Elasticsearch with real-time dashboards, AI-assisted search, and automated alerting.
Mastra Code
AI Code Assistants
"A coding agent that never compacts" — a terminal-based AI coding agent built on the Mastra framework, with Observational Memory instead of context compaction, multi-model support, and OAuth login for Claude Max or ChatGPT Plus.
nango
Developer Tools · Automation · Authentication
Build product integrations with AI using 800+ APIs — auth, proxy, and TypeScript functions on production-grade infrastructure.
OneUptime
Monitoring
The complete open-source observability platform that replaces PagerDuty, Datadog, Sentry, and StatusPage with a single self-hostable system.
Refly
No Code Platforms · AI Development · Automation
Build deterministic, versioned agent skills from natural language—run them anywhere from Claude Code to Slack.