npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@vectorhook/instantsearch

v1.0.0

Published

VectorHook adapter for Algolia InstantSearch

Readme

@vectorhook/instantsearch

npm version License: MIT

An adapter that lets you use Algolia's InstantSearch frontend libraries with VectorHook as the backend search engine.

This adapter translates queries from InstantSearch libraries (vanilla JS, React, Vue, Angular) to VectorHook's search API format, allowing you to leverage InstantSearch's rich UI components while using VectorHook's powerful search capabilities.

Installation

# npm
npm install @vectorhook/instantsearch @vectorhook/client instantsearch.js

# or yarn
yarn add @vectorhook/instantsearch @vectorhook/client instantsearch.js

# For React InstantSearch
npm install react-instantsearch-dom

# For Vue InstantSearch
npm install vue-instantsearch

Quick Start

// Initialize VectorHook client
import VectorHook from '@vectorhook/client';
import VectorHookInstantSearch from '@vectorhook/instantsearch';
import instantsearch from 'instantsearch.js';
import { searchBox, hits } from 'instantsearch.js/es/widgets';

// Initialize VectorHook client
const vectorhookClient = new VectorHook({
  apiKey: 'your_api_key',
  baseUrl: 'https://api.vectorhook.com'
});

// Initialize the InstantSearch adapter
const searchClient = new VectorHookInstantSearch({
  vectorhookClient: vectorhookClient,
  collectionName: 'products',
  mappings: {
    queryBy: 'name,description',
    facetBy: 'categories,brand,in_stock'
  }
});

// Create the InstantSearch instance
const search = instantsearch({
  indexName: 'products',
  searchClient
});

// Add widgets
search.addWidgets([
  searchBox({
    container: '#searchbox',
  }),
  hits({
    container: '#hits',
    templates: {
      item: (hit) => `
        <div>
          <h3>${hit.name}</h3>
          <p>${hit.description}</p>
          <p>$${hit.price}</p>
        </div>
      `
    }
  })
]);

// Start the search
search.start();

Framework Integrations

React InstantSearch

import React from 'react';
import VectorHook from '@vectorhook/client';
import VectorHookInstantSearch from '@vectorhook/instantsearch';
import { InstantSearch, SearchBox, Hits, RefinementList } from 'react-instantsearch-dom';

const vectorhookClient = new VectorHook({
  apiKey: 'your_api_key',
  baseUrl: 'https://api.vectorhook.com'
});

const searchClient = new VectorHookInstantSearch({
  vectorhookClient: vectorhookClient,
  collectionName: 'products',
  mappings: {
    queryBy: 'name,description',
    facetBy: 'categories,brand'
  }
});

function App() {
  return (
    <InstantSearch indexName="products" searchClient={searchClient}>
      <div className="search-panel">
        <div className="search-panel__filters">
          <RefinementList attribute="categories" />
          <RefinementList attribute="brand" />
        </div>
        <div className="search-panel__results">
          <SearchBox />
          <Hits hitComponent={Hit} />
        </div>
      </div>
    </InstantSearch>
  );
}

function Hit({ hit }) {
  return (
    <article>
      <h1>{hit.name}</h1>
      <p>{hit.description}</p>
      <p>${hit.price}</p>
    </article>
  );
}

export default App;

Vue InstantSearch

<template>
  <ais-instant-search
    :search-client="searchClient"
    index-name="products"
  >
    <div class="search-panel">
      <div class="search-panel__filters">
        <ais-refinement-list attribute="categories" />
        <ais-refinement-list attribute="brand" />
      </div>
      <div class="search-panel__results">
        <ais-search-box />
        <ais-hits>
          <template slot="item" slot-scope="{ item }">
            <h1>{{ item.name }}</h1>
            <p>{{ item.description }}</p>
            <p>${{ item.price }}</p>
          </template>
        </ais-hits>
      </div>
    </div>
  </ais-instant-search>
</template>

<script>
import VectorHook from '@vectorhook/client';
import VectorHookInstantSearch from '@vectorhook/instantsearch';

export default {
  data() {
    const vectorhookClient = new VectorHook({
      apiKey: 'your_api_key',
      baseUrl: 'https://api.vectorhook.com'
    });

    const searchClient = new VectorHookInstantSearch({
      vectorhookClient: vectorhookClient,
      collectionName: 'products',
      mappings: {
        queryBy: 'name,description',
        facetBy: 'categories,brand'
      }
    });

    return {
      searchClient
    };
  }
};
</script>

Configuration Options

The VectorHookInstantSearch constructor accepts the following options:

const searchClient = new VectorHookInstantSearch({
  // Required options
  vectorhookClient: vectorhookClient, // Initialized VectorHook client
  collectionName: 'products',         // VectorHook collection to search

  // Field mapping options
  mappings: {
    // Fields to search (comma-separated)
    queryBy: 'name,description',
    
    // Fields for faceting (comma-separated)
    facetBy: 'categories,brand,in_stock',
    
    // Field used for tag filtering
    tagsField: 'tags',
    
    // Field for geo search
    geoField: '_geo',
    
    // Map Algolia field names to VectorHook field names
    facetMap: {
      'category': 'categories',
      'author.name': 'author_name'
    },
    
    // Map index names to sort options
    sortMap: {
      'products_price_asc': 'price:asc',
      'products_price_desc': 'price:desc'
    },
    
    // Default sort when none specified
    defaultSort: 'price:asc'
  },
  
  // Additional query parameters to include in all searches
  additionalQueryParams: {
    group_limit: 3,
    typo_tolerance_enabled: false
  },
  
  // Performance options
  requestTimeout: 5000,  // Timeout in ms
  maxRetries: 2,         // Max retries for failed requests
  
  // Debug mode
  debug: false           // Set to true for verbose logging
});

Features

  • Full Compatibility: Works with all InstantSearch libraries (JS, React, Vue, Angular)
  • Faceting: Supports refinement lists, hierarchical menus, and range sliders
  • Pagination: Works seamlessly with InstantSearch's pagination components
  • Sorting: Supports multiple indices for different sort orders
  • Highlighting: Converts VectorHook highlights to InstantSearch format
  • Error Handling: Built-in retries for failed requests
  • Customization: Extensive mapping options for field names and behaviors

Field Mapping

Default Field Mappings

VectorHook's field names might be different from what InstantSearch expects. The adapter provides mapping options to handle these differences:

const searchClient = new VectorHookInstantSearch({
  // ...other options
  mappings: {
    // Map Algolia field names to VectorHook field names
    facetMap: {
      'category': 'categories',      // InstantSearch uses 'category', VectorHook uses 'categories'
      'author.name': 'author_name'   // Handle nested fields
    }
  }
});

Sort Mapping

For sorting, InstantSearch typically uses different indices with specific names. The adapter maps these index names to VectorHook sort parameters:

const searchClient = new VectorHookInstantSearch({
  // ...other options
  mappings: {
    sortMap: {
      'products_price_asc': 'price:asc',
      'products_price_desc': 'price:desc',
      'products_created_at_desc': 'created_at:desc'
    }
  }
});

Advanced Usage

Multi-Index Search

For multi-index searching (e.g., for sorting):

// instantsearch.js
const search = instantsearch({
  indexName: 'products',
  searchClient
});

// Add a sort-by widget
search.addWidgets([
  sortBy({
    container: '#sort-by',
    items: [
      { label: 'Default', value: 'products' },
      { label: 'Price (asc)', value: 'products_price_asc' },
      { label: 'Price (desc)', value: 'products_price_desc' }
    ]
  })
]);

The adapter will map these index names to VectorHook sort parameters based on your sortMap configuration.

Custom Highlighting

Configure highlighting parameters:

const searchClient = new VectorHookInstantSearch({
  // ...other options
  additionalQueryParams: {
    highlight_fields: 'name,description',
    highlight_start_tag: '<mark>',
    highlight_end_tag: '</mark>'
  }
});

Geo Search

For geo search capabilities:

// React InstantSearch
<InstantSearch indexName="products" searchClient={searchClient}>
  <Configure aroundLatLng="40.7128,-74.0060" aroundRadius="1000" />
  {/* Other widgets */}
</InstantSearch>

The adapter will convert these parameters to VectorHook's geo filter format.

API Reference

VectorHookInstantSearch

Constructor

new VectorHookInstantSearch(options)

Methods

| Method | Description | |--------|-------------| | search(requests) | Main method called by InstantSearch to perform searches | | setCollection(collectionName) | Change the collection being searched | | updateOptions(options) | Update adapter options | | resetOptions() | Reset options to initial values | | getState() | Get current search state | | clearCache() | Compatibility method (no-op for VectorHook) |

Compatibility Notes

Sorting

VectorHook uses sort_by parameter with format field:direction, while InstantSearch typically uses separate indices.

Faceting

The adapter automatically converts InstantSearch facet filters to VectorHook's filter format.

Highlighting

VectorHook's highlighting format is converted to match what InstantSearch expects.

Migration from Algolia

If you're migrating from Algolia to VectorHook, this adapter makes it easier by allowing you to keep your existing InstantSearch UI code. You only need to:

  1. Replace the Algolia client with the VectorHook client and this adapter
  2. Configure the appropriate field mappings
  3. Ensure your VectorHook schema matches your data structure

Troubleshooting

Common Issues

  • Missing facets: Ensure you've added the facet fields to the facetBy option.
  • Incorrect sorting: Check your sortMap configuration.
  • Search not working: Verify your VectorHook API key and collection name.

Debug Mode

Enable debug mode to see detailed logs:

const searchClient = new VectorHookInstantSearch({
  // ...other options
  debug: true
});

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

License

This project is licensed under the MIT License - see the LICENSE file for details.