Skip to main content
Version: Next

usePrivacyFilter

Privacy Filter is a token-level model that scans text for personally identifiable information (PII) — names, emails, phone numbers, addresses, SSNs, secrets, and more — and returns the detected spans together with the entity type. Inference runs entirely on-device, so the input text never leaves the user's phone.

info

It is recommended to use models provided by us, which are available at our Hugging Face repository. You can also use constants shipped with our library.

API Reference

High Level Overview

import {
usePrivacyFilter,
PRIVACY_FILTER_OPENAI,
} from 'react-native-executorch';

const model = usePrivacyFilter({ model: PRIVACY_FILTER_OPENAI });

try {
const entities = await model.generate(
'My name is Sarah Chen and my email is [email protected].'
);
console.log(entities);
// [
// { label: 'private_person', text: 'Sarah Chen', startToken: 3, endToken: 5 },
// { label: 'private_email', text: '[email protected]', startToken: 11, endToken: 14 },
// ]
} catch (error) {
console.error(error);
}

Arguments

usePrivacyFilter takes PrivacyFilterProps that consists of:

  • model of type PrivacyFilterModelSources containing the model source, tokenizer source, and BIOES label list.
  • An optional flag preventLoad which prevents auto-loading of the model.

You need more details? Check the following resources:

Returns

usePrivacyFilter returns an object called PrivacyFilterType containing a generate function for running detection. To get more details please read: PrivacyFilterType API Reference.

Running the model

To run the model, call the generate method with the text you want to scan. The method returns a promise that resolves to an array of PiiEntity objects, each describing one detected span (label, decoded text, and inclusive startToken / exclusive endToken indices into the tokenized input).

Inputs are processed in sliding windows with 50% overlap (the window size matches the model's exported forward input shape), so there is no length limit — long documents are scanned end-to-end without truncation.

note

Token indices in returned entities are positions in the tokenizer's output (the unpadded encode() stream), not character offsets in the original string. Use the entity's decoded text field if you want to display or redact spans verbatim.

Tuning precision and recall

Both built-in models ship with neutral, validity-only Viterbi decoding by default. If you want to shift the precision/recall tradeoff, pass an optional viterbiBiases object — six floats matching the operating-point schema in OpenAI's viterbi_calibration.json. Negative backgroundToStart makes the decoder enter spans more eagerly (higher recall); positive backgroundStay keeps it in the background label more often (higher precision).

Example

import React, { useState } from 'react';
import { Button, Text, View, TextInput, ScrollView } from 'react-native';
import {
usePrivacyFilter,
PRIVACY_FILTER_OPENAI,
PiiEntity,
} from 'react-native-executorch';

export default function App() {
const model = usePrivacyFilter({ model: PRIVACY_FILTER_OPENAI });
const [text, setText] = useState(
'My name is Sarah Chen and you can reach me at [email protected].'
);
const [entities, setEntities] = useState<PiiEntity[]>([]);

const handleScan = async () => {
if (!model.isReady) {
console.error('Privacy Filter model is not loaded yet.');
return;
}
try {
const detected = await model.generate(text);
setEntities(detected);
} catch (error) {
console.error('Error during running Privacy Filter model', error);
}
};

return (
<ScrollView>
<TextInput
multiline
value={text}
onChangeText={setText}
style={{ borderWidth: 1, padding: 8, minHeight: 120 }}
/>
<Button
onPress={handleScan}
title="Detect PII"
disabled={!model.isReady}
/>
{entities.map((entity, idx) => (
<View key={idx} style={{ paddingVertical: 4 }}>
<Text>
{entity.label}:{' '}
<Text style={{ fontWeight: 'bold' }}>{entity.text}</Text>
</Text>
</View>
))}
</ScrollView>
);
}

Supported models

ModelCategoriesDescription
openai/privacy-filter8OpenAI's base PII detector. Covers names, emails, phone numbers, addresses, dates of birth, URLs, and generic secrets / API keys.
OpenMed/privacy-filter-nemotron55+Fine-tune of the base model with a much wider label space — adds medical, financial, demographic, technical, and government-document categories on top of the base 8.

Categories — The number of distinct entity types the model can emit. Both models share the same backbone (256-token windows, 128-token banded attention) and tokenizer (o200k); they differ only in the BIOES label space.