A powerful, SQL-like array filtering library for TypeScript and JavaScript with advanced pattern matching, MongoDB-style operators, deep object comparison, and zero dependencies.
Go beyond JavaScript's native Array.filter() with a library that understands your data:
- ๐ฏ SQL-like Wildcards - Use
%and_for flexible pattern matching - ๐ Deep Object Filtering - Search through nested objects up to configurable depths
- โก Zero Dependencies - Lightweight and production-ready (only Zod for runtime validation)
- ๐ Type-Safe - Built with strict TypeScript for maximum reliability
- โจ Smart Autocomplete - IntelliSense suggests only valid operators for each property type
- ๐จ Multiple Strategies - String patterns, objects, predicates, operators, or custom comparators
- ๐ Performance Optimized - Optional caching and regex compilation optimization
- ๐ฆ MongoDB-Style Operators - 30+ operators for advanced filtering (v5.0.0+)
- ๐ Geospatial Operators - Location-based filtering with $near, $geoBox, $geoPolygon (v5.6.0+)
- ๐ Date/Time Operators - Temporal filtering with $recent, $upcoming, $dayOfWeek, $age (v5.6.0+)
- ๐จ Lazy Evaluation - Process large datasets efficiently with generators (v5.1.0+)
- ๐จ Framework Integrations - React, Vue, and Svelte support (v5.3.0+)
- ๐งช Battle-Tested - 613+ tests ensuring reliability
# Using npm npm install @mcabreradev/filter # Using yarn yarn add @mcabreradev/filter # Using pnpm pnpm add @mcabreradev/filterRequirements: Node.js >= 20, TypeScript 5.0+ (optional)
import { filter } from '@mcabreradev/filter'; const users = [ { name: 'Alice', email: 'alice@example.com', age: 30, city: 'Berlin' }, { name: 'Bob', email: 'bob@example.com', age: 25, city: 'London' }, { name: 'Charlie', email: 'charlie@example.com', age: 35, city: 'Berlin' } ]; // Simple string matching (case-insensitive by default) filter(users, 'Berlin'); // โ Returns Alice and Charlie // Wildcard patterns (SQL-like) filter(users, '%alice%'); // โ Returns Alice // Object-based filtering filter(users, { city: 'Berlin', age: 30 }); // โ Returns Alice // Negation support filter(users, '!London'); // โ Returns Alice and Charlie // Predicate functions filter(users, (user) => user.age > 28); // โ Returns Alice and Charlie // v5.0.0: MongoDB-style operators filter(users, { age: { $gte: 25, $lt: 35 } }); // โ Returns Bob and Alice filter(users, { city: { $in: ['Berlin', 'Paris'] } }); // โ Returns Alice and Charlie filter(users, { name: { $startsWith: 'A' } }); // โ Returns AliceNew in v5.4.0: Full framework integration support for React, Vue, and Svelte!
import { useFilter, useDebouncedFilter, usePaginatedFilter } from '@mcabreradev/filter'; function UserList() { const { filtered, isFiltering } = useFilter(users, { active: true }); return ( <div> {isFiltering && <span>Filtering...</span>} {filtered.map(user => <User key={user.id} {...user} />)} </div> ); } function SearchUsers() { const [search, setSearch] = useState(''); const { filtered, isPending } = useDebouncedFilter(users, search, { delay: 300 }); return ( <div> <input onChange={(e) => setSearch(e.target.value)} /> {isPending && <span>Loading...</span>} {filtered.map(user => <User key={user.id} {...user} />)} </div> ); }<script setup> import { ref } from 'vue'; import { useFilter, usePaginatedFilter } from '@mcabreradev/filter'; const searchTerm = ref(''); const { filtered, isFiltering } = useFilter(users, searchTerm); </script> <template> <div> <span v-if="isFiltering">Filtering...</span> <div v-for="user in filtered" :key="user.id">{{ user.name }}</div> </div> </template><script> import { writable } from 'svelte/store'; import { useFilter } from '@mcabreradev/filter'; const searchTerm = writable(''); const { filtered, isFiltering } = useFilter(users, searchTerm); </script> {#if $isFiltering} <span>Filtering...</span> {/if} {#each $filtered as user (user.id)} <div>{user.name}</div> {/each}Features:
- โ
React Hooks:
useFilter,useFilteredState,useDebouncedFilter,usePaginatedFilter - โ Vue Composables: Full Composition API support with reactivity
- โ Svelte Stores: Reactive stores with derived state
- โ TypeScript: Full type safety with generics
- โ SSR Compatible: Works with Next.js, Nuxt, and SvelteKit
See Framework Integrations Guide for complete documentation.
Filter by simple values across all object properties:
const products = [ { id: 1, name: 'Laptop', price: 1200 }, { id: 2, name: 'Mouse', price: 25 }, { id: 3, name: 'Monitor', price: 450 } ]; // String search filter(products, 'Laptop'); // โ [{ id: 1, ... }] // Number search filter(products, 25); // โ [{ id: 2, ... }] // Boolean search filter(tasks, true); // Finds all completed tasksSQL-like wildcards for flexible matching:
// % matches zero or more characters filter(users, '%alice%'); // Contains 'alice' filter(users, 'Al%'); // Starts with 'Al' filter(users, '%son'); // Ends with 'son' // _ matches exactly one character filter(codes, 'A_'); // 'A1', 'A2', but not 'AB1' filter(ids, 'user-10_'); // 'user-101', 'user-102' // Negation with ! filter(users, '!admin'); // Exclude admin filter(files, '!%.pdf'); // Exclude PDFsMatch by specific properties (AND logic):
// Single property filter(products, { category: 'Electronics' }); // Multiple properties (all must match) filter(products, { category: 'Electronics', price: 1200, inStock: true }); // Nested objects filter(users, { address: { city: 'Berlin' }, settings: { theme: 'dark' } });Powerful operators for advanced filtering with intelligent autocomplete - TypeScript suggests only valid operators for each property type!
interface Product { name: string; price: number; tags: string[]; inStock: boolean; } // TypeScript autocompletes operators based on property types filter(products, { price: { // Suggests: $gt, $gte, $lt, $lte, $eq, $ne $gte: 100, $lte: 500 }, name: { // Suggests: $startsWith, $endsWith, $contains, $regex, $match, $eq, $ne $startsWith: 'Laptop' }, tags: { // Suggests: $in, $nin, $contains, $size $contains: 'sale' }, inStock: { // Suggests: $eq, $ne $eq: true } });๐ Learn more about autocomplete โ
// Greater than / Less than filter(products, { price: { $gt: 100 } }); filter(products, { price: { $lte: 500 } }); // Range queries filter(products, { price: { $gte: 100, $lte: 500 } }); // Date ranges filter(orders, { date: { $gte: new Date('2025-01-01'), $lte: new Date('2025-12-31') } }); // Not equal filter(users, { role: { $ne: 'guest' } });Available: $gt, $gte, $lt, $lte, $eq, $ne
// In / Not in array filter(products, { category: { $in: ['Electronics', 'Books'] } }); filter(products, { status: { $nin: ['archived', 'deleted'] } }); // Array contains value filter(products, { tags: { $contains: 'sale' } }); // Array size filter(products, { images: { $size: 3 } });Available: $in, $nin, $contains, $size
// Starts with / Ends with filter(users, { email: { $endsWith: '@company.com' } }); filter(files, { name: { $startsWith: 'report-' } }); // Contains substring filter(articles, { title: { $contains: 'typescript' } }); // Regular expressions filter(users, { email: { $regex: '^[a-z]+@example\\.com$' } }); filter(users, { phone: { $regex: /^\+1-\d{3}-\d{4}$/ } }); // $match is an alias for $regex filter(users, { username: { $match: '^[a-z]+\\d+$' } });Available: $startsWith, $endsWith, $contains, $regex, $match
Combine multiple conditions with logical operators:
// $and - All conditions must match filter(products, { $and: [ { category: 'Electronics' }, { inStock: true }, { price: { $lt: 1000 } } ] }); // $or - At least one condition must match filter(products, { $or: [ { category: 'Electronics' }, { category: 'Accessories' } ] }); // $not - Negates the condition filter(products, { $not: { category: 'Furniture' } }); // Complex nested queries filter(products, { $and: [ { inStock: true }, { $or: [ { rating: { $gte: 4.5 } }, { price: { $lt: 50 } } ] }, { $not: { category: 'Clearance' } } ] }); // Combine with field-level conditions filter(products, { category: 'Electronics', $and: [ { price: { $gte: 100 } }, { $or: [{ inStock: true }, { preOrder: true }] } ] });Available: $and, $or, $not
// Multiple operators, multiple properties filter(products, { price: { $gte: 100, $lte: 500 }, category: { $in: ['Electronics', 'Accessories'] }, name: { $startsWith: 'Pro' }, inStock: { $eq: true } });New in v5.5.0: Intuitive array-based OR filtering without explicit $in operator!
// Array syntax - clean and intuitive (OR logic) filter(products, { category: ['Electronics', 'Books'] }); // Equivalent to: { category: { $in: ['Electronics', 'Books'] } } // Multiple properties with array OR (independent OR conditions) filter(products, { category: ['Electronics', 'Accessories'], price: [100, 200, 300] }); // Logic: (category === 'Electronics' OR category === 'Accessories') // AND (price === 100 OR price === 200 OR price === 300) // Combining array OR with other conditions (AND logic) filter(users, { city: ['Berlin', 'Paris'], age: 30, role: ['admin', 'moderator'] }); // Logic: (city === 'Berlin' OR city === 'Paris') // AND age === 30 // AND (role === 'admin' OR role === 'moderator') // Works with wildcards filter(users, { email: ['%@gmail.com', '%@yahoo.com'] }); // Matches emails ending with @gmail.com OR @yahoo.com // Empty array matches nothing filter(products, { category: [] }); // โ Returns empty arrayBenefits:
- โจ More intuitive than
$inoperator - ๐ Cleaner, more readable code
- ๐ 100% backward compatible
- ๐ฏ Works with strings, numbers, booleans
- ๐ Supports wildcard patterns
New in v5.6.0: Filter by geographic location with powerful spatial operators!
import { filter, type GeoPoint } from '@mcabreradev/filter'; interface Restaurant { name: string; location: GeoPoint; rating: number; } const userLocation: GeoPoint = { lat: 52.52, lng: 13.405 }; // $near - Find points within radius filter(restaurants, { location: { $near: { center: userLocation, maxDistanceMeters: 5000 } } }); // $geoBox - Bounding box queries filter(stores, { location: { $geoBox: { southwest: { lat: 52.5, lng: 13.3 }, northeast: { lat: 52.6, lng: 13.5 } } } }); // $geoPolygon - Polygon containment filter(properties, { location: { $geoPolygon: { points: [ { lat: 51.5074, lng: -0.1278 }, { lat: 51.5100, lng: -0.1200 }, { lat: 51.5050, lng: -0.1150 }, { lat: 51.5020, lng: -0.1250 } ] } } }); // Combine with other filters filter(restaurants, { location: { $near: { center: userLocation, maxDistanceMeters: 3000 } }, rating: { $gte: 4.5 }, isOpen: true });Available: $near, $geoBox, $geoPolygon
Features:
- ๐ Location-based filtering
- ๐ Accurate distance calculation
- ๐บ๏ธ Bounding box and polygon support
- โก Fast spherical law of cosines
- ๐ Automatic coordinate validation
See Geospatial Operators Guide for complete documentation.
New in v5.6.0: Filter by relative time, days of week, time of day, and age calculations!
import { filter } from '@mcabreradev/filter'; interface Event { name: string; date: Date; startTime: Date; } const events: Event[] = [...]; // Events in next 7 days filter(events, { date: { $upcoming: { days: 7 } } }); // Recent events (last 24 hours) filter(events, { date: { $recent: { hours: 24 } } }); // Weekday events only filter(events, { date: { $dayOfWeek: [1, 2, 3, 4, 5] } }); // Business hours events (9 AM - 5 PM) filter(events, { startTime: { $timeOfDay: { start: 9, end: 17 } } }); // Adult users (18+) filter(users, { birthDate: { $age: { min: 18 } } }); // Weekend events filter(events, { date: { $isWeekend: true } }); // Combine multiple datetime conditions filter(events, { date: { $upcoming: { days: 7 }, $dayOfWeek: [1, 2, 3, 4, 5] }, startTime: { $timeOfDay: { start: 9, end: 17 } } });Available: $recent, $upcoming, $dayOfWeek, $timeOfDay, $age, $isWeekday, $isWeekend, $isBefore, $isAfter
Features:
- ๐ Relative time filtering (last/next N days/hours/minutes)
- ๐๏ธ Day of week filtering (0-6)
- โฐ Time of day filtering (0-23 hours)
- ๐ Age calculation (years/months/days)
- ๐ Weekday/weekend filtering
- ๐ Full TypeScript support with autocomplete
See Date/Time Operators Guide for complete documentation.
For complex custom logic:
// Simple predicate filter(numbers, (n) => n > 5); // Complex conditions filter(products, (product) => product.price < 100 && product.inStock && product.rating >= 4.0 ); // Type-safe with TypeScript filter<Product>(products, (p: Product): boolean => p.price > 100 && p.name.includes('Pro') );Efficiently process large datasets with lazy evaluation:
import { filterLazy, filterFirst, filterExists, filterCount, toArray, take, map } from '@mcabreradev/filter'; // Lazy evaluation - process items on-demand const filtered = filterLazy(millionRecords, { active: true }); for (const item of filtered) { process(item); if (shouldStop) break; // Early exit - stops processing immediately } // Find first N matches with early exit optimization const first10 = filterFirst(users, { premium: true }, 10); // Check existence without processing all items const hasAdmin = filterExists(users, { role: 'admin' }); // Count matching items const activeCount = filterCount(users, { active: true }); // Compose lazy operations for powerful pipelines const result = toArray( take( map(filterLazy(users, { active: true }), u => u.name), 100 ) ); // Chunked processing for batch operations for (const chunk of filterLazyChunked(largeDataset, { needsProcessing: true }, 1000)) { await api.batchUpdate(chunk); }Benefits:
- ๐ 500x faster for operations that don't need all results
- ๐พ 100,000x less memory for large datasets
- โก Early exit optimization for existence checks
- ๐ Streaming support for async data sources
- ๐ฆ Chunked processing for batch operations
See Lazy Evaluation Guide for complete documentation.
New in v5.2.0: Advanced multi-layer memoization strategy for maximum performance.
The library implements a sophisticated caching system with three layers:
- Result Cache - Caches complete filter results
- Predicate Cache - Memoizes compiled predicate functions
- Regex Cache - Caches compiled regex patterns
import { filter, clearFilterCache, getFilterCacheStats } from '@mcabreradev/filter'; const largeDataset = [...]; // First call - processes data const results = filter(largeDataset, { age: { $gte: 18 } }, { enableCache: true }); // Second call - returns cached result instantly const sameResults = filter(largeDataset, { age: { $gte: 18 } }, { enableCache: true });| Scenario | Without Cache | With Cache | Speedup |
|---|---|---|---|
| Simple query (10K items) | 5.3ms | 0.01ms | 530x |
| Regex pattern | 12.1ms | 0.02ms | 605x |
| Complex nested | 15.2ms | 0.01ms | 1520x |
const products = await fetchProducts(); const electronics = filter( products, { category: { $in: ['Electronics', 'Computers'] }, price: { $gte: 100, $lte: 2000 }, inStock: true, rating: { $gte: 4.0 } }, { enableCache: true } ); const electronicsAgain = filter( products, { category: { $in: ['Electronics', 'Computers'] }, price: { $gte: 100, $lte: 2000 }, inStock: true, rating: { $gte: 4.0 } }, { enableCache: true } );// Get cache statistics const stats = getFilterCacheStats(); console.log(stats); // { hits: 150, misses: 10, size: 25, hitRate: 0.9375 } // Clear cache when data changes clearFilterCache(); // Memory management let data = [/* large dataset */]; filter(data, query, { enableCache: true }); data = null; // Cache will be garbage collectedโ Enable for:
- Large datasets (>1,000 items)
- Repeated identical queries
- Complex expressions with regex
- Read-heavy workloads
- Dashboard/analytics views
โ Disable for:
- Frequently changing data
- One-time queries
- Memory-constrained environments
- Unique expressions every time
import { filter, clearFilterCache } from '@mcabreradev/filter'; class ProductDashboard { private products: Product[]; constructor(products: Product[]) { this.products = products; } getElectronics() { return filter( this.products, { category: 'Electronics' }, { enableCache: true } ); } getHighRated() { return filter( this.products, { rating: { $gte: 4.5 } }, { enableCache: true } ); } refreshData(newProducts: Product[]) { this.products = newProducts; clearFilterCache(); } } const dashboard = new ProductDashboard(products); dashboard.getElectronics(); dashboard.getHighRated(); dashboard.getElectronics(); dashboard.getHighRated();See Memoization Guide for complete documentation.
New in v5.5.0: Built-in debug mode with expression tree visualization, performance metrics, and condition tracking!
Enable debug mode to see how your filter expressions are evaluated:
import { filter } from '@mcabreradev/filter'; // Enable debug mode with config option filter(users, { city: 'Berlin' }, { debug: true }); // Console output: // โโ Filter Debug Tree // โ Expression: {"city":"Berlin"} // โ Matched: 3/10 (30.0%) // โ Execution time: 0.42ms // โโ โ city = "Berlin"// Verbose mode - detailed evaluation info filter(users, { age: { $gte: 25 } }, { debug: true, verbose: true }); // Show execution timings filter(products, { premium: true }, { debug: true, showTimings: true }); // Colorized output (ANSI colors) filter(users, { city: 'Berlin' }, { debug: true, colorize: true }); // All options combined filter(users, { age: { $gte: 25 }, city: 'Berlin' }, { debug: true, verbose: true, showTimings: true, colorize: true });Use filterDebug for programmatic access to debug information:
import { filterDebug } from '@mcabreradev/filter'; const result = filterDebug(users, { age: { $gte: 30 } }); console.log('Matched:', result.items.map(u => u.name)); console.log('Stats:', { matched: result.stats.matched, total: result.stats.total, percentage: result.stats.percentage, executionTime: result.stats.executionTime, conditionsEvaluated: result.stats.conditionsEvaluated }); // Access debug tree console.log('Debug Tree:', result.debug.tree);Visualize complex nested expressions:
filter(products, { $and: [ { category: 'Electronics' }, { inStock: true }, { $or: [ { rating: { $gte: 4.5 } }, { price: { $lt: 50 } } ] } ] }, { debug: true, verbose: true }); // Console output shows tree structure: // โโ Filter Debug Tree // โ Expression: Complex nested query // โ Matched: 5/10 (50.0%) // โ Execution time: 1.23ms // โโ AND // โ โโ โ category = "Electronics" // โ โโ โ inStock = true // โ โโ OR // โ โโ โ rating >= 4.5 // โ โโ โ price < 50 // โโ Conditions evaluated: 8Debug Options:
debug(boolean) - Enable debug modeverbose(boolean) - Show detailed evaluation infoshowTimings(boolean) - Display execution timingscolorize(boolean) - Use ANSI colors in output
Use Cases:
- ๐ Understanding complex filter logic
- โก Performance optimization
- ๐ Debugging unexpected results
- ๐ Analytics and monitoring
- ๐งช Testing and validation
Customize filter behavior with options:
import { filter } from '@mcabreradev/filter'; // Case-sensitive matching filter(users, 'ALICE', { caseSensitive: true }); // Increase max depth for nested objects filter(data, expression, { maxDepth: 5 }); // Enable caching for repeated queries filter(largeDataset, expression, { enableCache: true }); // Enable debug mode (v5.5.0+) filter(users, expression, { debug: true }); // Custom comparison logic filter(data, expression, { customComparator: (actual, expected) => actual === expected });Available Options:
caseSensitive(boolean, default:false) - Case-sensitive string matchingmaxDepth(number, default:3, range: 1-10) - Max depth for nested objectsenableCache(boolean, default:false) - Enable result cachingdebug(boolean, default:false) - Enable debug mode with tree visualization (v5.5.0+)verbose(boolean, default:false) - Show detailed evaluation info in debug mode (v5.5.0+)showTimings(boolean, default:false) - Display execution timings in debug mode (v5.5.0+)colorize(boolean, default:false) - Use ANSI colors in debug output (v5.5.0+)customComparator(function, optional) - Custom comparison function
Full TypeScript support with strict typing:
import { filter } from '@mcabreradev/filter'; import type { Expression, FilterOptions, ComparisonOperators } from '@mcabreradev/filter'; interface Product { id: number; name: string; price: number; category: string; } const products: Product[] = [...]; // Type-safe filtering const result = filter<Product>(products, { price: { $gte: 100 } }); // result is Product[] // Type-safe expressions const priceFilter: ComparisonOperators = { $gte: 100, $lte: 500 }; filter<Product>(products, { price: priceFilter });interface Product { id: number; name: string; price: number; category: string; brand: string; rating: number; inStock: boolean; tags: string[]; createdAt: Date; } const products: Product[] = [...]; // E-commerce: Find affordable, highly-rated electronics in stock const affordableElectronics = filter(products, { category: 'Electronics', price: { $lte: 1000 }, rating: { $gte: 4.5 }, inStock: { $eq: true } }); // Search: Products matching keyword with filters const searchResults = filter(products, { name: { $contains: 'laptop' }, brand: { $in: ['Apple', 'Dell', 'HP'] }, price: { $gte: 500, $lte: 2000 } }); // Analytics: Recent high-value orders const thirtyDaysAgo = new Date(); thirtyDaysAgo.setDate(thirtyDaysAgo.getDate() - 30); const recentHighValue = filter(orders, { createdAt: { $gte: thirtyDaysAgo }, amount: { $gte: 1000 }, status: { $in: ['completed', 'shipped'] } });Filter is optimized for performance:
- Operators use early exit strategies for fast evaluation
- Regex patterns are compiled and cached
- Optional caching for repeated queries on large datasets (530x-1520x faster)
- Lazy evaluation for efficient large dataset processing (500x faster)
- Type guards for fast type checking
// โ
Fast: Operators with early exit filter(data, { age: { $gte: 18 } }); // โ
Fast with caching for repeated queries filter(largeData, expression, { enableCache: true }); // โ
Fast with lazy evaluation for large datasets const result = filterFirst(millionRecords, { active: true }, 100); // โ ๏ธ Slower: Complex predicates (but more flexible) filter(data, (item) => complexCalculation(item));For performance optimization tips, see Performance Guide.
- Complete Wiki - Complete documentation with 150+ examples, API reference, TypeScript guide, real-world use cases, FAQ, and troubleshooting
- Framework Integrations - Complete guide for React, Vue, and Svelte integrations
- Operators Guide - Detailed guide for all 30+ MongoDB-style operators with examples and advanced regex patterns
- Geospatial Operators - Complete guide for location-based filtering with $near, $geoBox, $geoPolygon
- Date/Time Operators - Complete guide for temporal filtering with $recent, $upcoming, $dayOfWeek, $age
- Lazy Evaluation - Comprehensive guide to lazy evaluation for efficient large dataset processing
- Logical Operators - Advanced patterns and complex queries with $and, $or, $not
- Performance Benchmarks - Detailed performance metrics and optimization strategies
- Migration Guide - Migration guide from v3.x or native Array.filter()
- Examples - Real-world usage examples and code samples
- Installation & Setup
- Interactive Playground ๐ฎ NEW
- Framework Integrations โญ NEW
- Geospatial Operators ๐ NEW
- Date/Time Operators ๐ NEW
- All Operators Reference
- Regex Patterns Guide
- Logical Operators Guide
- Lazy Evaluation
- Memoization & Caching
- Performance Benchmarks
- TypeScript Integration
- Real-World Examples
- Performance Tips
- API Reference
- FAQ
- Troubleshooting
Good news: v5.x is 100% backward compatible! All v3.x code continues to work.
// โ
All v3.x syntax still works filter(data, 'string'); filter(data, { prop: 'value' }); filter(data, (item) => true); filter(data, '%pattern%'); // โ
New in v5.x filter(data, { age: { $gte: 18 } }); filter(data, expression, { caseSensitive: true }); filter(data, expression, { enableCache: true });What's New in v5.x:
- v5.5.0: Array OR syntax, visual debugging, interactive playground
- v5.4.0: Framework integrations (React, Vue, Svelte)
- v5.3.0: Initial framework support
- v5.2.0: Enhanced memoization, logical operators ($and, $or, $not), regex operators
- v5.1.0: Lazy evaluation with generators
- v5.0.0: 18+ MongoDB-style operators, configuration API, runtime validation
See Migration Guide for detailed migration guide.
// Main filter function filter<T>(array: T[], expression: Expression<T>, options?: FilterOptions): T[] // Lazy evaluation functions filterLazy<T>(array: T[], expression: Expression<T>, options?: FilterOptions): IterableIterator<T> filterFirst<T>(array: T[], expression: Expression<T>, count: number, options?: FilterOptions): T[] filterExists<T>(array: T[], expression: Expression<T>, options?: FilterOptions): boolean filterCount<T>(array: T[], expression: Expression<T>, options?: FilterOptions): number // Validation functions validateExpression(expression: unknown): Expression<T> validateOptions(options: unknown): FilterOptions // Cache management clearFilterCache(): void getFilterCacheStats(): { hits: number; misses: number; size: number; hitRate: number } // Configuration mergeConfig(options?: FilterOptions): FilterConfig createFilterConfig(options?: FilterOptions): FilterConfig // Geospatial utilities calculateDistance(p1: GeoPoint, p2: GeoPoint): number isValidGeoPoint(point: unknown): point is GeoPoint evaluateNear(point: GeoPoint, query: NearQuery): boolean evaluateGeoBox(point: GeoPoint, box: BoundingBox): boolean evaluateGeoPolygon(point: GeoPoint, query: PolygonQuery): boolean // Framework integrations useFilter<T>(data: T[], expression: Expression<T>, options?: FilterOptions) // React useFilter<T>(data: Ref<T[]>, expression: Ref<Expression<T>>, options?: FilterOptions) // Vue filterStore<T>(data: Writable<T[]>, expression: Writable<Expression<T>>, options?: FilterOptions) // SvelteFor complete API reference, see API Reference.
Works in all modern browsers and Node.js:
- Node.js: >= 20
- Browsers: Chrome, Firefox, Safari, Edge (latest versions)
- TypeScript: >= 5.0
- Module Systems: ESM, CommonJS
We welcome contributions! Please read our Contributing Guide for details on:
- Development setup and workflow
- Testing requirements
- Coding standards
- Pull request process
Ways to Contribute:
- Report bugs or request features via GitHub Issues
- Submit pull requests with bug fixes or new features
- Improve documentation
- Share your use cases and examples
For detailed guidelines, see CONTRIBUTING.md
# Run tests pnpm test # Watch mode pnpm test:watch # Coverage report pnpm test:coverage # Type checking pnpm typecheckThe library has 270+ tests with comprehensive coverage of all features.
- ๐ Geospatial Operators: Location-based filtering with $near, $geoBox, $geoPolygon
- ๐ Distance Calculation: Spherical law of cosines for accurate distance measurement
- ๐บ๏ธ Spatial Queries: Proximity search, bounding box, and polygon containment
- ๐ Coordinate Validation: Automatic validation of lat/lng coordinates
- โก Performance Optimized: Fast algorithms for all geospatial operations
- ๐ Complete geospatial documentation and examples
- ๐ Date/Time Operators: Temporal filtering with $recent, $upcoming, $dayOfWeek, $timeOfDay, $age
- โฐ Relative Time Filtering: Filter by last/next N days/hours/minutes
- ๐๏ธ Day-of-Week Filtering: Filter by specific days (Monday-Sunday)
- ๐ Time-of-Day Filtering: Filter by hour ranges (0-23)
- ๐ Age Calculation: Calculate age in years/months/days with min/max ranges
- ๐ Weekday/Weekend Support: $isWeekday and $isWeekend operators
- ๐ Full TypeScript Support: Context-aware autocomplete for Date properties
- ๐ Zero Dependencies: Uses native Date API
- ๐ Complete datetime operators documentation and examples
- โ 90 new tests (613 total tests)
- ๐ Bug fixes and stability improvements
- ๐ Documentation updates
- ๐ง Build optimizations
- ๐จ Array OR Syntax: Intuitive array-based OR filtering (
{ city: ['Berlin', 'Paris'] }) - ๐ Visual Debugging: Built-in debug mode with expression tree visualization
- ๐ฎ Interactive Playground: New online playground for testing filters
- ๐ Debug Analytics: Performance metrics and condition evaluation tracking
- ๐จ Colorized Output: ANSI color support for debug tree visualization
- โก Performance improvements for array operations
- ๐จ Framework Integrations: React, Vue, and Svelte support
- ๐ช React Hooks:
useFilter,useFilteredState,useDebouncedFilter,usePaginatedFilter - ๐ Vue Composables: Full Composition API support with reactive refs
- ๐ฆ Svelte Stores: Reactive store-based filtering
- ๐ Comprehensive framework documentation
- โ 100% test coverage for all integrations
- ๐ TypeScript generics for type safety
- ๐ SSR compatibility (Next.js, Nuxt, SvelteKit)
- ๐จ Initial framework integration support
- ๐ช React hooks implementation
- ๐ Vue composables implementation
- ๐ฆ Svelte stores implementation
- ๐พ Enhanced Memoization: Multi-layer caching (530x faster)
- ๐ Logical Operators: $and, $or, $not for complex queries
- ๐ Regex Operators: $regex and $match for pattern matching
- ๐ Performance optimizations
- ๐จ Lazy Evaluation: filterLazy, filterFirst for efficient processing
- ๐ Generator-based filtering
- โก Early exit optimization
- โจ Added 18+ MongoDB-style operators
- โ๏ธ Configuration API with 4 options
- โ Runtime validation with Zod
- ๐ Performance optimizations
- ๐ Enhanced TypeScript support
- ๐งช 270+ tests
- ๐ Reorganized documentation into
/docsdirectory
See Migration Guide for detailed changelog and migration guide.
MIT License - see LICENSE.md for details.
Copyright (c) 2025 Miguelangel Cabrera
Author: Miguelรกngel Cabrera Repository: github.com/mcabreradev/filter
Inspired by MongoDB query syntax, SQL wildcards, and functional programming patterns.
- ๐ Complete Documentation
- ๐ฌ GitHub Discussions
- ๐ Issue Tracker
- โญ Star on GitHub
Made with โค๏ธ for the JavaScript/TypeScript community