A lightweight, WASM-powered input obfuscation library to protect sensitive data from browser extensions and client-side scraping.
- @secure-input/wasm - Rust-based ChaCha20Poly1305 encryption compiled to WASM (~10KB)
- @secure-input/core - Framework-agnostic JS library with Web Worker (~15KB)
- @secure-input/react - React hooks and components (~5KB)
Total Size: ~30KB gzipped
Before building, install:
-
Node.js 18+ and pnpm
npm install -g pnpm
-
Rust and wasm-pack
# Install Rust curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh # Add WASM target rustup target add wasm32-unknown-unknown # Install wasm-pack curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
# 1. Install dependencies
pnpm install
# 2. Build WASM package first
cd packages/wasm
pnpm build
cd ../..
# 3. Build all packages
pnpm build
# 4. Run example apps
cd packages/examples/react-demo
pnpm dev
# Open http://localhost:5173import { SecureInput } from "@secure-input/react";
function CouponForm() {
const handleSubmit = async (encrypted: string) => {
await fetch("/api/validate", {
method: "POST",
body: encrypted,
});
};
return <SecureInput onEncryptedSubmit={handleSubmit} />;
}import { SecureInput } from "@secure-input/core";
const secureInput = new SecureInput();
await secureInput.initialize();
const encrypted = await secureInput.encrypt("COUPON2024");
console.log(encrypted); // Base64 encrypted string
secureInput.destroy(); // Cleanup-
Create NPM account at https://www.npmjs.com
-
Login locally:
npm login
-
Update package.json files with your details:
authorfield in each packagerepository.urlin each package
# 1. Build all packages
pnpm build
# 2. Create changeset (describes changes)
pnpm changeset
# Select packages to publish
# Choose version bump (major/minor/patch)
# Write description
# 3. Update versions
pnpm changeset version
# 4. Install to update lockfile
pnpm install
# 5. Publish to NPM
pnpm releaseThe repo includes CI/CD workflows:
-
Push to GitHub:
git init git add . git commit -m "Initial commit" git remote add origin <your-repo-url> git push -u origin main
-
Add NPM token to GitHub:
- Generate token at https://www.npmjs.com/settings/tokens
- Add as
NPM_TOKENsecret in GitHub repo settings
-
Auto-publish: Push to
mainbranch triggers publish workflow
cd packages/examples/vanilla-demo
pnpm devcd packages/examples/react-demo
pnpm devYou'll need to decrypt on your server. Example in Node.js:
// Install: npm install @noble/ciphers
import { chacha20poly1305 } from "@noble/ciphers/chacha";
function decryptValue(encryptedBase64, key) {
const data = Buffer.from(encryptedBase64, "base64");
const nonce = data.slice(0, 12);
const ciphertext = data.slice(12);
const cipher = chacha20poly1305(key, nonce);
const plaintext = cipher.decrypt(ciphertext);
return Buffer.from(plaintext).toString("utf8");
}
// Use in API route
app.post("/api/validate", (req, res) => {
const encrypted = req.body;
const key = getKeyForUser(); // Store keys per session/user
const couponCode = decryptValue(encrypted, key);
// Validate coupon...
});Run after building:
# Check sizes
du -sh packages/*/dist
# Or use bundlephobia
npx bundlephobia@latest @secure-input/coreIssue: WASM build fails
- Ensure Rust and wasm-pack are installed
- Run
rustup update
Issue: Worker not loading in dev
- Vite handles workers automatically with
?workersuffix - Check browser console for CORS errors
Issue: Build fails with TypeScript errors
- Run
pnpm installto ensure all deps are installed - Check that all packages built in correct order (wasm → core → react)
- Customize encryption: Modify
packages/wasm/src/lib.rsfor different algorithms - Add more frameworks: Create Vue/Svelte/Angular wrappers
- Server adapters: Add
@secure-input/serverpackage for Next.js/Express helpers - Documentation site: Use VitePress or Docusaurus
- This provides obfuscation, not absolute security
- Always validate server-side with rate limiting
- Use HTTPS in production
- Rotate encryption keys periodically
- Consider using session-specific keys
Open an issue on GitHub or check the docs in each package's README.
Ready to protect your inputs! 🛡️