# JavaScript and TypeScript

# Library

# Utilities

# Libraries

Name Description
Ramda (opens new window) A practical functional library
Project Fluent (opens new window) A localization system for natural-sounding translations
Anime (opens new window) A lightweight animation library

# Throttle, Debounce

function throttle(func: Function, delay: number): (...rest: any[]) => any {
    let start = performance.now();

    return function (...args: any[]): any {
        if (performance.now() - start > delay) {
            start = performance.now();

            return func.call(this, ...args);
function debounce(func: Function, delay: number): (...rest: any[]) => void {
    let timer: number;

    return function (...args: any[]) {
        timer = setTimeout(func.bind(this, ...args), delay);

# Generate an unique ID

function uid(): string {
    return Math.random()
        .substr(2, 9);

# User Interface

# Frameworks

Name Description
Vue (opens new window) The Progressive JavaScript Framework
Svelte (opens new window) Cybernetically enhanced web apps

Vue and Svelte, both, are very performant and use Single File Component that allows to have scoped styles, unlike React. The Vue ecosystem is fabulous. Use Vue3 and the Composition API.

CSS-in-JS is bullshit. Please use CSS modules (opens new window).

# Components

Mostly Framework agnostic.

Name Description
Tippy (opens new window) The complete tooltip, popover, dropdown, and menu solution

# Bundlers / Tools

Name Description
Rollup (opens new window) Rollup is a module bundler
Vite (Vue) (opens new window) Vite is an web dev build tool that serves your code via native ES Module
Snowpack (opens new window) / Pika (opens new window) The build tool for modern web apps
Parcel (opens new window) Zero configuration web application bundler
Name Description Language
esbuild (opens new window) An extremely fast JavaScript bundler and minifier Go
deno (opens new window) A secure runtime for JavaScript and TypeScript Rust

# Promises, Async and Await [TODO]

# Proxy

The Proxy object is used to define custom behavior for fundamental operations. It can be seen as the dot "." on object notation.

# Example: Web Storage API

Here is an example to transfom the Web Storage API as if it is a single Object, or a key/value DB. It's a unusual usage of Proxy to show you the power of this API. This could be improved by using JSON parse() or stringify().

export const storage = getProxy(localStorage);
export const session = getProxy(sessionStorage);

function getProxy(webStorage: Storage): object {
    return new Proxy(
        {}, // this can be an inner object to update
            set(_obj, prop, value) {
                webStorage.setItem(prop.toString(), String(value));
                return true;
            get(_obj, prop) {
            has(obj, prop) {
                return typeof Reflect.get(obj, prop) === 'string';
            deleteProperty(_obj, prop) {
                return true;

# Usage

// storage => localStorage | session => sessionStorage
import { storage, session } from "./proxy-storage.ts";

storage.foo = "bar"; // *Storage.setItem("foo", "bar");
storage.foo // => "bar" | *Storage.getItem("foo");
storage.foo ? "yes" : "no"; // => "yes" | no *Storage equivalent
delete storage.foo; // *Storage.removeItem("foo");
// test Storage support
function hasStorageSupport(webStorage: Storage): boolean {
    try {
        webStorage.setItem('__storage__', 'foo');
        return true;
    } catch (_e) {
        return false;

# Tagged Template literals [TODO]

# Web Workers

The Web Workers doesn't have access to the DOM API. The cost needed for the communication between threads may be high. Try to use the main thread for UI changes only, at least, as often as possible.

# Simple Example

let element = document.querySelector("#result");
let worker = new Worker("./worker.js");

worker.addEventListener("message", event => {
    let sum = event.data;

    element.innerHTML = sum;

worker.postMessage({a: 2, b: 3});

# worker.js

let ctx = self;

self.addEventListener("message", event => {
    let {a, b} = event.data;
    let sum = a + b;


# Libraries

# Image manipulation

As a Worker doesn't have access to the DOM, in order to transfer ImageData to a Worker, you need to decode the image in the main thread:

export function getImageData(src: string, size?: number): Promise<ImageData> {
    return new Promise((resolve, reject) => {
        let image = new Image();
        let canvas = document.createElement("canvas");
        let context = canvas.getContext("2d");

        image.addEventListener("error", reject);
        image.addEventListener("load", () => {
            let width = image.naturalWidth;
            let height = image.naturalHeight;
            let finalWidth = size || width;
            let finalHeight = size ? size / (width / height) : height;

            canvas.width = finalWidth;
            canvas.height = finalHeight;

            context.drawImage(image, 0, 0, width, height, 0, 0, finalWidth, finalHeight);

            let data = context.getImageData(0, 0, finalWidth, finalHeight);


        image.src = src;