31615
A resourceful newsletter featuring the latest and most important news, articles, books and updates in the world of #javascript 🚀 Don't miss our Quizzes! Let's chat: @nairihar
CHALLENGE
const a = 9007199254740991n;Читать полностью…
const b = BigInt(Number.MAX_SAFE_INTEGER);
console.log(a === b);
console.log(a + 1n);
console.log(typeof a);
console.log(a === 9007199254740991);
CHALLENGE
Читать полностью…
class DatabaseError extends Error {
constructor(message, code) {
super(message);
this.name = "DatabaseError";
this.code = code;
}
}
class ConnectionError extends DatabaseError {
constructor(host) {
super(`Failed to connect to ${host}`, 503);
this.name = "ConnectionError";
this.host = host;
}
}
const err = new ConnectionError("db.server.io");
console.log([
err instanceof ConnectionError,
err instanceof DatabaseError,
err instanceof Error,
err.name,
err.code,
err.message,
].join(" | "));
CHALLENGE
const items = [Читать полностью…
{ name: "banana", price: 1.5, qty: 10 },
{ name: "apple", price: 1.5, qty: 5 },
{ name: "cherry", price: 3.0, qty: 8 },
{ name: "date", price: 2.0, qty: 8 },
];
const sorted = [...items].sort((a, b) => {
if (a.price !== b.price) return a.price - b.price;
if (a.qty !== b.qty) return b.qty - a.qty;
return a.name.localeCompare(b.name);
});
console.log(sorted.map(i => `${i.name}:${i.qty}`).join(", "));
CHALLENGE
const values = [0.1 + 0.2, NaN, Infinity, -0, 42.6789];Читать полностью…
const results = values.map((v, i) => {
if (i === 0) return Number.isInteger(v) + " | " + v.toFixed(2);
if (i === 1) return Number.isFinite(v) + " | " + Number.isNaN(v);
if (i === 2) return Number.isFinite(v) + " | " + Number.MAX_SAFE_INTEGER;
if (i === 3) return Object.is(v, -0) + " | " + (v === 0);
if (i === 4) return v.toFixed(2) + " | " + v.toPrecision(4);
});
results.forEach(r => console.log(r));
CHALLENGE
Читать полностью…
const inventory = new Map([
["sword", { quantity: 3, weight: 15 }],
["shield", { quantity: 1, weight: 25 }],
["potion", { quantity: 10, weight: 2 }],
]);
inventory.set("bow", { quantity: 2, weight: 8 });
inventory.delete("shield");
const totalWeight = [...inventory.entries()].reduce((acc, [item, { quantity, weight }]) => {
return acc + quantity * weight;
}, 0);
const heaviestItem = [...inventory.entries()].reduce((max, [item, data]) =>
data.weight > max.weight ? { name: item, ...data } : max,
{ name: "", weight: 0 }
);
console.log(inventory.size, totalWeight, heaviestItem.name);
CHALLENGE
Читать полностью…
class Vehicle {
#speed = 0;
constructor(brand) {
this.brand = brand;
}
accelerate(amount) {
this.#speed += amount;
return this;
}
getSpeed() {
return this.#speed;
}
toString() {
return `${this.brand} @ ${this.#speed}km/h`;
}
}
class Car extends Vehicle {
#gear = 1;
constructor(brand, model) {
super(brand);
this.model = model;
}
shiftUp() {
this.#gear++;
return this;
}
toString() {
return `${super.toString()} [Gear ${this.#gear}]`;
}
}
const car = new Car("Toyota", "Supra");
car.accelerate(60).accelerate(40).shiftUp().shiftUp();
console.log(car.toString());
console.log(car instanceof Car);
console.log(car instanceof Vehicle);
console.log(Object.getPrototypeOf(Car) === Vehicle);
🤟 What’s Actually New in JavaScript (And What’s Coming Next)
If you don’t read the specs or endless posts about new language features, this is a great way to catch up. Most of the features are supported in Node, like Promise.try, Set union/intersection/difference, Array.fromAsync, and using, with others soon to land, like Math.sumPrecise and Map.getOrInsert (in Node 26).
Neciu Dan
CHALLENGE
Читать полностью…
const config = {
host: "localhost",
port: 3000,
db: {
name: "mydb",
maxConnections: 10
}
};
Object.freeze(config);
config.port = 9999;
config.db.maxConnections = 99;
config.newProp = "surprise";
delete config.host;
const sealed = Object.seal({ x: 1, y: 2 });
sealed.x = 100;
sealed.z = 999;
delete sealed.y;
console.log(config.port, config.db.maxConnections, config.host);
console.log(sealed.x, sealed.y, sealed.z);
👀 Optique 1.0: Type-Safe Combinatorial CLI Parser
Build composable parsers for CLIs with type safety, type inference, and built-in shell completion support, plus config file integration and man page generation from the same definitions. v1.0 is the first stable release and Hong compares it to hongminhee/2026/optique-10-discriminated-unions-for-cli">Commander.js and explains why you'd use Optique.
Hong Minhee
🤔 aube: A New Node.js Package Manager
Yes, another one! What’s noteworthy is it comes from the developer of mise, a tool that makes managing numerous languages so much easier. aube’s selling points are raw performance and being a drop-in replacement. Its defaults are also security-focused.
Jeff Dickey
😃 Git 2.54 has been released with a couple of headline features:
• git history offers a new, easy way to edit commit messages or interactively split a commit into two.
• You can now define hooks in config files (whether in a repo, at user level, or even system level) rather than just in .git/hooks. You can also run multiple hooks for the same event in this way.
🌟 Bun v1.3.13: Smarter Testing, Streaming Installs, and Less Memory
The Bun runtime has had a great run of releases, including last week’s v1.3.12 with built-in browser automation. Now, bun test gets numerous enhancements with --isolate, --parallel, --shard and --changed options for test env isolation, parallelization, and to run only test files affected by recent changes. The runtime now uses 5% less memory, bun install gets faster, and more.
Jarred Sumner
😉 Evan You's State of Vue 2026 Talk
A month ago, Evan You (of Vue.js and VoidZero fame) gave his annual address. Less Vue-focused than usual (though Vapor Mode is “almost ready”), the talk focuses on Vite-ecosystem updates covering Vite 8, Vite+, and Void.
Evan You / Vue.js Amsterdam
😮 HyperFrames: Write HTML and JavaScript to Create Videos
An open-source framework for creating and rendering videos with HTML and JavaScript. Essentially a simpler non-React alternative to Remotion. It includes a variety of built-in blocks/components for common video effects and elements, and can also composite existing video and audio clips. GitHub repo.
HeyGen
CHALLENGE
const obj = {
name: "Nikola",
greetArrow: () => {
return `Hello, ${this?.name ?? "stranger"}!`;
},
greetRegular() {
return `Hello, ${this.name}!`;
},
greetNested() {
const inner = () => `Hi, ${this.name}!`;
return inner();
}
};
console.log(obj.greetArrow());
console.log(obj.greetRegular());
console.log(obj.greetNested());
Читать полностью…
CHALLENGE
const log = [];Читать полностью…
const handler = {
set(target, key, value) {
log.push(`set:${key}=${value}`);
target[key] = value;
return true;
},
get(target, key) {
log.push(`get:${key}`);
return target[key];
}
};
const state = new Proxy({}, handler);
state.count = 0;
state.count = state.count + 1;
state.count = state.count + 1;
console.log(log.join(" | "));
😮 html-to-text 10.0: Advanced HTML to Text Converter
Uses a variety of techniques to convert even complex HTML into plain text (but with some formatting, such as for tables). v10 brings the project up to modern standards.
KillyMXI
🤟 Node.js 26.0 (Current) Released
It's here! Complete with the Temporal API enabled by default, V8 14.6 (say hello to map ‘upsert’ methods like Map.prototype.getOrInsert() and iterator sequencing with Iterator.concat()), plus Undici 8. v26 is the ‘Current’ cutting-edge release until October when it gets promoted to LTS.
Rafael Gonzaga
CHALLENGE
const ops = {
add: (a, b) => a + b,
subtract: (a, b) => a - b,
multiply: (a, b) => a * b,
divide: (a, b) => b !== 0 ? a / b : NaN,
};
const pipeline = (...fns) => (value) => fns.reduce((acc, fn) => fn(acc), value);
const double = (x) => ops.multiply(x, 2);
const addTen = (x) => ops.add(x, 10);
const halve = (x) => ops.divide(x, 2);
const subtractThree = (x) => ops.subtract(x, 3);
const transform = pipeline(double, addTen, halve, subtractThree);
const results = [5, 0, -4].map(transform);
console.log(results);
Читать полностью…
CHALLENGE
const delay = (ms, val) => new Promise(res => setTimeout(res, ms, val));Читать полностью…
async function pipeline(...fns) {
return async (input) => {
let result = input;
for (const fn of fns) {
result = await fn(result);
}
return result;
};
}
const double = async (x) => delay(10, x * 2);
const addTen = async (x) => delay(10, x + 10);
const square = async (x) => delay(10, x ** 2);
(async () => {
const process = await pipeline(double, addTen, square);
const output = await process(3);
console.log(output);
})();
CHALLENGE
Читать полностью…
const EventEmitter = (() => {
const listeners = new WeakMap();
return class {
constructor() {
listeners.set(this, {});
}
on(event, fn) {
const map = listeners.get(this);
(map[event] ??= []).push(fn);
return this;
}
emit(event, ...args) {
const map = listeners.get(this);
(map[event] ?? []).forEach(fn => fn(...args));
return this;
}
};
})();
const bus = new EventEmitter();
const log = [];
bus
.on("data", val => log.push(`A:${val}`))
.on("data", val => log.push(`B:${val}`))
.on("done", () => log.push("done"));
bus.emit("data", 1).emit("data", 2).emit("done");
console.log(log.join(" | "));
CHALLENGE
Читать полностью…
async function fetchData(id) {
if (id < 0) throw new Error("Invalid ID");
return { id, value: id * 10 };
}
async function process() {
const results = await Promise.allSettled([
fetchData(1),
fetchData(-1),
fetchData(3),
]);
results.forEach(({ status, value, reason }) => {
if (status === "fulfilled") {
console.log(`fulfilled: ${value.id} -> ${value.value}`);
} else {
console.log(`rejected: ${reason.message}`);
}
});
}
process();
CHALLENGE
function* counter(start, end) {
for (let i = start; i <= end; i++) {
yield i;
}
}
function* pipeline() {
const first = yield* counter(1, 3);
console.log("Counter done:", first);
yield "bridge";
const second = yield* counter(7, 9);
console.log("Counter done:", second);
}
const gen = pipeline();
const results = [];
let next = gen.next();
while (!next.done) {
results.push(next.value);
next = gen.next();
}
console.log(results);
Читать полностью…
CHALLENGE
Читать полностью…
class ValidationError extends Error {
constructor(message, field) {
super(message);
this.name = "ValidationError";
this.field = field;
}
}
class NetworkError extends ValidationError {
constructor(message, field, statusCode) {
super(message, field);
this.name = "NetworkError";
this.statusCode = statusCode;
}
}
const err = new NetworkError("Not Found", "endpoint", 404);
console.log([
err instanceof NetworkError,
err instanceof ValidationError,
err instanceof Error,
err instanceof TypeError,
].join(", "));
CHALLENGE
async function* paginate(items, pageSize) {
for (let i = 0; i < items.length; i += pageSize) {
const page = items.slice(i, i + pageSize);
yield await Promise.resolve(page);
}
}
async function* transform(source, fn) {
for await (const chunk of source) {
yield fn(chunk);
}
}
async function run() {
const data = [10, 20, 30, 40, 50, 60];
const pages = paginate(data, 2);
const mapped = transform(pages, (page) => page.map((x) => x * 2));
const results = [];
for await (const page of mapped) {
results.push(page.reduce((a, b) => a + b, 0));
}
console.log(results);
}
run();
Читать полностью…
CHALLENGE
const values = [0.1 + 0.2, NaN, Infinity, -0, 42.6789];Читать полностью…
const results = values.map((v, i) => {
if (i === 0) return v.toFixed(2);
if (i === 1) return Number.isFinite(v) + " " + Number.isNaN(v);
if (i === 2) return Number.isFinite(v) + " " + isFinite(v);
if (i === 3) return Object.is(v, 0) + " " + Object.is(v, -0);
if (i === 4) return v.toPrecision(4);
});
console.log(results.join(" | "));
CHALLENGE
Читать полностью…
const partial = (fn, ...presetArgs) => {
return function partiallyApplied(...laterArgs) {
return fn(...presetArgs, ...laterArgs);
};
};
const calculateTax = (taxRate, discount, price) => {
const discounted = price - (price * discount) / 100;
return parseFloat((discounted + (discounted * taxRate) / 100).toFixed(2));
};
const withVAT = partial(calculateTax, 20);
const withVATandDiscount = partial(withVAT, 15);
console.log(withVAT(0, 100));
console.log(withVATandDiscount(200));
console.log(partial(calculateTax, 10, 5)(50));
CHALLENGE
const counter = (function () {
let count = 0;
const history = [];
return {
increment(step = 1) {
count += step;
history.push(count);
return this;
},
decrement(step = 1) {
count -= step;
history.push(count);
return this;
},
getHistory: () => history,
getCount: () => count,
};
})();
counter.increment(5).increment(3).decrement(2);
console.log(counter.getCount(), counter.getHistory().join(" -> "));
Читать полностью…
CHALLENGE
const user = {
profile: {
name: "Marcus",
score: 0,
nickname: null,
bio: undefined,
},
};
user.profile.nickname ??= "Anonymous";
user.profile.bio ??= "No bio provided";
user.profile.score ??= 100;
user.profile.rank ??= "Beginner";
const { name, score, nickname, bio, rank } = user.profile;
console.log(`${name} | ${score} | ${nickname} | ${bio} | ${rank}`);
Читать полностью…