bybence

dev

PackagesDocs
npmbybence.co

Authenticated encryption without repeating the plumbing.

SecureKit keeps the application-facing API small while covering the pieces that tend to get rebuilt around Node.js crypto: purpose separation, versioned tokens, key rotation, exact-match indexes and diagnostics.

$npm i @bybence/securekit

Documentationnpm package

securekit-demo.mjs

01

import { encrypt, decrypt } from "@bybence/securekit";

02

03

const email = "hello@example.com";

04

const token = encrypt(email, {

05

purpose: "user.email",

06

});

07

08

decrypt(token, { purpose: "user.email" });

Result

"hello@example.com"

cipher

AES-256-GCM

derivation

HKDF-SHA-256

token

sk4

runtime deps

0

What SecureKit removes from application code.

Node.js already provides the cryptographic primitive. SecureKit standardizes the repeated application code around it.

Direct Node.js crypto

01

import crypto from "node:crypto";

02

const key = Buffer.from(process.env.ENCRYPTION_KEY, "base64");

03

const iv = crypto.randomBytes(12);

04

const cipher = crypto.createCipheriv("aes-256-gcm", key, iv);

05

const encrypted = Buffer.concat([

06

cipher.update(email, "utf8"),

07

cipher.final()

08

]);

09

const tag = cipher.getAuthTag();

With SecureKit

01

import { encrypt } from "@bybence/securekit";

02

const encrypted = encrypt(email);

What happens inside encrypt().

The public API stays short, while the token format and authenticated steps remain explicit and versioned.

Serialize

Preserve supported JavaScript value types.

Derive

HKDF-SHA-256 derives purpose-separated key material.

Encrypt

AES-256-GCM uses a fresh 96-bit IV.

Bind

Purpose, context and metadata are authenticated.

Frame

Emit a versioned sk4 token for future decoding.

Output

sk4.eyJ2Ijo0LCJraWQiOiJkZWZhdWx0Iiw...

Production features stay opt-in.

Use the basic encrypt/decrypt path first. Add the extra surface only when the application has a concrete need for it.

Purpose separation

Keep user.email, billing.bank-account and other data classes cryptographically separated.

encrypt(email, { purpose: "user.email" })

Context binding

Bind ciphertext to application metadata so the token is only valid in the intended context.

context: { userId: 123 }

Blind indexes

Perform exact-match lookups without turning the ciphertext itself deterministic.

blindIndex(email, { normalize: "email" })

Key rotation

Identify old key IDs and re-encrypt values under a new current key.

needsReencrypt(token) rotate(token)

Sealed values

Attach an authenticated expiration time to application data.

seal(data, { expiresIn: "15m" })

Password hashing

Scrypt hashing and timing-safe password verification live in the same focused package.

await hashPassword(password)

Benchmark: SecureKit 0.9.0 · Apple M2 · Node.js 22.18.0 · 2026-09-25

Benchmark results against raw Node.js crypto.

Binary throughput is measured against a framed raw Node.js AES-256-GCM baseline on the same machine and runtime.

Encrypt bytes

4.49 GiB/s

223.06 µs P95

SecureKit

4,489 ops/s

measured

Raw Node.js

4,528 ops/s

baseline

Decrypt bytes

5.53 GiB/s

181.18 µs P95

SecureKit

5,535 ops/s

measured

Raw Node.js

5,571 ops/s

baseline

Blind index · email

630,160 ops/s

1.6 µs p95

Batch · 1,000 values

6.39 ms

158 batches/s · 6.84 KiB input

Reproducibility

Local reproducible benchmark, not an independent certification or security audit. Results vary by machine and runtime.

Source 65e51b9d049af6376ee0ae0baa21fe491ac709a0219e8277b9d2f9e1fa3fcdd0

Benchmark c8446e7829bbe322436c1c45ced5a7758d529a38ab5bef4cdbabadd49f5abba5

$ npx securekit doctor

✓ .env.local exists

✓ SECUREKIT_KEY exists

✓ Key is canonical 256-bit Base64

✓ .env.local is ignored by Git

✓ HKDF is available

✓ AES-256-GCM is available

✓ No problems found.

init

generate-key

doctor

inspect

guide

Setup checks from the same package.

Generate keys, inspect token metadata and validate the local environment without adding a separate diagnostics tool.

Start with the two-function path. Add the rest only when the application needs it.

The docs cover setup, purpose binding, blind indexes, lazy key rotation, sealed values and the CLI without making those features part of the minimum path.

Read the SecureKit docs