TL;DR: A powerful, zero-dependency filtering library that brings MongoDB-style operators, SQL wildcards, and intelligent autocomplete to TypeScript arrays. Think of it as Array.filter() on steroids! 💪
The Problem
We've all been there - writing complex array filtering logic that becomes a nested mess of conditions:
const results = products.filter(p =>
p.price >= 100 &&
p.price <= 500 &&
(p.category === 'Electronics' || p.category === 'Accessories') &&
p.inStock &&
p.rating >= 4.5 &&
p.name.toLowerCase().includes('laptop')
);
This works, but it's:
- ❌ Hard to read and maintain
- ❌ Prone to errors
- ❌ Not reusable
- ❌ Difficult to compose dynamically
The Solution
Enter @mcabreradev/filter - a library that lets you write expressive, declarative filters:
import { filter } from '@mcabreradev/filter';
const results = filter(products, {
price: { $gte: 100, $lte: 500 },
category: { $in: ['Electronics', 'Accessories'] },
inStock: true,
rating: { $gte: 4.5 },
name: { $contains: 'laptop' }
});
Much cleaner, right? 🎯
🌟 Key Features
1. MongoDB-Style Operators (18 Total!)
If you've used MongoDB, you'll feel right at home:
// Comparison operators
filter(products, { price: { $gte: 100, $lt: 1000 } });
// Array operators
filter(products, { category: { $in: ['Electronics', 'Books'] } });
filter(products, { tags: { $contains: 'sale' } });
// String operators
filter(users, { email: { $endsWith: '@company.com' } });
filter(files, { name: { $regex: '^report-\\d{4}\\.pdf$' } });
// Logical operators
filter(products, {
$and: [
{ inStock: true },
{ $or: [
{ rating: { $gte: 4.5 } },
{ price: { $lt: 50 } }
]}
]
});
2. Intelligent TypeScript Autocomplete ✨
This is where it gets really cool. The library uses conditional types to suggest only valid operators for each property type:
interface Product {
name: string;
price: number;
tags: string[];
inStock: boolean;
}
filter(products, {
price: {
// TypeScript suggests: $gt, $gte, $lt, $lte, $eq, $ne
$gte: 100 // ✅
// $startsWith is NOT suggested (it's for strings!)
},
name: {
// TypeScript suggests: $startsWith, $endsWith, $contains, $regex, $eq, $ne
$startsWith: 'Laptop' // ✅
},
tags: {
// TypeScript suggests: $in, $nin, $contains, $size
$contains: 'sale' // ✅
}
});
No more guessing which operators work with which types! 🎉
3. SQL-like Wildcards
For those who prefer SQL-style pattern 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'
// Negation
filter(users, '!admin'); // Exclude admin
filter(files, '!%.pdf'); // Exclude PDFs
4. Lazy Evaluation for Performance 🚀
Process large datasets efficiently with generators:
import { filterLazy, filterFirst, filterExists } from '@mcabreradev/filter';
// Process items on-demand (500x faster for early exits!)
const filtered = filterLazy(millionRecords, { active: true });
for (const item of filtered) {
process(item);
if (shouldStop) break; // Stops immediately, doesn't process remaining items
}
// Find first N matches
const first10 = filterFirst(users, { premium: true }, 10);
// Check existence without processing all items
const hasAdmin = filterExists(users, { role: 'admin' });
Performance gains:
- 🚀 500x faster for operations that don't need all results
- 💾 100,000x less memory for large datasets
- ⚡ Early exit optimization
5. Advanced Memoization 💾
Built-in multi-layer caching for repeated queries:
const results = filter(
largeDataset,
{ age: { $gte: 18 } },
{ enableCache: true }
);
// Same query again? Returns cached result instantly!
const sameResults = filter(
largeDataset,
{ age: { $gte: 18 } },
{ enableCache: true }
);
Performance improvements:
- Simple queries: 530x faster
- Regex patterns: 605x faster
- Complex nested: 1520x faster
6. Framework Integrations 🎨
First-class support for React, Vue, and Svelte:
React:
import { useFilter, useDebouncedFilter } from '@mcabreradev/filter';
function UserList() {
const { filtered, isFiltering } = useFilter(users, { active: true });
return <div>{filtered.map(user => <User key={user.id} {...user} />)}</div>;
}
function SearchUsers() {
const [search, setSearch] = useState('');
const { filtered, isPending } = useDebouncedFilter(users, search, { delay: 300 });
return <input onChange={(e) => setSearch(e.target.value)} />;
}
Vue:
<script setup>
import { ref } from 'vue';
import { useFilter } from '@mcabreradev/filter';
const searchTerm = ref('');
const { filtered, isFiltering } = useFilter(users, searchTerm);
</script>
Svelte:
<script>
import { writable } from 'svelte/store';
import { useFilter } from '@mcabreradev/filter';
const searchTerm = writable('');
const { filtered, isFiltering } = useFilter(users, searchTerm);
</script>
📦 Installation
npm install @mcabreradev/filter
# or
yarn add @mcabreradev/filter
# or
pnpm add @mcabreradev/filter
Requirements: Node.js >= 20, TypeScript 5.0+ (optional)
🎯 Real-World Use Cases
E-commerce Product Search
const affordableElectronics = filter(products, {
category: 'Electronics',
price: { $lte: 1000 },
rating: { $gte: 4.5 },
inStock: true,
tags: { $contains: 'sale' }
});
User Management
const activeAdmins = filter(users, {
role: { $in: ['admin', 'super-admin'] },
active: true,
lastLogin: { $gte: thirtyDaysAgo },
email: { $endsWith: '@company.com' }
});
Analytics & Reporting
const recentHighValueOrders = filter(orders, {
createdAt: { $gte: thirtyDaysAgo },
amount: { $gte: 1000 },
status: { $in: ['completed', 'shipped'] },
$not: { category: 'refunded' }
});
🔥 Why Choose This Library?
✅ Zero Dependencies (only Zod for runtime validation)
✅ Type-Safe - Built with strict TypeScript
✅ Battle-Tested - 300+ tests with 100% coverage
✅ Lightweight - Small bundle size
✅ Framework Agnostic - Works everywhere
✅ 100% Backward Compatible - Safe to upgrade
✅ Excellent DX - Intelligent autocomplete
✅ Production Ready - Used in real-world applications
✅ Edge-Ready - Works in Cloudflare Workers, Vercel Edge, Deno Deploy
🎮 Try It Out
Want to see it in action? Check out the interactive playground where you can experiment with all features in real-time!
📚 Documentation
The library comes with comprehensive documentation:
- Official Website - Interactive docs and examples
- Complete Wiki - 150+ examples
- Frontend Frameworks Integrations - React, Vue, Svelte guides
- Operators Guide - All 18 operators explained
- Lazy Evaluation - Performance optimization
- Performance Benchmarks - Detailed metrics
🚀 Get Started
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
filter(users, 'Berlin'); // Alice and Charlie
// Wildcard patterns
filter(users, '%alice%'); // Alice
// Object-based filtering
filter(users, { city: 'Berlin', age: 30 }); // Alice
// MongoDB-style operators
filter(users, { age: { $gte: 25, $lt: 35 } }); // Bob and Alice
// Predicate functions
filter(users, (user) => user.age > 28); // Alice and Charlie
🌐 Links
- Website: mcabreradev-filter.vercel.app
- GitHub: github.com/mcabreradev/filter
- NPM: @mcabreradev/filter
- Playground: Try it live
🤝 Contributing
Contributions are welcome! Check out the Contributing Guide to get started.
📝 License
MIT License - Free to use in personal and commercial projects.
💬 What Do You Think?
Have you struggled with complex array filtering in your projects? Would you use a library like this? Let me know in the comments! 👇
If you found this useful, consider giving it a ⭐ on GitHub!
Made with ❤️ for the JavaScript/TypeScript community
Top comments (0)