Powerful fuzzy search for Angular applications with automatic highlighting, built on Fuse.js
🚀 Try Live Demo • Installation • Quick Start • Documentation • Examples
- 🚀 Modern Angular - Built for Angular 20+ (LTS) with standalone components
- 🔍 Fuzzy Search - Powered by Fuse.js
- ✨ Highlight Support - Automatically highlight matched terms
- 🎯 Type Safe - Full TypeScript support
- 🪶 Lightweight - Zero dependencies (except Angular & Fuse.js)
- 📦 Tree Shakeable - Optimized bundle size
npm install @almothafar/angular-fusejs fuse.jsimport {Component} from '@angular/core';
import {AngularFuseJsPipe} from '@almothafar/angular-fusejs';
import {FormsModule} from '@angular/forms';
@Component({
selector: 'app-search',
imports: [AngularFuseJsPipe, FormsModule],
template: `
<input [(ngModel)]="searchTerm" placeholder="Search books...">
<div *ngFor="let book of books | fuseJsSearch: searchTerm : { keys: ['title', 'author'], supportHighlight: true }">
<h3 [innerHTML]="book.fuseJsHighlighted?.title || book.title"></h3>
<p>{{ book.author }}</p>
</div>
`
})
export class SearchComponent {
books = [
{title: 'JavaScript: The Good Parts', author: 'Douglas Crockford'},
{title: 'Clean Code', author: 'Robert Martin'},
{title: 'The Pragmatic Programmer', author: 'Hunt and Thomas'}
];
searchTerm = '';
}For complete documentation, examples, and API reference, see the library README.
Run the demo application locally:
# Install dependencies (this repo uses pnpm)
pnpm install
# Serve demo app (automatically uses local library)
pnpm startNavigate to http://localhost:4200/ to see the library in action!
import { Component } from '@angular/core';
import { AngularFuseJsPipe } from '@almothafar/angular-fusejs';
import { FormsModule } from '@angular/forms';
import { CommonModule } from '@angular/common';
@Component({
selector: 'app-book-search',
imports: [CommonModule, FormsModule, AngularFuseJsPipe],
template: `
<div class="search-container">
<input
[(ngModel)]="searchQuery"
placeholder="Search books..."
class="search-input"
>
<div class="results">
<div
*ngFor="let book of books | fuseJsSearch: searchQuery : searchOptions"
class="book-card"
>
<h3 [innerHTML]="book.fuseJsHighlighted?.title || book.title"></h3>
<p class="author" [innerHTML]="book.fuseJsHighlighted?.author || book.author"></p>
<span class="score">Match: {{ (1 - (book.fuseJsScore || 0)) * 100 | number:'1.0-0' }}%</span>
</div>
</div>
</div>
`
})
export class BookSearchComponent {
searchQuery = '';
books = [
{ title: 'JavaScript: The Good Parts', author: 'Douglas Crockford', year: 2008 },
{ title: 'Clean Code', author: 'Robert C. Martin', year: 2008 },
{ title: 'The Pragmatic Programmer', author: 'Andrew Hunt', year: 1999 },
{ title: 'Design Patterns', author: 'Gang of Four', year: 1994 }
];
searchOptions = {
keys: ['title', 'author'],
supportHighlight: true,
threshold: 0.4,
minSearchTermLength: 2
};
}import { Component, OnInit, inject } from '@angular/core';
import { AngularFuseJsService } from '@almothafar/angular-fusejs';
import { FormControl } from '@angular/forms';
import { debounceTime, distinctUntilChanged } from 'rxjs/operators';
@Component({
selector: 'app-advanced-search',
template: `
<input [formControl]="searchControl" placeholder="Type to search...">
<div *ngFor="let item of results">
<h4 [innerHTML]="item.fuseJsHighlighted.name"></h4>
<small>Relevance: {{ (1 - item.fuseJsScore) * 100 }}%</small>
</div>
`
})
export class AdvancedSearchComponent implements OnInit {
private fuseService = inject(AngularFuseJsService);
searchControl = new FormControl('');
results: any[] = [];
data = [
{ name: 'Angular Framework', description: 'Web application framework' },
{ name: 'React Library', description: 'JavaScript library for UI' },
{ name: 'Vue.js', description: 'Progressive JavaScript framework' }
];
ngOnInit() {
this.searchControl.valueChanges.pipe(
debounceTime(300),
distinctUntilChanged()
).subscribe(searchTerm => {
this.results = this.fuseService.searchList(
this.data,
searchTerm || '',
{
keys: ['name', 'description'],
supportHighlight: true,
threshold: 0.3,
maximumScore: 0.6 // Only show good matches
}
);
});
}
}pnpm run buildpnpm run build:prodpnpm testThe demo app automatically uses the local library via TypeScript path mapping. Just run:
pnpm startAny changes you make to the library will require a rebuild:
pnpm run build
# Then restart the demoBefore publishing, always test your changes:
-
Build the library:
pnpm run build
-
Run unit tests:
pnpm run test -
Test in the demo app:
# The demo automatically uses the local built library pnpm start # Visit http://localhost:4200 and test the functionality
-
Check for TypeScript errors:
pnpm exec ng build @almothafar/angular-fusejs --configuration production
Version 3.0.0 is a complete rewrite for Angular 20+ (LTS). See the migration guide for breaking changes.
For older Angular versions (14 to "Until it breaks"), use version 2.x:
npm install @almothafar/angular-fusejs@2.1.0Contributions are welcome! Please feel free to submit a Pull Request.
MIT © Al-Mothafar Al-Hasan
- 🐛 Report Bug
- 💡 Request Feature
- ⭐ Star this repo if you find it helpful!
♥️ Consider buying me a coffee!
Made with ❤️ by Al-Mothafar Al-Hasan