pii-browser
v0.1.0
Published
Browser-first PII detection, obfuscation, and de-obfuscation with a precompiled Rust/WASM core and GLiNER integration.
Maintainers
Readme
pii-browser
Browser-first PII detection, obfuscation, and de-obfuscation with:
- a precompiled Rust/WASM core bundled in the npm package
- GLiNER-based browser inference for unstructured entity hints
- a stateless, catalog-driven API designed for AI chat handoff flows
The published npm package ships compiled artifacts only (dist/ and the prebuilt WASM bundle). The
source repository can remain private while consumers install the public package from npm.
Install
npm install pii-browserWhat it is for
Use this package when you need to:
- detect PII in the browser
- replace it with placeholders or natural surrogates before sending text to an LLM
- keep a portable replacement catalog per conversation
- de-obfuscate a later LLM response using that same catalog
Quick start
import {
createConversationCatalog,
obfuscate,
deobfuscate,
} from 'pii-browser';
const catalog = createConversationCatalog('support-thread-42');
const outbound = await obfuscate({
text: 'John Doe lives at 1234 Market St, San Francisco, CA 94103.',
catalog,
policies: {
defaultPolicy: { mode: 'placeholder' },
},
});
// send outbound.text to your AI model
const inbound = await deobfuscate({
text: outbound.text,
catalog: outbound.catalog,
policies: {
defaultPolicy: { mode: 'placeholder' },
},
});Stateful wrapper
If you want a convenience wrapper in a browser app:
import { createPiiEngine } from 'pii-browser';
const engine = await createPiiEngine({
model: 'gliner',
onProgress(progress) {
console.log(progress.message);
},
});
const result = await engine.obfuscate('Jane Johnson emailed [email protected].', {
policies: {
defaultPolicy: { mode: 'placeholder' },
},
});
const restored = engine.deobfuscate(result.text);What gets published
The npm tarball includes:
- compiled JavaScript in
dist/ - generated type declarations in
dist/ - the precompiled WASM bundle in
vendor/pii-wasm/ - this README and the package license
The package does not publish the TypeScript source tree under src/.
Model assets and caching
The GLiNER model and tokenizer assets are downloaded on first use in the browser. The runtime uses:
- the Transformers.js browser cache path
- Cache Storage for direct asset fetches when the browser supports it
That means refreshes should reuse already-downloaded assets instead of starting from a cold download every time.
Publishing
This repo is set up to publish the package with the precompiled WASM binary included.
Local publish flow
pnpm install
pnpm changeset
pnpm version:packages
pnpm release:check
pnpm release:publishCI publish flow
A Changesets workflow is included at:
.github/workflows/release.yml
On main, it will either:
- open/update a version PR
- or publish to npm when pending changesets have been merged
Required secret:
NPM_TOKEN
Versioning
Versioning is managed with Changesets.
pnpm version:packages does two things:
- runs
changeset version - synchronizes the new version into:
- the root
package.json - the Rust workspace version in
Cargo.toml
- the root
This keeps the npm package version aligned with the embedded Rust/WASM build version.
Notes
model: 'disabled'keeps only structured-rule detection and skips GLiNER loading.- User-defined replacement rules always override generated mappings.
- Placeholder mode is the safest default for LLM round-trips.
