TLDR
Zod is a tool for Typescript that allows you to validate types during runtime. It has 30K ⭐️ stars on Github, is used by 1M people, and has over 300 contributors. It also has 8.7 weekly downloads on npm. However, there's a catch. It's 150 times slower than using regular typeof checks! The benchmark code can be found at the end of the article.
Choosing convenience instead of performance
It seems to me that many modern programmers are neglecting efficiency. They built resource hungry tools & applications with unnecessary features. Back in time, slow code considered garbage people used to focused more on performance than convenience. Unfortunately, not every company has the luxury of running expensive servers or paying high costs for various software services and expensive instances. Most of companies are SMEs and can't afford huge AWS bills.
More open source projects are suffering
Consider Express.js as an example. Compared to a basic native http server it's considered slow but it's a great tool for saving coding time. Next.js is 14.5x slower than rendering with pure react https://github.com/eknkc/ssr-benchmark. Various back-end and front-end frameworks are on this list. Fortunately new solutions (at least for backend) come to the rescue with tools like llrt or Bun.
Budget infrastructure
My hope is that more importance will be given to performance in future software development. This would allow smaller businesses to run their systems using fewer resources. We've seen SaaS/PaaS companies rising prices overnight and migration is pain in the butt. Clients and managers won't cover additional costs and will ask for migration to alternative cheap services, while only a few may decide to absorb the added expenses.
Code is used for benchmark
Zod
import { z } from "zod";
const personSchema = z.object({
name: z.string(),
age: z.number(),
});
const start = performance.now();
for (let i = 0; i < 10000000; i++) {
zod();
}
const end = performance.now();
console.log(`Parsing took ${end - start} ms`);
function zod(){
return personSchema.parse({
name: "John Doe",
age: 30,
});
}
Plain
const start = performance.now();
for (let i = 0; i < 10000000; i++) {
plain()
}
const end = performance.now();
console.log(`Parsing took ${end - start} ms`);
function plain(){
const obj = {
name: "John Doe",
age: 30,
};
if (typeof obj!== "object" || obj === null) {
throw new TypeError("Expected object");
}
if (typeof obj.name!== "string") {
throw new TypeError("Expected string");
}
if (typeof obj.age!== "number") {
throw new TypeError("Expected number");
}
return obj
}