Purgo is a zero-config, client-side log-scrubbing library that prevents Protected Health Information (PHI) from leaking into browser consoles, DevTools, and network debuggers.
- 🔒 HIPAA-Friendly: Automatically redacts PHI from logs and network requests
- 🪶 Lightweight: < 7 kB gzip
- ⚡ Fast: < 3% runtime overhead
- 🔌 Zero-Config: Works out-of-the-box with React, Next.js, Vue, and vanilla JS
- 🧩 Extensible: Add custom patterns and redaction strategies
📚 Visit the Wiki for comprehensive documentation, guides, and best practices.
npm install purgo
# or
yarn add purgo
# or
pnpm add purgo
// Just import it - that's it!
import 'purgo';
// Now all console logs and network requests will be automatically scrubbed
console.log('Patient email: patient@example.com'); // Outputs: "Patient email: ***"
import { purgo } from 'purgo';
purgo({
targets: ['console', 'fetch', 'xhr'],
patterns: ['email', 'ssn', /\b\d{7,8}-[A-Z]{2}\b/], // Built-in + custom patterns
censor: (match) => '[REDACTED]' + match.slice(-2) // Custom redaction
});
import { redact } from 'purgo';
const patientData = {
name: 'John Doe',
email: 'john.doe@example.com',
ssn: '123-45-6789'
};
const safeData = redact(patientData);
// Result: { name: 'John Doe', email: '***', ssn: '***' }
If you want just the redaction functionality without any automatic patching of global objects:
import { redact, initRedactionEngine } from 'purgo/core';
// Optional: customize the redaction engine
initRedactionEngine({
patterns: ['email', 'phone', 'ssn', /\b[A-Z]{2}-\d{6}\b/g],
censor: (match) => `[REDACTED-${match.slice(-2)}]`
});
// Explicitly redact values
const email = "patient@example.com";
console.log(redact(email)); // Outputs: "[REDACTED-om]"
// Auto-patch process.stdout
import 'purgo/node';
// Direct use with console.log or process.stdout.write
console.log('Patient email: patient@example.com'); // Outputs: "Patient email: ***"
process.stdout.write('SSN: 123-45-6789\n'); // Outputs: "SSN: ***"
For more control, you can combine the auto-patching with custom configuration:
// Use the Node.js module for auto-patching
import 'purgo/node';
// Import the core module for custom configuration
import { initRedactionEngine } from 'purgo/core';
// Configure the redaction engine with custom patterns and redaction style
initRedactionEngine({
patterns: ['email', 'ssn', /\b\d{7,8}-[A-Z]{2}\b/], // Built-in + custom patterns
censor: (match) => '[REDACTED]' + match.slice(-2) // Custom redaction style
});
// Test with various sensitive data
const email = 'test@test.com';
const ssn = '123456789';
console.log("Email: ", email); // Outputs: "Email: [REDACTED]om"
console.log("SSN: ", ssn); // Outputs: "SSN: [REDACTED]89"
// app.js
import express from 'express';
import 'purgo/node';
import { initRedactionEngine } from 'purgo/core';
// Configure Purgo with custom patterns and redaction
initRedactionEngine({
patterns: ['email', 'ssn', 'phone', /\b\d{7,8}-[A-Z]{2}\b/],
censor: (match) => '[REDACTED]' + match.slice(-2)
});
const app = express();
app.use(express.json());
// Example route that handles PHI
app.post('/api/patient', (req, res) => {
// PHI in request body will be automatically redacted in logs
console.log('Received patient data:', req.body);
// Process the data (using the original, unredacted data)
const patientId = savePatient(req.body);
// Log with PHI (will be automatically redacted)
console.log(`Created patient with email ${req.body.email}`);
res.json({ success: true, patientId });
});
// Server logs will show:
// Received patient data: { name: 'Jane Doe', email: '[REDACTED]om', ssn: '[REDACTED]21' }
// Created patient with email [REDACTED]om
Pino is a popular structured logger for Node.js that's commonly used in healthcare applications. Purgo provides a dedicated integration:
import { pinoRedactor } from 'purgo/node';
import pino from 'pino';
const logger = pino({
redact: pinoRedactor({
paths: ['req.body.ssn', 'req.body.email', 'patient.mrn']
})
});
// Logs will have PHI automatically redacted
logger.info({
req: { body: { email: 'patient@example.com' } }
});
// In your entry file (e.g., main.jsx or index.jsx)
import 'purgo';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<App />
</React.StrictMode>
);
// app/layout.tsx
import 'purgo';
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>{children}</body>
</html>
);
}
Purgo v0.1.2+ includes special handling for Next.js environments to ensure compatibility with the App Router and Server Components architecture.
// main.js
import 'purgo';
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
<script src="https://unpkg.com/purgo/dist/index.global.js"></script>
<script>
// Purgo is automatically initialized
console.log('Patient SSN: 123-45-6789'); // Outputs: "Patient SSN: ***"
</script>
Initializes Purgo with custom options.
interface PurgoOptions {
targets?: Array<'console' | 'fetch' | 'xhr'>;
patterns?: Array<RegExp | string>;
censor?: (match: string) => string;
hashMode?: boolean;
}
Note: When using ES modules, we recommend using the auto-patching import (
import 'purgo'
) or the combined approach withimport 'purgo/node'
andimport { initRedactionEngine } from 'purgo/core'
rather than the named import (import { purgo } from 'purgo'
), which may cause issues in some environments.
- targets: Array of targets to patch (default:
['console', 'fetch', 'xhr']
) - patterns: Array of built-in pattern names or custom RegExp objects (default:
['email', 'phone', 'ssn', 'mrn', 'icd10']
) - censor: Function to transform matched content (default:
() => '***'
) - hashMode: Enable SHA-256 hashing of censored tokens for correlation (default:
false
)
- email: Email addresses
- phone: Phone numbers in various formats
- ssn: Social Security Numbers
- mrn: Medical Record Numbers
- icd10: ICD-10 diagnosis codes
Redacts PHI from any value while preserving structure.
function redact<T>(value: T): T;
The core module provides just the redaction functionality without any automatic patching of global objects.
import { redact, initRedactionEngine } from 'purgo/core';
This is useful when:
- You want more control over what gets redacted
- You want to avoid patching global objects
- You're using a framework that doesn't work well with patched globals
- You need to customize the redaction behavior extensively
As of v0.1.2, all modules include full TypeScript declarations for improved developer experience.
Creates a redactor for use with Pino logger.
interface PinoRedactorOptions {
paths: string[];
additionalPatterns?: Array<RegExp | string>;
censor?: (match: string) => string;
}
Purgo is designed to be lightweight and fast:
- Bundle Size: < 7 kB gzip
- Runtime Overhead: < 3% compared to raw operations
- Redaction Speed: ≤ 40 µs to redact a 5 kB string on M1 2.8 GHz
Contributions are welcome! Please see CONTRIBUTING.md for details on how to contribute to this project.
For more detailed documentation, guides, and best practices, please visit the Purgo Wiki.
MIT License - see LICENSE for details.
A ready-to-sign Business Associate Agreement (BAA) template is available in the legal directory.