# meilisearch-js: the Meilisearch API client for JavaScript and TypeScript

> meilisearch-js is the official API client for the Meilisearch search engine, written in TypeScript and shipped to npm as meilisearch. It publishes TypeScript sources directly for local development and a built bundle for consumers, supports Node, the browser, React Native and Deno, and the README is unusually precise about the environments it does not test.

**meilisearch/meilisearch-js** — JavaScript/TypeScript client for Meilisearch

- Repository: https://github.com/meilisearch/meilisearch-js
- Website: https://www.meilisearch.com
- Stars: 869 · Forks: 122
- Language: TypeScript
- License: MIT
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/meilisearch-meilisearch-js

## What the package is, and how it is packaged

meilisearch-js is the Meilisearch API client for JavaScript developers, described in the README as the Meilisearch API client written for JavaScript. Meilisearch itself is the open-source search engine, hosted in a separate repository, and this package is only the client.

The package.json describes it as the Meilisearch JS client for Node.js and the browser, with the name meilisearch, the version 0.62.0 and the MIT licence. The description field in the repository metadata says JavaScript/TypeScript client for Meilisearch, and the topics are javascript, meilisearch, nodejs, sdk and typescript.

Two details in the packaging are worth knowing about because they affect how you consume it. The exports map points the package root at ./src/index.ts and the wildcard at ./src/*.ts, so the sources are shipped and importable directly, which is what lets a bundler compile from TypeScript rather than from a prebuilt bundle. The publishConfig overrides the exports at publish time to point at ./dist/index.js, so the npm tarball gives you the built output instead.

There is a third export, ./token, which is present only in the publishConfig and points at ./dist/token.js. That separate entry point is the one to use in a browser, because it is the entry point that does not pull in the code that would otherwise require an admin-level key on the client.

The files array ships src, dist and CONTRIBUTING.md, and sideEffects is false, which lets a bundler drop unused parts of the client from your output.

The engines field is explicit: node ^20.19.0 or >=22.12.0. Those are recent floors, and the README's separate note about which Node versions are tested matches it.

## Installing and the four import routes

The package is published to npm as meilisearch, and installation is one command:

```sh
npm i meilisearch
```

After that, how you import depends on your environment, and the README covers four cases.

In an ES module environment, the named import:

```js
import { Meilisearch } from "meilisearch";

const client = new Meilisearch({
  host: "http://127.0.0.1:7700",
  apiKey: "masterKey",
});
```

For a browser without a bundler, a script tag pointing at a CDN, and the README's note that each CDN provides more ways to import packages so you should read their documentation:

```html
<script type="module">
  import { Meilisearch } from "https://www.unpkg.com/meilisearch";
  const client = new Meilisearch(/* ... */);
  // ...
</script>
```

For a back-end Node.js environment or anything else on CommonJS modules, a require call:

```js
const { Meilisearch } = require("meilisearch");

const client = new Meilisearch({
  host: "http://127.0.0.1:7700",
  apiKey: "masterKey",
});
```

And for Deno, where the specifier goes through npm:

```js
import { Meilisearch } from "npm:meilisearch";

const client = new Meilisearch({
  host: "http://127.0.0.1:7700",
  apiKey: "masterKey",
});
```

React Native needs one extra package, react-native-url-polyfill, because the client depends on the URL API that React Native does not fully implement.

The runtime support statement is precise in a way that is unusual and useful. Node.js LTS and Maintenance versions are supported and tested, and other versions may or may not work. Other runtimes, Deno and Bun in particular, are not tested, and the README asks you to open an issue if the package does not work there.

There is a warning for TypeScript users of the meilisearch/token entry point. TypeScript 4.7 or newer is required, and tsconfig.json has to be set up correctly for package exports, with a link to the tsconfig bases recommendations. That is the standard friction of conditional exports in TypeScript, and the README flags it in advance rather than letting you discover it.

## Getting started: adding documents and the playground

The README points to a playground for a concrete example, and the tree confirms it, with a playgrounds/ directory containing a javascript example whose source is at playgrounds/javascript/src/meilisearch.ts. The package.json wires it to a Vite dev server:

```bash
pnpm playground:javascript
```

The document-adding example is the shape most users write first. An index is where the documents are stored, and you get one from the client:

```js
const { Meilisearch } = require("meilisearch");
// Or if you are in a ES environment
import { Meilisearch } from "meilisearch";
(async () => {
  const client = new Meilisearch({
    host: "http://127.0.0.1:7700",
    apiKey: "masterKey",
  });

  // An index is where the documents are stored.
  const index = client.index("movies");
```

The example documents that follow are movie records with an id, a title and a genres array, which is the shape that shows off what Meilisearch is good at: filtering on an array attribute and matching on text.

The apiKey value in the examples is masterKey, and that is not a placeholder. The docker-compose.yml in the repository sets MEILI_MASTER_KEY to the same literal value, along with MEILI_NO_ANALYTICS set to true and MEILI_EXPERIMENTAL_ALLOWED_IP_NETWORKS set to any. The master key is the admin-level key, and using it in client-side code is exactly what the separate ./token export exists to avoid.

The compose file is otherwise a good picture of the local development setup. There is a package service built from docker/node.Dockerfile with the working directory at /home/package and the repository mounted into it, with a named volume hiding the host node_modules so native bindings stay inside the container. The meilisearch service runs the getmeili/meilisearch-enterprise image at version 1.55, publishing port 7700.

## The toolchain: Vite, Vitest, Typedoc, VitePress and oxlint

The package.json scripts describe the development setup in detail, and it is a modern one.

The build is a Vite build followed by a separate type check and emit:

```bash
pnpm build
```

which runs vite build and then tsc with tsconfig.build.json, so the bundler and the compiler are two separate steps rather than one.

The tests run under Vitest, with a run mode and a watch mode, and coverage comes from the v8 provider. Type checking has its own script, tsc with noEmit, with a watch variant.

The API documentation is generated by Typedoc and served with VitePress, and the scripts build the typedoc output first and then run vitepress dev or vitepress build over the docs directory. There is a typedoc.json at the root and a typedoc/ directory for the configuration and templates.

Linting is where the project has moved on from its older tooling. The lint script is oxlint with the type-aware flag, and there is an oxlint.config.ts at the root. Formatting is Prettier with a .prettierrc.js, and a style script runs both in sequence. Git hooks are handled by Husky, with a prepare script that installs them, and lint-staged.config.js for staged files.

The repository also contains .agents/ and .cursor/ directories alongside an AGENTS.md file, which is the modern equivalent of editor-specific instructions for coding agents working in the repository.

Package management is pnpm, with pnpm-lock.yaml and pnpm-workspace.yaml at the root, and the workspace is set up so the package is consumed from source during development.

## Compatibility with the server, and how the client tracks it

A client for a search engine has an awkward dependency: the server's API moves, and the client has to move with it or the two disagree.

The README points at a compatibility section and at the Meilisearch documentation for the API reference, with the client library documentation hosted separately at meilisearch.github.io/meilisearch-js. The Meilisearch project also publishes a roadmap on a public tabbed site, and the client's own releases show the pattern of tracking server releases closely.

The version numbers make the relationship visible. The client is at 0.62.0, and the recent releases are v0.62.0 on 2026-09-09, v0.61.0 on 2026-08-11 and v0.60.0 on 2026-07-22. That is roughly one release a month, on a 0.x version line, which under semver carries no compatibility guarantee between minors.

The 0.x line is not an accident of numbering. A client that mirrors an API which is still moving is exactly the case where a 1.0 promise would be premature, and the monthly cadence reflects a client being updated as the server adds endpoints and changes behaviour.

What that means for an adopter is concrete. The client version and the server version are a pair you choose together, not independently. The last push to the repository was on 2026-10-14, so the main branch is ahead of the newest published release, and the repository ships a .code-samples.meilisearch.yaml file at the root, which is the mechanism Meilisearch uses to validate that documentation samples still compile against the current API.

There is also a hosted option. The README links Meilisearch Cloud for those who would rather not run the engine, and separately links the self-hosted download for those who would.

## Limits: runtime support, the key exposure problem and the 0.x line

The limits are visible in what the README documents.

The first is runtime support. Only Node.js LTS and Maintenance versions are tested, Deno and Bun are explicitly not tested, and other Node versions may or may not work. The README turns this into a request rather than a warning, asking you to open an issue if the package does not work on Deno or Bun. That is honest, and it means if you deploy on one of those runtimes you are on your own.

The second is the key exposure problem, and it is the one that catches people out. The examples construct a client with apiKey set to masterKey, which is the admin-level key. That is correct in a back-end process and wrong in a browser bundle, where an admin key in shipped JavaScript is readable by anyone who opens the devtools. The presence of the separate ./token export in the package's publishConfig is the project's answer, but the README does not spell out the reasoning in so many words, so a reader has to infer it from the two entry points.

The third is the 0.x version line. Under semver, a 0.x version carries no compatibility guarantee, so a minor bump can break your code. For a client whose purpose is to track a moving server API that is defensible, but it does mean you should pin the version rather than float it.

The fourth is the TypeScript floor for the token entry point. TypeScript 4.7 or newer is required, and tsconfig.json has to be configured correctly for package exports, which trips up projects whose tsconfig was written before conditional exports existed.

The fifth is what the client does not do. It is an HTTP client for one engine's API. It does not add a query builder, an analytics layer, an index management abstraction or a fallback when the engine is down, and the README is not trying to pretend otherwise.

## meilisearch-js against raw fetch and against the Elastic and Typesense clients

Two comparisons make the choice clearer.

The first is against calling the Meilisearch HTTP API yourself with fetch. The API is straightforward, a JSON request and a JSON response, so a hand-written client for two or three endpoints is genuinely simple. What you give up is the type definitions, which is the bigger loss than it looks, because Meilisearch's filter and sort parameters are stringly typed and the client's types encode which attributes are filterable, which are sortable and what the document shape is. Beyond that, the client handles the parts that are easy to get wrong: the task model, where indexing and search operations return a task identifier and you poll for the result, and the error shapes.

The second comparison is against the clients for other search engines, Elastic's and Typesense's. The difference in approach is what the engine itself is. An Elasticsearch client talks to a distributed system with shards, replicas and mappings, and its client library reflects that complexity with cluster health, bulk helpers and index management. A Meilisearch client talks to a single server with a simpler index model, and the client stays correspondingly small.

The practical consequence is that switching search engines means switching clients, and the shape of your code changes with it. A Meilisearch client is a thin, pleasant wrapper over a documented HTTP API, with the value concentrated in types and the task model. An Elasticsearch client is an interface to a distributed search infrastructure.

The other honest framing is that the client is not where the differentiation lives. Meilisearch's own behaviour, its typo tolerance, its ranking and its filtering are the product. meilisearch-js is good plumbing for that product, and choosing it over a hand-written fetch wrapper is a small decision with real convenience value, not a strategic one.

## Conclusion

Adopt meilisearch-js when you are calling a Meilisearch instance from JavaScript or TypeScript and want the client's own type definitions and API coverage rather than hand-written fetch calls. Do not adopt it if you need to run against a Meilisearch version whose API the client has not caught up with, since the client tracks server releases closely. Verify first that your Node version satisfies the engines field in package.json, which asks for 20.19 or newer or 22.12 or newer, and that the browser usage you plan relies on the separate token entry point rather than shipping an admin key to the client.

## FAQ

### How do I install the Meilisearch JavaScript client and create a client?

Install the package with npm i meilisearch, then import the Meilisearch class. In an ES module environment you use import { Meilisearch } from "meilisearch", in CommonJS you use require, in Deno the specifier is npm:meilisearch, and in a browser you can import from a CDN such as unpkg in a module script tag. You then construct it with a host and an apiKey.

### Which Node.js versions does meilisearch-js support?

The package.json engines field requires node ^20.19.0 or >=22.12.0. The README says Node.js LTS and Maintenance versions are supported and tested while other versions may or may not work, and that Deno and Bun are not tested, with a request to open an issue if the package does not work there.

### What does the meilisearch/token entry point do?

The package's publishConfig defines three exports: the root, the token entry point at ./dist/token.js and the package.json. The token entry point exists separately from the main one, and importing it in a browser is the way to use the client without pulling in code that expects an admin-level API key. Importing it from TypeScript requires TypeScript 4.7 or newer and a correctly configured tsconfig for package exports.

## Sources

- [License: MIT](https://github.com/meilisearch/meilisearch-js/blob/main/LICENSE)
- [meilisearch/meilisearch-js on GitHub](https://github.com/meilisearch/meilisearch-js)
- [Project website](https://www.meilisearch.com)
- [README](https://github.com/meilisearch/meilisearch-js/blob/main/README.md)
- [Releases](https://github.com/meilisearch/meilisearch-js/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/meilisearch-meilisearch-js
