/SDK reference

Node.js SDK /

Zero-dependency PII redaction for Node.js. 86KB package, ~1.6ms per page.

Installation

Terminal
$ npm install euredact

redact()

Main entry point. Redact PII from a text string. Returns a RedactResult with the cleaned text and a list of detections.

Signature
function redact(
  text: string,
  options?: RedactOptions
): RedactResult
ParameterTypeDefaultDescription
textstringThe input text to redact.
countriesstring[]undefinedCountry codes (e.g. ["NL", "BE"]) the document is declared to belong to. Since 0.3.2 this scores detection rather than gating it: every pattern runs whatever you declare, and a match attributed outside the set comes back with outOfScope true rather than being dropped. Declaring it is worth more in this SDK than in the Python one: 99.72% recall against 99.43% blind, where Python gives up less without it.
countryHintstring[]undefinedA prior that resolves ambiguity without narrowing scope or flagging anything out of scope — use it when you know the likely origin but do not want outOfScope semantics.
contextDocumentContextundefinedShares country evidence across the chunks of one document, so a chunk with no country signal of its own is still scored with what the rest of the document established. Pair with chunkOffset. Caching is disabled while a context is in use.
referentialIntegritybooleanfalseReplace PII with consistent labels (ENTITY_1, ENTITY_2, ...) instead of generic type labels.
detectDatesbooleanfalseInclude DOB and date-of-death detections. Off by default.
cachebooleantrueEnable result caching for faster subsequent calls.

Return value

A RedactResult object with:

ParameterTypeDefaultDescription
redactedTextstringThe text with PII replaced by labels like [NATIONAL_ID], [BANK_ACCOUNT], etc.
detectionsDetection[]Array of detected PII entities with type, value, position, and country.
sourcestringSource identifier for the redaction engine.
degradedbooleanWhether the result was produced in a degraded mode.
inferredCountries[string, number][]New in 0.3.2. The countries the engine concluded the document belongs to, each with a score in 0-1, most likely first. Populated whether or not you passed countries.
evidenceCountryEvidence[]New in 0.3.2. The individual signals behind inferredCountries, so an attribution can be audited rather than taken on faith.
detectionMode"declared" | "inferred"New in 0.3.2. "declared" when you passed countries, "inferred" otherwise (including when you passed only countryHint).

Detection

Each detection in the array contains:

ParameterTypeDefaultDescription
entityTypeEntityTypeThe type of PII detected (enum value).
startnumberStart character index in the original text.
endnumberEnd character index in the original text.
textstringThe original PII text that was detected.
sourceDetectionSourceThe detection engine that found this entity.
countrystring | nullThe country code associated with this detection, or null.
confidencestringConfidence level of the detection.
countryConfidencenumberNew in 0.3.2. How strongly the document supports the country on this detection, 0-1. Separate from confidence, which is about the match itself: a pattern can fire unambiguously while its country attribution stays a guess.
outOfScopebooleanNew in 0.3.2. True when the detection was attributed to a country outside the countries you declared. It is still redacted and still returned — filter on this field if you only want in-scope entities.

CountryEvidence

One signal supporting a country attribution. New in 0.3.2.

ParameterTypeDefaultDescription
countrystringThe ISO country code this signal points at.
sourcestringWhat produced the signal, e.g. "ibanPrefix", "phonePrefix", "tld".
logOddsnumberHow much this signal moves the score. Signals accumulate, so several weak ones can outweigh a single strong one.
span[number, number]Where in the text the signal was found. Offsets are absolute when chunkOffset is passed.

DocumentContext

New in 0.3.2. Country inference reads signals out of the text, so a document processed in chunks loses accuracy at exactly the chunks that carry no signal of their own — a page of bare reference numbers between two pages full of Dutch addresses. A DocumentContext carries the evidence across chunks so the whole document is scored as one.

Chunked document
import { DocumentContext, redact } from "euredact";

const ctx = new DocumentContext();
let offset = 0;
for (const chunk of chunks) {
  const result = redact(chunk, { context: ctx, chunkOffset: offset });
  offset += chunk.length;
  console.log(result.redactedText);
}

// Every signal the document produced, spans pointing into the full text.
console.log(ctx.evidence);

Pass chunkOffset or the evidence spans will all point into the start of the text. Caching is disabled while a context is in use, since the result depends on the document rather than on the chunk alone.

In 0.3.3 evidence became a getter, not a method — it was a method alongside size, a getter, on the same class. Read it as ctx.evidence; ctx.evidence() now throws. The Python SDK keeps ctx.evidence(), following its own idiom.

Reuse a context only across chunks of the same document. A context shared between unrelated documents mixes their countries, which cannot cause a miss — a context influences scoring only, never which spans are found — but can attribute a value to the wrong national scheme.

Example

index.ts
import { redact } from "euredact";

const result = redact(
  "Mijn BSN is 111222333 en IBAN NL91ABNA0417164300.",
  { countries: ["NL"] }
);

console.log(result.redactedText);
// "Mijn BSN is [NATIONAL_ID] en IBAN [BANK_ACCOUNT]."

console.log(result.detections);

countries takes an array. Since 0.3.3 a bare string throws a TypeError, on every entry point, in both SDKs. Before that, countries: "NL" was walked character by character into the codes "N" and "L"; neither resolves, so the call declared nothing and every detection came back with outOfScope true while the redacted text still looked correct. A pipeline filtering on that field — which these docs tell you to do — kept none of them. A wrong country code still only warns; a wrong type has no correct reading to fall back on.

redactBatch()

Process multiple texts efficiently. Loads country configs once. Same options as redact(), returns an array of RedactResult.

Signature
function redactBatch(
  texts: string[],
  options?: RedactOptions
): RedactResult[]

Example

batch.ts
import { redactBatch } from "euredact";

const results = redactBatch([
  "BSN 111222333",
  "IBAN DE89370400440532013000",
]);

results.forEach((r) => {
  console.log(r.redactedText);
});

addCustomPattern()

Register a custom regex pattern at runtime. Detected matches will be labeled with the given entity type.

Signature
function addCustomPattern(
  entityType: string,
  pattern: string
): void
ParameterTypeDefaultDescription
entityTypestringThe label to use for matches (e.g. "EMPLOYEE_ID").
patternstringA regex pattern string to match against input text.

Example

custom.ts
import { addCustomPattern, redact } from "euredact";

addCustomPattern("EMPLOYEE_ID", "EMP-\\d{6}");

const result = redact("Contact EMP-123456 for details");

console.log(result.redactedText);
// "Contact [EMPLOYEE_ID] for details"

availableCountries()

Returns an array of supported ISO country codes.

example.ts
import { availableCountries } from "euredact";

console.log(availableCountries());  // ["AT", "BE", "BG", ...]

Secret Detection

euRedact automatically detects secrets and API keys using two strategies: known-prefix patterns for popular services (AWS, GitHub, Stripe, OpenAI, Slack, JWT, SendGrid) and an entropy-based fallback that catches generic secrets near context keywords like api_key, token, and secret. Detected secrets are labeled as [SECRET].

secrets.ts
import { redact } from "euredact";

const result = redact(
  "My API key is sk-proj-abc123def456ghi789"
);

console.log(result.redactedText);
// "My API key is [SECRET]"

Performance

~1.6ms
Per page (2,000 chars)
~20,500
Records per second
300-character record
~50KB
Memory per country
86KB
Package size
0
Dependencies

Supported Countries

31 European and EEA countries with country-specific PII patterns.

ATBEBGCHCYCZDEDKEEELESFIFRHRHUIEISITLTLULVMTNLNOPLPTROSESISKUK

Entity Types

These are the 27 types this package emits, across all supported countries.

27 is the Rules Engine layer. The forthcoming AI layer adds 13 more — names, addresses, medical information and the other categories that have no fixed format for a pattern to match, plus the GDPR Article 9 special-category types. What euRedact detects lists all 40 with the layer responsible for each, so a count of 40 elsewhere on this site is not a different number from this one.

[BANK_ACCOUNT][BIC][CREDIT_CARD][PHONE][EMAIL][DOB][DATE_OF_DEATH][NATIONAL_ID][SSN][TAX_ID][PASSPORT][DRIVERS_LICENSE][LICENSE_PLATE][VIN][VAT][POSTAL_CODE][IP_ADDRESS][IPV6_ADDRESS][MAC_ADDRESS][HEALTH_INSURANCE][HEALTHCARE_PROVIDER][CHAMBER_OF_COMMERCE][IMEI][GPS_COORDINATES][UUID][SOCIAL_HANDLE][SECRET]

View source on GitHub

Browse the code, report issues, or contribute.

GitHubarrow_outward