<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ fuse.js - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ fuse.js - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Fri, 29 May 2026 16:32:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/fuse-js/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Add Search to a React App with Fuse.js ]]>
                </title>
                <description>
                    <![CDATA[ Search is a powerful way help people visiting your site find the content that's most important to them. But often it's really challenging to figure out the rules and logic to make that happen. In this article, we'll see how can we can use fuse.js to ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-add-search-to-a-react-app-with-fuse-js/</link>
                <guid isPermaLink="false">66b8e33e6a98b2a27ee1f348</guid>
                
                    <category>
                        <![CDATA[ fuse.js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ front end ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Front-end Development ]]>
                    </category>
                
                    <category>
                        <![CDATA[ frontend ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ js ]]>
                    </category>
                
                    <category>
                        <![CDATA[ json ]]>
                    </category>
                
                    <category>
                        <![CDATA[ General Programming ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ react hooks ]]>
                    </category>
                
                    <category>
                        <![CDATA[ React ]]>
                    </category>
                
                    <category>
                        <![CDATA[ search ]]>
                    </category>
                
                    <category>
                        <![CDATA[ tech  ]]>
                    </category>
                
                    <category>
                        <![CDATA[ technology ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Colby Fayock ]]>
                </dc:creator>
                <pubDate>Tue, 26 May 2020 14:45:00 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/05/fusejs-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Search is a powerful way help people visiting your site find the content that's most important to them. But often it's really challenging to figure out the rules and logic to make that happen. In this article, we'll see how can we can use fuse.js to add search to our apps.</p>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-fusejs">What is fuse.js?</a></li>
<li><a class="post-section-overview" href="#heading-why-is-search-important">Why is search important?</a></li>
<li><a class="post-section-overview" href="#heading-what-are-we-going-to-build">What are we going to build?</a></li>
<li><a class="post-section-overview" href="#heading-step-0-bootstrapping-our-app">Step 0: Bootstrapping our app</a></li>
<li><a class="post-section-overview" href="#heading-step-1-installing-fusejs">Step 1: Installing Fuse.js</a></li>
<li><a class="post-section-overview" href="#heading-step-2-creating-a-new-fuse-search-instance">Step 2: Creating a new Fuse search instance</a></li>
<li><a class="post-section-overview" href="#heading-step-3-setting-up-dynamic-search-based-on-user-input">Step 3: Setting up dynamic search based on user input</a></li>
</ul>
<div class="embed-wrapper">
        <iframe width="560" height="315" src="https://www.youtube.com/embed/GZl-yEz4_qw" style="aspect-ratio: 16 / 9; width: 100%; height: auto;" title="YouTube video player" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen="" loading="lazy"></iframe></div>
<h2 id="heading-what-is-fusejs">What is fuse.js?</h2>
<p><a target="_blank" href="https://fusejs.io/">Fuse.js</a> is a JavaScript library that provides fuzzy search capabilities for applications and websites. It's nice and easy to use out of the box, but also includes configuration options that allow you to tweak and create powerful solutions.</p>
<h2 id="heading-why-is-search-important">Why is search important?</h2>
<p>Whether you're a content creator or are trying to sell a product with your website, it's important to help your visitors actually find what they're looking for. </p>
<p>If you're building an ecommerce website, you want someone to be able to easily find your Bender vinyl figures rather than having to dig through the entire catalog first.</p>
<h2 id="heading-what-are-we-going-to-build">What are we going to build?</h2>
<p>We're going to start off with a basic Create React App example. It's going to include some character info as structured data for one of my favorite shows Futurama that's simply dumped out into an HTML list.</p>
<p>With that list, we're going to use fuse.js to provide client-side search capabilities, allowing us to demonstrate searching for the character we're looking for by their name and other details.</p>
<h2 id="heading-step-0-bootstrapping-our-app">Step 0: Bootstrapping our app</h2>
<p>To get started, we're going to need content to work with. I got started by building a list of characters from Futurama as structured json data that I put in a list with a fresh Create React App.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Futurama character search demo</em></p>
<p>You'll also notice I've already added an input for our search. It's not yet functional but we'll use that to get started.</p>
<p>If you'd like to start off at the same place, I created a branch with my demo repo that you can clone locally to walk through the project with me!</p>
<pre><code class="lang-shell">git clone --single-branch --branch start git@github.com:colbyfayock/my-futurama-characters.git
</code></pre>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/tree/start">Git branch "start"</a></p>
<p>Or <a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/20d4e42aaf69e214b63e684e012cd2f8c95d427b">follow along with the commit</a>.</p>
<h2 id="heading-step-1-installing-fusejs">Step 1: Installing Fuse.js</h2>
<p>First thing we'll want to do is actually add Fuse.js to our app. In your project, run:</p>
<pre><code class="lang-shell">yarn add fuse.js
# or
npm install --save fuse.js
</code></pre>
<p>This will save the dependency to our project so that we'll be able to use it in our project.</p>
<p>Next we'll want to import the dependency to our app so that we can start building with it. At the top of your file, in our case <code>src/App.js</code> if you're following along with me in a new Create React App project, add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> Fuse <span class="hljs-keyword">from</span> <span class="hljs-string">'fuse.js'</span>;
</code></pre>
<p>If you want to test that it's working, you can <code>console.log(Fuse)</code> and see our <code>Fuse</code> class we'll use to create our search capabilities.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/fusejs-class.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Imported fuse.js class</em></p>
<p>And with that, we're ready to get started!</p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/54720daffa6ff415997c319b12f8f44d7ec8b748">Follow along with the commit</a></p>
<h2 id="heading-step-2-creating-a-new-fuse-search-instance">Step 2: Creating a new Fuse search instance</h2>
<p>To use Fuse.js, we'll want to first create a new instance of it.</p>
<p>At the top of your component, add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fuse = <span class="hljs-keyword">new</span> Fuse(characters, {
  <span class="hljs-attr">keys</span>: [
    <span class="hljs-string">'name'</span>,
    <span class="hljs-string">'company'</span>,
    <span class="hljs-string">'species'</span>
  ]
});
</code></pre>
<p>With this does:</p>
<ul>
<li>Creates a new instance of Fuse</li>
<li>Passes in our <code>characters</code> array of objects</li>
<li>Specifies the 3 keys in our data that we want to search on</li>
</ul>
<p>Next, to perform the search, we can add:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = fuse.search(<span class="hljs-string">'bender'</span>);
</code></pre>
<p>And if we console log out the results, we can see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/basic-fusejs-search-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Basic fuse.js search results</em></p>
<p>You'll notice that we have more results than our friend Bender though. Fuse.js provides a "fuzzy search" meaning it tries to help you in case you're not sure what you're looking for or if you're misspelling your query.</p>
<p>To get an idea of how this works, let's add the <code>includeScore</code> option to our search:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fuse = <span class="hljs-keyword">new</span> Fuse(characters, {
  <span class="hljs-attr">keys</span>: [
    <span class="hljs-string">'name'</span>,
    <span class="hljs-string">'company'</span>,
    <span class="hljs-string">'species'</span>
  ],
  <span class="hljs-attr">includeScore</span>: <span class="hljs-literal">true</span>
});
</code></pre>
<p>Now we can see the <code>score</code> attribute in our results object.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/fusejs-search-results-with-score.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Fuse.js search results with score</em></p>
<p>You'll notice that our first result has a really low score. With fuse.js, a lower score means it's closer to an exact match.</p>
<p>A score of 0 indicates a perfect match, while a score of 1 indicates a complete mismatch.</p>
<p>It's saying that is incredibly likely that the first result is what we're looking for, but it's not confident in the others.</p>
<p>So with our results, we want to actually connect that to our UI. If you notice our array output is different than what we are mapping through for the HTML list, so let's create a new variable that we can change it to:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = fuse.search(<span class="hljs-string">'bender'</span>);
<span class="hljs-keyword">const</span> characterResults = results.map(<span class="hljs-function"><span class="hljs-params">character</span> =&gt;</span> character.item);
</code></pre>
<p>What this is doing is creating a new array using the <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">map</a> method that will only include the <code>item</code> property from each array object.</p>
<p>Then if we replace our <code>characters</code> map inside of our list with <code>characterResults.map</code>:</p>
<pre><code class="lang-jsx">&lt;ul className=<span class="hljs-string">"characters"</span>&gt;
  {characterResults.map(<span class="hljs-function"><span class="hljs-params">character</span> =&gt;</span> {
    <span class="hljs-keyword">const</span> { name, company, species, thumb } = character;
</code></pre>
<p>We can now see that our page only shows the results for "bender"!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-filtered-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with filtered results</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/adbf30a872fa134cfca4e142ba479877b9665e9a">Follow along with the commit!</a></p>
<h2 id="heading-step-3-setting-up-dynamic-search-based-on-user-input">Step 3: Setting up dynamic search based on user input</h2>
<p>Now that we have a hard-coded search working, we want someone to actually be able to use the search input to search!</p>
<p>To achieve this, we're going to use the <code>useState</code> hook and listen for changes to the <code>input</code> field, which will dynamically create a search for our data.</p>
<p>First, import the <code>useState</code> hook from React:</p>
<pre><code class="lang-js"><span class="hljs-keyword">import</span> React, { useState } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
</code></pre>
<p>Next, let's use that hook to create a state instance:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [query, updateQuery] = useState(<span class="hljs-string">''</span>);
</code></pre>
<p>Here, we're creating a new state of <code>query</code> that we can update with <code>updateQuery</code> that defaults to an empty string (<code>''</code>).</p>
<p>With that, let's tell our search input to use that <code>query</code> value as it's value:</p>
<pre><code class="lang-jsx">&lt;input type=<span class="hljs-string">"text"</span> value={query} /&gt;
</code></pre>
<p>At this point, nothing should be different, as we are using a blank query.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-filtered-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with filtered results - nothing changed</em></p>
<p>Now let's add an event handler to our input that we can use to update our state:</p>
<pre><code class="lang-jsx">&lt;input type=<span class="hljs-string">"text"</span> value={query} onChange={onSearch} /&gt;
</code></pre>
<p>And we'll want to create that function so we can use it:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">onSearch</span>(<span class="hljs-params">{ currentTarget }</span>) </span>{
  updateQuery(currentTarget.value);
}
</code></pre>
<p>This will update our <code>query</code> with the input's value any time it changes.</p>
<p>Now that our <code>query</code>  will have what we want to search for, we can update our search instance:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> results = fuse.search(query);
</code></pre>
<p>And now if you reload the page, it's blank! ?</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-no-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with no results</em></p>
<p>That's because by default, Fuse sees our empty query and doesn't match it to anything. If we now search for something like <code>slurms</code>, we can see our search dynamically update with results!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-results.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with results for "slurms"</em></p>
<p>If we wanted to fix this though so that all of our results show when there's no query, we can do so with an <code>if</code> statement or in my example, a ternary, that will show all of the characters if there is no query:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> characterResults = query ? results.map(<span class="hljs-function"><span class="hljs-params">character</span> =&gt;</span> character.item) : characters;
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-demo.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with all results</em></p>
<p>And with that, we have our basic search!</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/futurama-character-search-results-query.jpg" alt="Image" width="600" height="400" loading="lazy">
<em>Demo with filtered results for "zoidberg"</em></p>
<p><a target="_blank" href="https://github.com/colbyfayock/my-futurama-characters/commit/1b8918fc56f31517686a6c73f1969787728736ac">Follow along with the commit!</a></p>
<h2 id="heading-what-can-i-do-next">What can I do next?</h2>
<h3 id="heading-tuning-your-search">Tuning your search</h3>
<p>Fuse.js comes with a lot of options that you can use to tune your search to however you'd like. Want to only show confident results? Use the <code>threshold</code> option! Want case sensitive queries? Use the <code>isCaseSensitive</code> option!</p>
<p><a target="_blank" href="https://fusejs.io/api/options.html">https://fusejs.io/api/options.html</a></p>
<h3 id="heading-setting-the-default-query-with-url-parameters">Setting the default query with URL parameters</h3>
<p>Sometimes you want someone to be able to link to a particular set of results. To do this, we might want to be able to add a new URL parameter like <code>?q=bender</code>.</p>
<p>To make this work, you can grab that URL parameter with javascript and use that value to set our <code>query</code> state.</p>
<h2 id="heading-join-the-conversation">Join the conversation!</h2>
<div class="embed-wrapper">
        <blockquote class="twitter-tweet">
          <a href="https://twitter.com/colbyfayock/status/1265298322891378688"></a>
        </blockquote>
        <script defer="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script></div>
<div id="colbyfayock-author-card">
  <p>
    <a href="https://twitter.com/colbyfayock">
      <img src="https://res.cloudinary.com/fay/image/upload/w_2000,h_400,c_fill,q_auto,f_auto/w_1020,c_fit,co_rgb:007079,g_north_west,x_635,y_70,l_text:Source%20Sans%20Pro_64_line_spacing_-10_bold:Colby%20Fayock/w_1020,c_fit,co_rgb:383f43,g_west,x_635,y_6,l_text:Source%20Sans%20Pro_44_line_spacing_0_normal:Follow%20me%20for%20more%20JavaScript%252c%20UX%252c%20and%20other%20interesting%20things!/w_1020,c_fit,co_rgb:007079,g_south_west,x_635,y_70,l_text:Source%20Sans%20Pro_40_line_spacing_-10_semibold:colbyfayock.com/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_68,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_145,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_222,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/w_300,c_fit,co_rgb:7c848a,g_north_west,x_1725,y_295,l_text:Source%20Sans%20Pro_40_line_spacing_-10_normal:colbyfayock/v1/social-footer-card" alt="Follow me for more Javascript, UX, and other interesting things!" width="2000" height="400" loading="lazy">
    </a>
  </p>
  <ul>
    <li>
      <a href="https://twitter.com/colbyfayock">? Follow Me On Twitter</a>
    </li>
    <li>
      <a href="https://youtube.com/colbyfayock">?️ Subscribe To My Youtube</a>
    </li>
    <li>
      <a href="https://www.colbyfayock.com/newsletter/">✉️ Sign Up For My Newsletter</a>
    </li>
  </ul>
</div>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
