Skip to main content
Deno 2 is finally here 🎉️
Learn more

🍱 lowlighter’s standalone libraries

This is a collection of carefully crafted TypeScript standalone libraries. These try to be minimal, unbloated and convenient.

Most of them are written with deno in mind, but as the code honors web standards they should be usable on any runtime that follows web specifications (including browsers).

Index

These libraries are published at deno.land/x/libs.

Important


Love these bytes ? Consider 💝 sponsoring me, even one-time contributions are greatly appreciated !

ℹ️ About

While this repository is open, it is not really intended to be a collaborative project. Pull requests for bug fixes or improvements are still welcome, but I may not accept any feature request if it doesn’t seem to fit the scope of this project.

Additionally, these libraries tends to follow my own coding style which:

  • use ES next syntax
  • try to be minimalistic and visually unbloated (no semicolons, infered typing, etc.)
  • use caseless convention (single whole words are preferred assuming they’re unambiguous depending on the local context)

📜 License

This work is licensed under the MIT License.

If you include a significant part of it in your own project, you should keep the license notice with it, including the mention of the additional original authors if any.

📦 Libraries

🔳 QR Code generator

🦕 Playground

This library is based on the awesome work of @nayiki. Please take a look at their articles about QR Codes:

I rewrote this because I couldn’t find a suitable implementation using EcmaScript modules. Oddly enough, most of the libraries I found also required a <canvas> to properly work (but I specifically wanted a SVG image output). Usually it’s because they were maily intended for client-side usage. A few other implementations had either some dated code or obfuscated code which I didn’t want.

Features

  • Support out-of-the-box array, console and svg outputs
  • Customizable colors and error correction level (ECL)
  • No external dependencies
  • Not canvas based (i.e. no DOM dependencies and thus cross-platform)

Usage

import { qrcode } from "./qrcode.ts"

// SVG output
const svg = qrcode("https://example.com", { output: "svg" })
console.assert(svg.includes("</svg>"))

// Console output
qrcode("https://example.com", { output: "console" })

// Array output
const array = qrcode("https://example.com")
console.assert(Array.isArray(array))

🔑 Time-based One-Time Password (TOTP)

🦕 Playground

This library is based on the well-written article of @rajat-sr on hackernoon :

Their explanation was specifically intended for NodeJS so I rewrote it to make it compatible with native Web APIs. Additionally, the URL scheme for TOTP was implemented, and combined with the QR Code generator library it can be used to make it scannable with with an authenticator app such as Microsoft Authenticator or Google Authenticator.

Features

  • Issue a new TOTP secret with metadata (issuer, account, image, etc.)
  • No external dependencies
  • Lightweight

Usage

import { otpauth, otpsecret, verify } from "./totp.ts"
import { qrcode } from "./qrcode.ts"

// Issue a new TOTP secret
const secret = otpsecret()
const url = otpauth({ issuer: "example.com", account: "alice", secret })
console.log(`Please scan the following QR Code:`)
qrcode(url.href, { output: "console" })

// Verify a TOTP token
const token = prompt("Please enter the token generated by your app:")!
console.assert(await verify({ token, secret }))

➕ Diff (patience algorithm)

🦕 Playground

This library is based on the previous work of @jonTrent which is itself based on the work of Bram Cohen.

I wrote this library because I’m working on a side project that allows edition of text content, and I wanted to implemente some kind of versioning system à la git. The thing is I didn’t want to create a binary dependency on a binary, especially since the tracked content are mostly small text that may be anywhere in the filesystem, including remote files which would have been outside boundaries of git versioning.

Note


patch() is not implemented yet because I’m currently working on another personal project that I want to finish first (it’s actually the project that required both the QR code and the TOTP libraries) but it’ll eventually be available in the future.

Features

  • Compute unified patch between two strings
  • Match diff command line output
  • No external dependencies
  • Lightweight

Usage

import { diff } from "./diff.ts"

// Print unified patch
console.log(diff("foo", "bar"))
--- a
+++ b
@@ -1 +1 @@
-foo
+bar

🔐 Symmetric encryption (using AES-GCM 256 with a PBKDF2 derived key)

🦕 Playground

This library is inspired by existing password managers, where the aim is to provide a secure way to store credentials at rest (for example in a Deno.Kv store) while being able to recover them later using a single master key.

Here, it is achieved by using AES-GCM 256-bits with PBKDF2 derived key. The latter could for instance use a username as salt and a password as seed to consistently forge back the key and decrypt the stored credentials. These are provided by the native Web Crypto APIs.

This library also adds additional features such as data integrity and original length obfuscation. It does not re-implement cryptographic primitives, it just provides a convenient way to use them.

Caution


As explained in the license:

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND

The author is not responsible for any damage that could be caused by the use of this library. It is your responsibility to use it properly and to understand the security implications of the choices you make.

Features

  • Use native Web Crypto APIs
  • Use AES-GCM 256-bits with PBKDF2 derived key to encrypt and decrypt messages
    • Encrypted messages are different each time thanks to initialization vector
    • The derived key from a given seed/password are always the same
  • Added functionalities which also introduce additional entropy:
    • With SHA-256 to guarantee integrity
    • With stored size to guarantee integrity (for messages with length < 255)
    • With padding to force length be 256 or 512 bytes and obfuscate the original size (can be disabled using 0 as value)

Usage

import { decrypt, encrypt, exportKey, importKey } from "./encryption.ts"

// Generate a key. Same seed and salt combination will always yield the same key
const key = await exportKey({ seed: "hello", salt: "world" })
console.assert(key === "664d43091e7905723fc92a4c38f58e9aeff6d822488eb07d6b11bcfc2468f48a")

// Encrypt a message
const message = "🍱 bento"
const secret = await encrypt(message, { key, length: 512 })
console.assert(secret !== message)

// Encrypted messages are different each time and can also obfuscate the original message size
console.assert(secret !== await encrypt(message, { key, length: 512 }))
console.assert(secret.length === 512)

// Decrypt a message
const decrypted = await decrypt(secret, { key })
console.assert(decrypted === message)