# How the Search Algorithm Works in useTools.ts: FckSignups Tool Discovery Explained

> Discover how the FckSignups search algorithm in useTools.ts tokenizes queries, scores tools by keywords, and ranks results by match count and GitHub stars for precise tool discovery.

- Repository: [Abdullah/FckSignups](https://github.com/BraveOPotato/FckSignups)
- Tags: internals
- Published: 2026-09-08

---

**The search algorithm in [`useTools.ts`](https://github.com/BraveOPotato/FckSignups/blob/main/useTools.ts) implements an AND-match relevance engine that tokenizes queries, scores tools based on keyword presence in name/description/tags, and ranks results by match count and GitHub stars.**

The [`useTools.ts`](https://github.com/BraveOPotato/FckSignups/blob/main/useTools.ts) hook in the BraveOPotato/FckSignups repository powers the application's tool discovery feature, implementing a client-side search algorithm that filters and ranks developer tools without requiring a backend. This implementation processes user queries through a pipeline of tokenization, strict AND-matching, and multi-criteria sorting to deliver precisely relevant results ranked by community popularity.

## Core Components of the Search Implementation

The algorithm relies on three discrete helper functions defined in [`src/hooks/useTools.ts`](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useTools.ts) that transform raw query strings into ranked, sectioned results suitable for UI rendering.

### Tokenization Logic

The `tokenize` function normalizes user input by converting queries to lowercase and splitting on non-alphanumeric characters using the regex `/[^a-z0-9+]+/`. It strips punctuation and filters out empty strings, returning an array of clean search keywords. For example, the query `"Video Editor!"` becomes `["video", "editor"]`.

### Relevance Scoring with `matchScore`

The `matchScore` function calculates relevance by creating a lowercase "haystack" string concatenated from the tool's `name`, `description`, and `tags` properties. It iterates through the tokenized keywords and counts how many appear within this haystack, returning an integer score representing the number of matching terms.

### Result Sectioning via `sectionize`

After filtering and sorting complete, the `sectionize` function groups the final tool list into three distinct UI sections: **featured** tools, **editor's picks**, and tools that **meet the search criteria**. This organizes results for better user experience without affecting the underlying search logic.

## Step-by-Step Query Processing Pipeline

When the hook executes, it processes searches through a five-stage pipeline managed within React `useMemo` hooks to optimize performance and prevent unnecessary recalculations.

1. **Query Tokenization** — The hook memoizes tokenized keywords using `tokenize(searchQuery)` to avoid reprocessing identical strings on every render.

2. **Search State Detection** — The algorithm sets `isSearching = searchKeywords.length > 0` (evaluating at lines 90-91 in the source) to toggle between browse mode and active search mode.

3. **Category Pre-filtering** — Tools are first filtered by `activeCategory` before scoring occurs. This ensures category restrictions apply to the candidate pool before relevance calculation begins.

4. **Strict AND-Match Filtering** — For every remaining tool, the algorithm computes `matchScore(tool, keywords)` and enforces strict conjunctive logic by requiring `score == keywords.length`. This means **every** query term must appear somewhere in the tool's name, description, or tags for inclusion in results.

5. **Dual-Criteria Sorting** — Validated results are sorted using a comparator that first orders by descending `score` (relevance), then by descending `stars` count (GitHub popularity) to break ties using community trust signals.

## Ranking Strategy: AND-Match, Relevance, and Popularity

The FckSignups search algorithm employs a three-tier strategy that balances precision with discoverability:

- **AND-Match Precision** — Unlike OR-match systems that return results containing any keyword, this implementation requires all tokens to be present (`score == keywords.length`), ensuring high-precision results that match the complete user intent.

- **Relevance Weighting** — Tools matching more keywords rank higher through the `b.score - a.score` comparator, guaranteeing that exact matches outrank partial overlaps.

- **Popularity Fallback** — When relevance scores tie, the algorithm defaults to GitHub popularity using `b.tool.stars - a.tool.stars`, surfacing community-validated tools ahead of lesser-known alternatives with identical keyword matches.

## Implementation Examples

The following patterns demonstrate how to leverage the search algorithm in production code:

```typescript
// Basic search for tools containing both "video" and "editor"
const { filteredTools, isSearching } = useTools();

useEffect(() => {
  setSearchQuery("video editor");
}, []);

// filteredTools contains only tools with both keywords in their
// name, description, or tags, sorted by relevance then star count

```

```typescript
// Category-constrained search
setActiveCategory("productivity");
setSearchQuery("time tracker");

// Results are limited to productivity tools containing both
// "time" and "tracker" keywords

```

```typescript
// Direct helper usage for unit testing
import { tokenize, matchScore } from "./useTools";

const keywords = tokenize("photo collage");
const score = matchScore(someTool, keywords);
// score equals the number of query words present in the tool's data

```

## Summary

- The [`src/hooks/useTools.ts`](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useTools.ts) hook implements a client-side AND-match search algorithm requiring all query terms to appear in tool metadata before inclusion in results.
- Three helper functions—`tokenize`, `matchScore`, and `sectionize`—handle string normalization, relevance calculation, and UI grouping respectively.
- The algorithm filters by `activeCategory` first, then applies strict keyword matching logic that requires `score == keywords.length` for acceptance.
- Results are sorted first by descending match relevance, then by descending GitHub stars to balance accuracy with community validation.
- The implementation relies on React `useMemo` hooks to cache expensive tokenization and filtering operations between renders.

## Frequently Asked Questions

### Does the search algorithm support partial word matching?

The current implementation does not support partial word matching or fuzzy search. The `tokenize` function splits queries on non-alphanumeric boundaries using `/[^a-z0-9+]+/`, and `matchScore` checks for exact token presence in the tool's `name`, `description`, or `tags` fields. A search for "edit" will not match a tool containing only "editor" unless both terms are explicitly present in the query.

### How does the algorithm handle multiple search keywords?

The algorithm treats multiple keywords as a logical AND operation rather than OR. In the scoring phase, tools must accumulate a `matchScore` equal to the total number of query keywords to survive filtering. This ensures that searching for "video editor" returns only tools containing both terms somewhere in their metadata, eliminating results that match only one keyword.

### What determines the final order of search results?

Results are sorted using a two-tier comparator defined in the source. First, tools sort by descending relevance score (the number of matching keywords). If two tools achieve identical scores, the algorithm applies a secondary sort using descending GitHub stars (`tool.stars`), prioritizing more popular community tools when relevance is equal.

### Can the search functions be used outside the useTools hook?

Yes, both `tokenize` and `matchScore` are pure utility functions that can be imported directly from [`src/hooks/useTools.ts`](https://github.com/BraveOPotato/FckSignups/blob/main/src/hooks/useTools.ts) for unit testing or custom filter implementations. These functions have no React dependencies and accept standard strings and tool objects, making them portable for testing scoring logic independently of the React component lifecycle.