Local PII detection and anonymization for text.
Website · Issues · npm · PyPI · Discord
stella anonymize is an open-source, local-first PII redaction toolkit for legal and regulated workflows. Detection and replacement are implemented in a shared Rust core, with bindings for Node.js, Python, and browsers. The default pipeline is deterministic and makes no model or remote-service calls. Coverage varies by language, entity type, and document structure.
No detector catches everything. Reversible placeholder replacement is pseudonymization, and its maps contain original PII; do not log or treat them as anonymous output. The default pipeline targets personal identifiers, not passwords, authentication tokens, API keys, or private cryptographic material. IP addresses, MAC addresses, and URLs require explicit opt-in capabilities.
Contributing to the project is welcome.
npm install @stll/anonymizeRequires Node.js 20 or newer or Bun 1.4 or newer. Prebuilt native binaries ship
for macOS (arm64, x64), glibc-based Linux (arm64, x64), and Windows
(x64). Alpine Linux and other musl-based systems are not supported.
import{createPipeline,deanonymise}from"@stll/anonymize";constpipeline=awaitcreatePipeline({language: "en"});const{ redaction }=pipeline.redactText("Contact Alice Smith at alice@example.com.",);console.log(redaction.redactedText);// Contact [PERSON_1] at [EMAIL_ADDRESS_1].constoriginal=deanonymise(redaction.redactedText,redaction.redactionMap);console.log(original);// Contact Alice Smith at alice@example.com.Create the pipeline once and reuse it. Select one language, an exact combination
such as { language: ["cs", "en"] }, or { language: "all" }. Supported codes
are cs, de, en, es, fr, hu, it, lv, pl, pt-br, ro, sk,
and sv. The factory uses a bundled prepared artifact when one matches and
otherwise prepares the exact requested scope on first use. The
Node package guide covers sessions, custom
detections, operators, diagnostics, and prepared packages; the
capability manifest is the exact list
of public runtime surfaces and entity types.
npm install @stll/anonymize-wasmimport{createPipeline}from"@stll/anonymize-wasm";constpipeline=awaitcreatePipeline({language: "en"});const{ redaction }=pipeline.redactText("A contract signed by Alice Smith.");The browser build is single-threaded and works without cross-origin isolation,
SharedArrayBuffer, or a worker. Vite applications can use the package helper
to emit the WebAssembly module and prepared data. See the
browser guide.
uv add stella-anonymize-core
# or: pip install stella-anonymize-coreimportstella_anonymizeasanonymizepipeline=anonymize.create_pipeline(language="en", warmup="lazy-regex")
result=pipeline.redact_text(
"Contact Alice Smith at alice@example.com."
)
print(result.redaction.redacted_text)Prebuilt Python 3.11+ wheels target manylinux glibc x64/aarch64, macOS x64/arm64, and Windows x64. The Python guide covers sessions, encrypted archives, caller detections, DOCX, and PDF APIs.
echo"Contact Alice Smith at alice@example.com"| npx @stll/anonymize-cli
# Contact [PERSON_1] at [EMAIL_ADDRESS_1]The anonymize command reads stdin, files, or directory trees. It also supports
reversible keys and DOCX/PDF workflows:
npx @stll/anonymize-cli -k contract.key.json -o contract.anon.txt contract.txt
npx @stll/anonymize-cli -d contract.key.json contract.anon.txtRaw --key export is Linux-only and fails closed on other platforms because
the CLI cannot verify owner-only filesystem ACLs.
See the CLI reference for batch processing, selective restoration, document commands, JSON output, and exit codes.
@stll/anonymize-mcp exposes path-only tools over stdio. Tool arguments contain
filesystem paths rather than document text, and results contain aggregate
status rather than document contents or plaintext mappings.
{
"mcpServers": {
"stella-anonymize": {
"command": "npx",
"args": [
"-y",
"@stll/anonymize-mcp",
"--root",
"/absolute/path/to/workspace"
]
}
}
}The server requires Node.js 20+. It supports text, DOCX, PDF, and provider-neutral external-detection sidecars for text. Encrypted durable sessions are optional and currently limited to macOS and Linux. PDF tools need local Poppler and Tesseract installations; their executable paths can be set at server startup. Read the MCP guide before enabling durable sessions or document tools; it defines path, permission, key, archive, and failure boundaries.
DOCX extraction, anonymization, and restoration are available in Node.js and
Python, and through the CLI and local MCP server. The adapters preserve the
supported Word structures and return a coverage inventory for known content
outside the rewrite surface. The default require-full policy fails closed on
coverage gaps; partial rewrites require explicit opt-in.
The DOCX never stores the plaintext redaction mapping. Reversible workflows use
an application-owned session and, when persisted, an encrypted session archive.
Signed documents, tracked revisions, external relationship targets, and other
package features have explicit restrictions. See
@stll/anonymize-docx for the complete
coverage contract.
PDF inspection is available in Node.js, Python, and WASM. Node.js and Python both expose the destructive raster contract, which requires complete rendered page pixels, OCR text, and glyph geometry. The Node.js package can produce those observations with separately installed Poppler and Tesseract; the CLI and MCP server use that adapter. Python callers must supply observations and pixels from their own renderer/OCR boundary.
The output is a new image-only PDF. Source PDF objects are not copied and black
rectangles are not layered over recoverable content. This removes
searchability, accessibility, links, forms, signatures, metadata, attachments,
and other interactive features. Verification proves the fresh output structure
and requested pixel rewrite; it cannot prove perfect OCR or PII detection
recall. The certificate therefore never claims that the output is PII-free.
See @stll/anonymize-pdf for the inspection,
rendering, OCR, resource-limit, and verification contracts.
| Package | Purpose |
|---|---|
@stll/anonymize | Node.js SDK and native runtime |
stella-anonymize-core | Python bindings |
@stll/anonymize-wasm | Browser/WASM runtime |
@stll/anonymize-cli | Command-line text, DOCX, and PDF workflows |
@stll/anonymize-mcp | Path-only local MCP server |
@stll/anonymize-docx | Structure-aware DOCX adapter |
@stll/anonymize-pdf | PDF inspection and destructive raster anonymization |
@stll/anonymize-data | Published dictionaries and detector configuration |
crates/anonymize-core | Shared Rust core |
crates/document-rules-core | Structured document rule engine |
Platform-specific Node.js binary packages are installed automatically as
optional dependencies of @stll/anonymize. Node.js and Bun use the same native
binding; Bun 1.4 or newer is required. A clean macOS arm64 npm install from the
packed artifacts uses about 80 MiB on disk; CI caps the packed SDK, data
package, and every native sidecar combination at 85 MiB. Install
@stll/anonymize-wasm separately only when you need the browser runtime.
The deterministic pipeline is evaluated against publicly available tools on TAB-ECHR, RedactionBench, MEDDOCAN, MultiGraSCCo, and German Legal Entity Recognition. Tracks use different task semantics, and synthetic scores are not necessarily representative or directly comparable. Read the methodology, browse the aggregate results, or follow the reproduction guide.
bun install --frozen-lockfile
bun run build
bun run lint
bun run format:check
bun run typecheck
bun run test
bun run check:versionRead the contributor guide for prerequisites, focused checks, architecture pointers, changesets, and the sensitive-fixture policy. A CLA check runs on pull requests.
Apache-2.0. See LICENSE.
