local-pii

On-device Model (Expo)

Run the Rampart NER model on iOS and Android with onnxruntime-react-native.

The Rampart NER model (names, addresses, IDs) is a 14.7 MB quantized ONNX model that runs on device via onnxruntime-react-native.

bun add onnxruntime-react-native expo-asset expo-file-system @local-pii/model-rampart
bun run fetch-model   # downloads the model into @local-pii/model-rampart (sha256-pinned)

Requires a dev client / prebuild — not Expo Go (onnxruntime-react-native is a native module). Run bunx expo prebuild then build a dev client.

1. Metro

Let Metro bundle the .onnx model as an asset:

// metro.config.js
const { getDefaultConfig } = require("expo/metro-config")
const { withLocalPiiMetro } = require("local-pii/metro")

module.exports = withLocalPiiMetro(getDefaultConfig(__dirname))

2. Use it

import { createAnonymizer } from "local-pii"
import { rampart } from "local-pii/expo"

const pii = createAnonymizer({
  ner: rampart({ model: require("@local-pii/model-rampart/assets/rampart-q4.onnx") }),
})

const { redactedText } = await pii.anonymize(
  "Ontem encontrei João Silva na Müllerstraße 42.",
)
// → "Ontem encontrei [GIVEN_NAME_1] [SURNAME_1] na [STREET_NAME_1] [BUILDING_NUMBER_1]."

Graceful degradation

If the model can't load, the anonymizer degrades to deterministic-only and calls onDegraded (set strict: true to throw instead):

createAnonymizer({
  ner: rampart({ model: require("@local-pii/model-rampart/assets/rampart-q4.onnx") }),
  onDegraded: (e) => console.warn("PII model unavailable, rules only:", e.message),
})

CITY, STATE and ZIP_CODE are kept (not redacted) by default — change with keep / redact.

On this page