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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@pinelab/vendure-plugin-better-search

v0.4.0

Published

Vendure plugin for better storefront search, without the need of external systems

Downloads

133

Readme

Vendure Better Search Plugin

Official documentation here

This plugin offers more intuitive search than Vendure's DefaultSearchPlugin before the need of an external platform like TypeSense or ElasticSearch.

This plug is meant for small to medium sized shops with up to ~10000 variants.

Goals

  1. Performant in memory search, without affecting customer facing API calls.
  2. Provide relevant, type-tolerant (fuzzy matching) search results, while still meeting goal 1
  3. Extensible with custom fields, custom field weighting.

This plugin is not meant to be a replacement for ElasticSearch or TypeSense, but rather a lightweight alternative for small to medium sized shops. If you want to test if it works for you, give it a try and run the load tests we have included.

Features:

  • Search by term or multiple terms, no and/or logic or query syntax.
  • Fuzzy matching / type tolerance
  • Extendable with custom fields
  • Index field weighting
  • Filtering by facets (faceted search): Planned feature, not implemented yet.

Getting started

  1. Add the plugin to your vendure-config.ts:
import { BetterSearchPlugin } from '@pinelab/vendure-plugin-better-search';

...
plugins: [
  BetterSearchPlugin,
],
  1. Run a database migration
  2. Start the server
  3. Do a search via the new betterSearch query. The very first time, this will throw an error, and it will start building the index in the background.
query Search {
  betterSearch(input: { term: "dumbbells" }) {
    totalItems
    items {
      productId
      slug
      productName
      productAsset {
        id
        preview
      }
      lowestPrice
      lowestPriceWithTax
      highestPrice
      highestPriceWithTax
      facetValueIds
      collectionIds
      collectionNames
    }
  }
}

⚠️ Set the env variable BETTER_SEARCH_INDEX_COLUMN_TYPE for your specific database! Without this, text is used as default, but this will be too small for most projects. Run a database migration after setting this env variable!

# For MySQL
BETTER_SEARCH_INDEX_COLUMN_TYPE=mediumblob

# For PostgreSQL
BETTER_SEARCH_INDEX_COLUMN_TYPE=bytea

Checkout this page on more information on the different column types: https://orkhan.gitbook.io/typeorm/docs/entities#column-types-for-mysql-mariadb

Custom fields

You can add custom fields by defining a custom mapToSearchDocument function together with a custom indexableFields object.

For example, we have a custom field keywords on our products, and we want to index it, and return it in the search results:

import {
  BetterSearchResult,
  defaultSearchConfig,
  BetterSearchConfigInput,
} from '@pinelab/vendure-plugin-better-search';

// Define an interface for our custom search result
interface MySearchResult extends BetterSearchResult {
  keywords: string[];
}

export const searchConfig: BetterSearchConfigInput<MySearchResult> = {
  mapToSearchDocument: (product, collections) => {
    // Use the default mapping to get the base document
    const defaultDocument = defaultSearchConfig.mapToSearchDocument(
      product,
      collections
    );
    return {
      ...defaultDocument,
      // Extend the base document with "keywords"
      keywords: product.customFields.keywords,
    };
  },
  indexableFields: {
    ...defaultSearchConfig.indexableFields,
    // Add "keywords" to the index with a weight of 2,
    keywords: {
      weight: 2,
      // Tell the GraphQL schema that "keywords" is a [String!]!
      // If you do not specify the graphqlFieldType, the field will not be returned in the search results
      graphqlFieldType: "[String!]!",
    },
  },
};

// Then in your vendure-config.ts, use the searchConfig:
plugins: [
  BetterSearchPlugin.init({
    searchConfig,
  }),
],

Checkout the defaultSearchConfig.ts for the default weights of each field.

Tips

  • Add a custom field keywords to your products, and make the plugin index it. This is where you'd save keywords, synonyms, etc. This will drastically improve the search experience.
  • Don't index descriptions unless you really have to, to save on memory usage. Also, most of the shops will have a better search experience when the description is not indexed, since the descriptions usually also contain a lot of noise.
  • Monitor your workers memory usage and database CPU usage. If any of these are high, you can increase the debounceIndexRebuildMs to reduce the number of rebuilds. If that doesn't work, your dataset might be too large for this search.

Load test

// TODO