MCPcopy Index your code
hub / github.com/searchkit/searchkit

github.com/searchkit/searchkit @v3.0.0

repository ↗ · DeepWiki ↗ · release v3.0.0 ↗ · + Follow
369 symbols 1,015 edges 145 files 0 documented · 0% updated 3mo agosearchkit@4.16.0 · 2026-04-04★ 4,85723 open issues
README

Search, made easy

Searchkit is an open source toolkit which helps you build a great search experience with Elasticsearch.

See why use Searchkit

Searchkit to simplify using Elasticsearch for Search: - Powerful Browser / Node.js SDK client for Elasticsearch - Out-of-the-box React Search State & components - Optional Integrations with GraphQL, Node.js REST APIs - A great Search experience without needing to be an expert in Elasticsearch

Highlights

Code Sandbox Examples

api-setup-2

Quick Intro to SDK

From a configuration


import Searchkit, { MultiMatchQuery, RefinementSelectFacet, RangeFacet, DateRangeFacet, TermFilter } from '@searchkit/sdk'

const searchkitConfig = {
  host: 'http://127.0.0.1:9200/', // elasticsearch instance url
  index: 'movies', // search indices name
  hits: {
    fields: [ 'title', 'plot', 'poster' ]
  },
  query: new MultiMatchQuery({
    fields: [ 'plot','title^4'],
    highlightFields: ["title"]
  }),
  sortOptions: [
    { id: 'relevance', label: 'Relevance', field: '_score' },
    { id: 'released', label: 'Recent Releases', field: { released: 'desc' } }
  ],
  filters: [
    new TermFilter({
      identifier: "writer",
      field: "writers",
      label: "Writers"
    })
  ],
  facets: [
    new RefinementSelectFacet({
      identifier: 'type',
      field: 'type.raw',
      label: 'Type'
      multipleSelect: true
    }),
    new RangeFacet({
      identifier: 'metascore',
      field: 'metaScore',
      label: 'Metascore',
      range: {
        min: 0,
        max: 100,
        interval: 5
      }
    }),
    new DateRangeFacet({
      identifier: 'released',
      field: 'released',
      label: 'Released'
    })
  ]
}

const request = Searchkit(config)
const response = await request
  .query("heat")
  .setFilters([
    { identifier: "metascore", min: 10, max: 90 },
    { identifier: 'writers', value: 'writer1' },
    { identifier: 'released', dateMin: '2021-01-01T10:10:10.000Z', dateMax: '2022-01-01T10:10:10.000Z' }
  ])
  .setSortBy("released")
  .execute({
    facets: true,
    hits: {
      size: 10,
      from: 0
    }
  })

Will provide a response like this


{
  "hits": {
    "items": [
      {
        "fields": {
          "title": "title",
          "plot": "plot text",
          "poster": "http://cdn.url/poster"
        },
        "highlight": {},
        "id": "1"
      }
      // ...9 further items
    ],
    "page": {
      "from": 0,
      "pageNumber": 0,
      "size": 10,
      "total": 4162,
      "totalPages": 417
    }
  },
"facets": [
    {
      "display": "ListFacet",
      "entries": [
        {
          "count": 83,
          "label": "J.J. Abrams",
        },
        {
          "count": 74,
          "label": "Jeffrey Lieber",
        },
        {
          "count": 73,
          "label": "Damon Lindelof",
        },
        {
          "count": 53,
          "label": "James Manos Jr.",
        },
        {
          "count": 53,
          "label": "Jeff Lindsay",
        },
      ],
      "identifier": "writers",
      "label": "Writers",
      "type": "RefinementSelectFacet",
    },
    {
      "display": "ListFacet",
      "entries": [
        {
          "count": 73,
          "label": "Naveen Andrews",
        },
        {
          "count": 56,
          "label": "Jennifer Carpenter",
        },
        {
          "count": 56,
          "label": "Michael C. Hall",
        },
        {
          "count": 53,
          "label": "Emilie de Ravin",
        },
        {
          "count": 42,
          "label": "Jared Padalecki",
        },
      ],
      "identifier": "actors",
      "label": "Actors",
      "type": "RefinementSelectFacet",
    },
  ],
  "sortedBy": "released",
  "summary": {
    "appliedFilters": [
      {
        "display": "ListFacet",
        "id": "writers_writer1",
        "identifier": "writers",
        "label": "Writers",
        "type": "ValueSelectedFilter",
        "value": "writer1",
      },
      {
        "display": "ListFacet",
        "id": "actors_actors",
        "identifier": "actors",
        "label": "Actors",
        "type": "ValueSelectedFilter",
        "value": "actors",
      },
      {
        "display": "RangeFacet",
        "id": "actors_actors",
        "identifier": "metascore",
        "label": "Metascore",
        "type": "ValueSelectedFilter",
        "min": "10",
        "max": "90"
      },
    ],
    "disabledFilters": [],
    "query": "heat",
    "sortOptions": [{
        "id": "relevance",
        "label": "Relevance",
      },
      {
        "id": "released",
        "label": "Recent Releases",
      },
      {
        "id": "title-released",
        "label": "Recent Titles",
      },
    ],
    "total": 4162
  }
}

React Integration

We provide a thin React client which integrates with Searchkit's SDK or Searchkit GraphQL API. It maintains search state (pagination, filtering and querying) and provides SearchState via a hook.

React Components

import {
  FacetsList,
  SearchBar,
  Pagination,
  ResetSearchButton,
  SelectedFilters
} from '@searchkit/elastic-ui'

import { useSearchkitSDK } from '@searchkit/sdk/lib/esm/react-hooks'
import { useSearchkitVariables } from '@searchkit/client'

const Page = () => {
  const variables = useSearchkitVariables()
  const { data, loading } = useSearchkitSDK(config, variables)
  const Facets = FacetsList([])
  return (
    <EuiPage>
      <EuiPageSideBar>
        <SearchBar loading={loading} />
        <EuiHorizontalRule margin="m" />
        <Facets data={data?.results} loading={loading} />
      </EuiPageSideBar>
      <EuiPageBody component="div">
        <EuiPageHeader>
          <EuiPageHeaderSection>
            <EuiTitle size="l">
              <SelectedFilters data={data?.results} loading={loading} />
            </EuiTitle>
          </EuiPageHeaderSection>
          <EuiPageHeaderSection>
            <ResetSearchButton loading={loading} />
          </EuiPageHeaderSection>
        </EuiPageHeader>
        <EuiPageContent>
          <EuiPageContentHeader>
            <EuiPageContentHeaderSection>
              <EuiTitle size="s">
                <h2>{data?.results.summary.total} Results</h2>
              </EuiTitle>
            </EuiPageContentHeaderSection>
          </EuiPageContentHeader>
          <EuiPageContentBody>
            <HitsList data={data} />
            <EuiFlexGroup justifyContent="spaceAround">
              <Pagination data={data?.results} />
            </EuiFlexGroup>
          </EuiPageContentBody>
        </EuiPageContent>
      </EuiPageBody>
    </EuiPage>
  )
}

See quickstart guide

NPM Packages

Sponsors

QBOX Elasticsearch hosting. They have kindly provided us an elasticsearch instance for our demo site.

FAQ

Can I upgrade from Searchkit v2?

Searchkit has undergone a total rewrite so whilst it should be straightforward to move onto, any code written for searchkit legacy wouldn't work on Searchkit v3.

Do I need to expose my Elasticsearch instance to the browser?

No! You dont expose your elasticsearch cluster to the browser, you can use the Search GraphQL API that sits in between elasticsearch and the browser.

Do I need to run a Node.js Server?

No! You can use the searchkit/sdk within the browser too.

Extension points exported contracts — how you extend this code

BaseFacet (Interface)
(no doc) [12 implementers]
packages/searchkit-sdk/src/facets/BaseFacet.ts
SearchkitField (Interface)
(no doc)
packages/searchkit-cli/src/index.ts
FilterLinkProps (Interface)
(no doc)
packages/searchkit-client/src/components.tsx
SearchkitSchemaConfig (Interface)
(no doc)
packages/searchkit-schema/src/schema.ts
SearchkitResponseTransformer (Interface)
(no doc) [8 implementers]
packages/searchkit-sdk/src/transformers/index.ts
CliConfig (Interface)
(no doc)
packages/searchkit-cli/src/index.ts
PaginationLinkProps (Interface)
(no doc)
packages/searchkit-client/src/components.tsx
HitsParameters (Interface)
(no doc)
packages/searchkit-schema/src/resolvers/HitsResolver.ts

Core symbols most depended-on inside this repo

execute
called by 34
packages/searchkit-sdk/src/index.ts
setupTestServer
called by 34
packages/searchkit-schema/tests/support/helper.ts
getFilters
called by 26
packages/searchkit-sdk/src/facets/BaseFacet.ts
addFilter
called by 21
packages/searchkit-client/src/searchkit.tsx
search
called by 20
packages/searchkit-client/src/searchkit.tsx
useSearchkit
called by 19
packages/searchkit-client/src/searchkit.tsx
setFilters
called by 18
packages/searchkit-sdk/src/index.ts
searchStateEqual
called by 14
packages/searchkit-client/src/searchkit.tsx

Shape

Method 147
Function 120
Interface 52
Class 50

Languages

TypeScript100%

Modules by API surface

packages/searchkit-client/src/searchkit.tsx39 symbols
packages/searchkit-sdk/src/index.ts20 symbols
packages/searchkit-sdk/src/transformers/index.ts15 symbols
packages/searchkit-sdk/src/core/QueryManager.ts14 symbols
packages/searchkit-schema/src/resolvers/ResultsResolver.ts13 symbols
packages/searchkit-cli/src/lib.ts13 symbols
packages/searchkit-sdk/src/facets/MultiQueryOptionsFacet.ts11 symbols
packages/searchkit-sdk/src/facets/HierarchicalMenuFacet.ts11 symbols
packages/searchkit-sdk/src/facets/BaseFacet.ts11 symbols
packages/searchkit-schema/src/core/QueryManager.ts11 symbols
packages/searchkit-sdk/src/facets/RefinementSelectFacet.ts10 symbols
packages/searchkit-sdk/src/facets/RangeFacet.ts10 symbols

Dependencies from manifests, versioned

@apollo/client3.3.19 · 1×
@docusaurus/core2.0.0-beta.15 · 1×
@docusaurus/preset-classic2.0.0-beta.15 · 1×
@elastic/datemath5.0.3 · 1×
@elastic/elasticsearch7.10.0 · 1×
@elastic/elasticsearch-types
@elastic/eui34.0.0 · 1×
@graphql-codegen/cli1.15.0 · 1×
@graphql-codegen/fragment-matcher1.15.0 · 1×
@graphql-codegen/introspection1.15.0 · 1×
@graphql-codegen/typescript1.15.0 · 1×

For agents

$ claude mcp add searchkit \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact