react-native-quick-filter is a standard React Native library built with
react-native-builder-bob.
It ships CommonJS + ESM + TypeScript types, and exposes its source via the
react-native field so Metro transforms it for the consumer's RN version.
Pick the source that fits your setup, then install the peer dependencies.
npm install react-native-quick-filter
npx expo install react-native-reanimated react-native-gesture-handler react-native-safe-area-contextIn the library directory:
npm run build # or rely on the prepack/prepare script
npm pack # → react-native-quick-filter-x.y.z.tgzIn the consuming app:
npm install /absolute/path/to/react-native-quick-filter-x.y.z.tgz
npx expo install react-native-reanimated react-native-gesture-handler react-native-safe-area-contextA tarball install is a real copy in node_modules, so Metro resolves it normally.
npm install github:<user>/<repo>The package's prepare script runs bob build on install, so the prebuilt
output is generated automatically.
Note: the
example/app in this repo uses a tarball install on purpose — it lives inside the library package, which breaks Metro's source/symlink resolution ("Failed to get SHA-1"). A separate consumer project does not hit this — a normalnode_modulesinstall just works.
| Package | Range | Why |
|---|---|---|
react |
>=18 |
— |
react-native |
>=0.74 |
— |
react-native-reanimated |
>=3.6 (v3/v4) |
dropdown reveal + side-panel slide/swipe |
react-native-gesture-handler |
>=2.14 |
swipe-to-close on the side panel |
react-native-safe-area-context |
>=4.8 |
safe-area insets for the panel/sheet |
These are peer dependencies — the consumer installs them once, and a single copy is shared (no duplicate React/Reanimated).
Wrap your app root once and add the Reanimated Babel plugin.
// App.tsx
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { SafeAreaProvider } from 'react-native-safe-area-context';
export default function App() {
return (
<GestureHandlerRootView style={{ flex: 1 }}>
<SafeAreaProvider>{/* your app */}</SafeAreaProvider>
</GestureHandlerRootView>
);
}// babel.config.js (bare RN). Reanimated plugin MUST be last.
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: ['react-native-reanimated/plugin'], // v4: 'react-native-worklets/plugin'
};With Expo, babel-preset-expo adds the Reanimated/worklets plugin automatically.
See USAGE.md for the full guide and API.md for the reference. Minimal:
import { FilterProvider, QuickFilterBar, FilterSidePanel } from 'react-native-quick-filter';
<FilterProvider facets={facets} chips={chips} onSelectionChange={setSelection}>
<QuickFilterBar />
<FilterSidePanel variant="masterDetail" side="left" />
</FilterProvider>Types ship with the package (types → lib/typescript/src/index.d.ts). All
public types are exported from the package root, e.g.:
import type { Facet, ChipSpec, Selection, QuickFilterTheme } from 'react-native-quick-filter';npm run typecheck && npm test && npm run buildall green.- Bump
versioninpackage.json. npm publish(theprepare/prepackscript buildslib/;filesshipssrc+lib).