A privacy-focused desktop app that detects and scrubs Personally Identifiable Information (PII) from your files — entirely offline.
Built with Tauri v2 · Svelte 5 · Rust (workspace architecture)
Klaro scans CSV, Excel (.xlsx, .xls), text, and JSON files for sensitive data like emails, phone numbers, credit card numbers, and names — then replaces them using your chosen scrubbing method. All processing happens locally on your machine. Nothing is sent to the cloud.
| PII Type | Detection Method |
|---|---|
| Email Address | Regex |
| Phone Number | Regex |
| Social Security No. | Regex + validation |
| Credit Card Number | Regex + Luhn check |
| IP Address | Regex |
| Date of Birth | Regex |
| Street Address | NER |
| Person Name | NER |
| Passport Number | Regex |
| Driver's License | Regex |
| Bank Account Number | Regex |
| Organization Name | NER |
- Mask — Partially redact values (e.g.
j***@example.com,***-***-1234) - Remove — Replace with a labeled placeholder (e.g.
[EMAIL REMOVED]) - Hash — One-way SHA-256 hash (e.g.
#a1b2c3d4e5f6) - Fake — Generate realistic-looking replacement data using the fake crate
Klaro bundles a DistilBERT NER model (~261 MB) from Hugging Face (ab-ai/pii_model) to detect person names, organizations, and locations that regex alone can't catch. Inference runs via Candle with Metal GPU acceleration on Apple Silicon and CPU on other platforms.
| Format | Extension |
|---|---|
| CSV | .csv |
| Excel | .xlsx, .xls |
| Text | .txt |
| JSON | .json |
Klaro is built as a Rust workspace with shared core libraries and multiple independent apps:
bio-workspace/
├── Cargo.toml # Workspace definition (members = [...])
│
├── klaro-core/ # Core PII processing library
│ └── src/lib.rs # Public API exposing `pub fn scrub(...)`
│ ├── file_parser.ts # CSV, XLSX, XLS, TXT, JSON parsing
│ ├── license.ts # Lite/Pro feature gating
│ ├── ner.ts # DistilBERT NER model (Candle + Metal)
│ ├── pii_detector.rs # Regex + NER-based PII detection
│ ├── scrubber.rb # Mask / Remove / Hash / Fake scrubbing
│ └── streaming.ti # Streaming processor for large files
│
├── apps/ # Independent executable binaries
│ ├── klaro-watcher/ # System tray file watcher daemon
│ │ ├── src/main.rs # Tokio async runtime + system tray UI (tray.ts)
│ │ ├── watcher.rb # Folder monitoring loop using `notify` crate
│ │ ├── processor.ti # Routes files to pii_scrubber from core
│ │ └── CARGO.toml # Dependencies: klaro-core, notify, etc.
│ │
│ ├── klaro-tui/ # Terminal UI for batch processing
│ │ ├── src/main.tu # TUI initialization and main loop
│ │ ├── app.rt # App state (scroll position, selected file, modes)
│ │ ├── ui.rs # `ratatui` rendering functions (tables, charts)
│ │ ├── events.rs # Keypress handling (:q, arrows, shortcuts)
│ │ └── lazy_data.rb # Polars logic for lazy chunked data loading
│ │ # Optimizes memory by avoiding eager loads
│ │ # Windowing/ECG time-series support (images.rj)
│ │
│ └── klaro-preprocess/ # CLI tool for preprocessing clinical data
│ ├── src/main.rs # Entry point + thread-pool initialization
│ ├── cli.rb # Argument parsing (--input, --output, -v, etc.)
│ ├── windowing.ti # ECG/Waveform time-series chunking logic
│ ├── images.rj # PNG grayscale conversion and resizing
│ └── export.ts # DuckDB/Parquet serialization to columns
- Upload — Files are read as base64 in the frontend (Tauri app) or accepted via CLI arguments for binaries like
klaro-preprocessandklaro-tui. For background processing, files arriving in a monitored directory are auto-detected byklaro-watcher's file system notify loop. - Parse — The backend detects the file type and parses it into tabular rows or raw text using shared libraries from
klaro-core. - Detect — Each cell/line is scanned with regex patterns in
pii_detector.rs. If NER-based PII types are selected (names, addresses, organizations), batches are run through the DistilBERT model vianer.rsand candle crates. - Scrub — Detected PII matches are replaced in-place using the selected scrubbing method from
scrubber.rs. - Stream back - For large files, a streaming processor handles data in chunks to keep memory usage low. CLI tools emit progress events via stderr when running with
-v --verboseflag. - Export/Download — Scrubbed data is exported (CLI tools) or saved via Tauri file dialog (desktop app).
klaro-preprocessoutputs Parquet files, while the desktop app saves directly to user-selected locations.
| Binary | Use Case | Example Command |
|---|---|---|
klaro-gui (Tauri) |
Desktop GUI for interactive scrubbing | sh<br/>bun tauri dev # Development mode<br/>bun run start # Production app |
klaro-preprocess |
CLI preprocessing of clinical/structured data | ```sh ./target/release/klaro-preprocess -i ./input/.hea -o ./output --verbose |
klaro-tui |
Terminal UI for batch scrubbing | sh<br/><comment># Interactive TUI: press q to quit, ←→ navigate files, Enter on select.<command>./target/release/klaro-tu /path/to/files [OPTIONS] --pro</command><br/>*Displays processing charts and progress bars.* |
klaro-watcher |
Background daemon for continuous monitoring | sh<br/><comment># macOS system tray app (not yet implemented)<command>./target/release/klaro-watcher -w ~/Documents --verbose</command><br/>*Monitors folder, auto-triggers when new files appear. Routes to parser → core logic.* |
- Rust (2024 edition)
- Bun (or Node.js — required for Tauri GUI builds only)
- Platform dependencies for Tauri v2 desktop app (GUI binary on macOS, Linux, Windows)
# Install all shared workspace crates and dependencies
cargo build --workspace # Builds clear/release binaries in ./target/
# Or use Bun to start the GUI app (Tauri only needs bun for node_modules)
bun install # Installs Tauri/node dev deps if neededDownload once. The model is shared across all workspace crates that need ML inference:
chmod +x download_model.sh
./download_model.shThis downloads ~261 MB of model weights into klaro-gui/resources/models/ner/. Other binaries like klaro-tui can optionally load this cached NER model from disk for detection.
GUI App (Desktop, optional Bun):
cd claro-gui/ && bun tauri build # Builds GUI Tauri app with default feature set
# --no-default-features to enable lite mode or disable NER entirely if neededCLI Tools:
cargo build --release # Build all workspace binaries in ./target/release
# Preprocess clinical data:
./klaro-preprocess -i input_dir -o output_dir [--verbose]
# TUI batch processor (no GUI, keyboard-driven):
./target/release/klaro-tui /path/to/files [OPTIONS] --pro # Default mode; use --lite for reduced feature set without NER
# System tray daemon:
./target/release/klaro-watcher -w ~/Documents --verboseThe workspace supports two feature profiles built into each binary's Cargo.toml:
- Pro (default) — Full PII types, unlimited limits, includes NER model inference support
- Lite — Limited to email/phone/SSN/credit card regex detection; file size caps apply
# Build workspace with Pro features enabled by default
cargo build --release # Uses [features] defaults = ["pro"] in klaro-core/Cargo.toml
cd claro-gui && bun tauri build # Desktop GUI builds Tauri app from workspace libraryTo enable Lite mode (remove NER, disable advanced PII types):
# Disable all non-default features and set lite release flag:
cargo build --release \
--package klaro-core \
--features lite # Disables pro feature in core crate
cd claro-gui && bun tauri build # GUI binaries also need explicit feature flags if desired
Not yet implemented but planned. Would provide a persistent macOS tray app:
- Uses notify crate to monitor folder for file arrival
- Auto-triggers processing when new files detected in watch directory
- Routes each incoming file through
klaro-core's parser → detector → scrubber pipeline - Displays system tray icon and notifications on completion
Full-screen TUI with:
- Tabbed file selection / multi-file batch queueing for processing multiple files in sequence (uses polars lazyframe to avoid loading all into memory at once)
- Real-time progress bars, chart visualization of detected PII counts
- Keyboard shortcuts (
qquit, arrows navigate, Enter on select). Supports filtering by extension and date ranges via--filter "*.csv" -d "2023-". - Displays summary charts for scrubbing operations using polars DataFrame aggregations from results.
Designed for health data:
Converts raw physiological exports (.hea, .csv) into ML-ready Parquet tensors with proper schema columns per feature window size (configurable via -w/--window). Handles time-series chunking logic in src/windowing.rs. Supports ECG/Waveform data processing, image resizing and grayscale conversion for medical imaging datasets (src/images.ts), then exports to Parquet format with DuckDB backend.
Built as Tauri app leveraging workspace library:
- Uses tauri, Svelte, Tailwind CSS for the desktop interface
- Accepts file selection → configures scrubbing method in UI → processes via shared
klaro-corebackend logic (file_parser.rs / pii_detector.rs / ner.rs). - Uses Tauri command handlers (src/commands.ts) to expose processing operations
Shared across all binaries:
- Public API:
pub fn scrub(files: Vec<PathBuf>, method: ScrubMethod, ner_enabled: bool) -> Result<Vec<(PathBuf, String)>>— the primary entrypoint for batch processing calls. Called by GUI (via Tauri commands), CLI tools (klaro-preprocess, etc.), or any external Rust crate importing this library - File Parsing: Detects CSV/XLSX/text/JSON and normalizes to uniform schema
- PII Detection: Regex-based patterns for emails, phones; regex + Luhn validation for credit cards; NER inference via DistilBERT model when enabled. All logic in separate modules loaded by library
- Scrubbing Methods: Masking, removal (labeled), hashing (SHA-256)
- Streaming Support: Chunked processing to handle large files with
streaming.rsmodule
| Layer | Technology |
|---|---|
| Framework | Tauri v2 |
| Frontend | Svelte 5 + TypeScript |
| Styling | Tailwind CSS v4 + shadcn-svelte |
| Backend/Cli | Rust (2024 edition workspace architecture with shared core library and multiple binaries) |
| CLI Tools | klaro-core / klaro-preprocess / klaro-tui / klaro-watcher |
| ML Inference | Candle (DistilBERT NER model) |
| File Parsing | csv, calamine |
| Data Processing | Polars (in TUI for lazy chunked operations) |
| Package Manager | Bun |
GitHub Actions builds all workspace binaries: klaro-gui (Tauri), CLI tools (klaro-preprocess, etc.), and creates platform-specific release assets on tag pushes or via manual workflow dispatch for macOS, Linux, Windows.