Warning
This package uses Uint8Array.prototype.toBase64() and Uint8Array.fromBase64(), which, as of November 2025, are only supported by the latest versions of browsers, Bun, Deno 2.5 or later and Node.js 25 or later. See MDN for compatibility.
A simple, secure, and fast symmetric encryption library that makes use of AES-GCM and modern platform features. It leverages the native Web Crypto API, so it works both in browsers (in secure contexts) and JavaScript runtimes.
AES-GCM is extremely fast on modern CPUs, which have dedicated hardware acceleration (AES-NI), in addition to being highly secure and even quantum-resistant (AES-256-GCM).
Use your preferred package manager.
# npm
npm i singlecrypt-text
# Yarn
yarn add singlecrypt-text
# pnpm
pnpm add singlecrypt-text
# Bun
bun add singlecrypt-textThis is a simple demonstration; production uses should utilize key rotation, among many other security measures.
There are two ways to use this library: object-oriented (recommended) or functional-oriented.
./lib/crypto.js
import SingleCryptText from "singlecrypt-text";
import { getMessageEncryptionKey } from "./lib/key";
export const cryptoMessage = new SingleCryptText(
await getMessageEncryptionKey()
);And now you can easily encrypt and decrypt messages:
// ...
import { cryptoMessage } from "./lib/crypto.js";
// ...
const message = await getMessage();
const encryptedMessage = await cryptoMessage.encrypt(message);
// ...
const decryptedMessage = await cryptoMessage.decrypt(encryptedMessage);
// ...
console.log(message === decryptedMessage); // True
// ..../lib/crypto/message.ts
import {
createSymmetricKeyFromText,
encryptTextSymmetrically,
decryptTextSymmetrically
} from "singlecrypt-text";
import { getMessageEncryptionKey } from "./lib/crypto/key";
const messageCryptoKey = await createSymmetricKeyFromText(
await getMessageEncryptionKey()
);
export async function encryptMessage(text: string) {
return await encryptTextSymmetrically(
text,
messageCryptoKey
);
}
export async function decryptMessage(ciphertext: string) {
return await decryptTextSymmetrically(
ciphertext,
messageCryptoKey
);
}Or you can reuse TextEncoder and TextDecoder instances for slightly better performance:
import {
createSymmetricKeyFromText,
encryptTextSymmetrically,
decryptTextSymmetrically
} from "singlecrypt-text";
import { getMessageEncryptionKey } from "./lib/crypto/key";
const textEncoder = new TextEncoder();
const textDecoder = new TextDecoder();
const messageCryptoKey = await createSymmetricKeyFromText(
await getMessageEncryptionKey()
);
export async function encryptMessage(text: string) {
return await encryptTextSymmetrically(
text,
messageCryptoKey,
true,
textEncoder
);
}
export async function decryptMessage(ciphertext: string) {
return await decryptTextSymmetrically(
ciphertext,
messageCryptoKey,
textDecoder
);
}And now you can easily encrypt and decrypt messages:
// ...
import { encryptMessage, decryptMessage } from "./lib/crypto/message.ts";
// ...
const message = await getMessage();
const encryptedMessage = await encryptMessage(message);
// ...
const decryptedMessage = await decryptMessage(encryptedMessage);
// ...
console.log(message === decryptedMessage); // True
// ...A class that simplifies symmetric encryption and decryption using a shared key derived from a text string.
It is also the default export.
new SingleCryptText(
key: string,
extractable: boolean = false,
textEncoder?: TextEncoder,
textDecoder?: TextDecoder
)key: The secret string to use as a key (should be high-entropy, such as a 32-byte random string).extractable(optional): Whether the generated cryptographic key is extractable. Defaults tofalse.textEncoder/textDecoder(optional): Optionally reuse your own encoder/decoder instances.
-
async encrypt(text: string, urlSafe?: boolean): Promise<string>Encrypt a string using the instance's key. Optionally specify
urlSafe(trueby default) to usebase64urlencoding. -
async decrypt(ciphertext: string): Promise<string>Decrypt a string previously encrypted by this or any compatible instance.
-
async getKey(): Promise<CryptoKey>Returns the underlying
CryptoKeyinstance.
import SingleCryptText from "singlecrypt-text";
const crypt = new SingleCryptText("my secret passphrase");
const encrypted = await crypt.encrypt("Sensitive message!");
const decrypted = await crypt.decrypt(encrypted);
console.log(decrypted); // "Sensitive message!"Functional exports for direct cryptographic operations.
createSymmetricKeyFromText(
key: string,
extractable?: boolean,
textEncoder?: TextEncoder
): Promise<CryptoKey>key: The secret string to use as a key (should be high-entropy, such as a 32-byte random string).extractable(optional): Whether the generated key is extractable. Defaults tofalse.textEncoder(optional): Optionally reuse your ownTextEncoderinstance.
Returns a Promise<CryptoKey> containing the derived symmetric key (SHA-256 hash).
Throws:
TypeErrorif there are problems with the text key.
encryptTextSymmetrically(
key: CryptoKey,
text: string,
urlSafe?: boolean,
textEncoder?: TextEncoder
): Promise<string>key: A symmetric key previously generated withcreateSymmetricKeyFromText.text: String value to encrypt.urlSafe(optional): Usebase64urlencoding iftrue(default:true). Iffalse, uses regularbase64.textEncoder(optional): Optionally reuse your ownTextEncoderinstance.
Returns a Promise<string> containing the encrypted value as a Base64 string.
Throws:
DOMExceptionif the key is invalid or if the operation failed (e.g., large payload).
decryptTextSymmetrically(
key: CryptoKey,
ciphertext: string,
textDecoder?: TextDecoder
): Promise<string>key: A symmetric key previously generated withcreateSymmetricKeyFromText.ciphertext: The string value to decrypt (encrypted with compatible methods/settings).textDecoder(optional): Optionally reuse your ownTextDecoderinstance.
Returns a Promise<string> containing the decrypted value.
Throws:
TypeError: if the second parameter is not a string.SyntaxError: if the input contains characters outside the Base64 alphabet.DOMException: if the key is invalid or if the operation failed.
Created by SSbit01.