My name is Vladimir, and I'm an engineering manager of a team building a banking app. Following the success of our core banking product, we've decided to expand to other financial services. In the last four months my team has grown 4x, going from a 4-person team to 4 teams totalling 15 people. It was, frankly, a shitshow, and now I see many...
It's been almost 2 years since I moved to a team lead role, then to a full-time engineering management position after the expansion of our team. I've been a front-end developer for 7 years before that, and initially I took the "advanced individual contributor" career track before doing the management turnaround. How's it been? Bumpy, but fun. In...
Aspiring developers often ask me what's the best programming language to learn. Personally, I mostly work with JS — solid choice, but everyone and their dog learns JS these days, so it might be time to add some diversity. I'm curious — which single programming language covers the most bases for you, and gives you most career opportunities for...
It's hard to believe, but, starting mid-october 2023 I conducted 60 technical interviews and hired 10 people into our team. It's been extremely tiring: around 80 hours of active interviewing, plus writing interview reports, plus screening CVs and take-home assignments, plus onboarding new members — all while doing my normal work stuff. Still, I...
I've been working with svelte exclusively for a year now, but I still manage to shoot myself in the foot every now and then when using reactive state. Some of the confusion is due to my prior experience with React, but some points are confusing on their own. Today, I dive into svelte internals to understand what's really going on. When you mutate...
We've already learnt a lot about svelte's reactivity system — the primary way to work with state in svelte components. But not all state belongs in components — sometimes we want app-global state (think state manager), sometimes we just want to reuse logic between components. React has hooks, Vue has composables. For svelte, the problem is even...
I open-sourced banditypes — the smallest runtime validation library for TS / JS. It manages to fit all the basic functionality into an astounding 400 bytes. For reference, the popular zod and yup libraries are around 11KB, superstruct measures 1.8KB for the same set of functionality. Today, I'll tell you how I managed to pull this off. The...
I love writing, and I also love data. When starting my blog, I integrated Google Analytics — it's free, easy to set up (just drop a few tags on the page), and that's what I knew back then. I did not enjoy it being run by a big corporation, but I was too lazy to research the alternatives, and then pay for them. But when Google announced sunsetting...
Say I'm building a TODO app with two tabs: done and pending tasks. To make the app routable, I put the active tab into the ?tab query parameter, so that mytodo.io?tab=done takes me directly to the done tasks. I implement routing like this (pardon my hand-coded querystring parser): const tasks = { done: [], pending: [],};const tab =...
I've been working with TypeScript for a long long time. I think I'm not too bad at it. However, to my despair, some low-level behaviors still confuse me: Why does 0 | 1 extends 0 ? true : false evaluate to false? I'm very ashamed, but I sometimes confuse "subtype" and "supertype". Which is which? While we're at it, what are type "narrowing" and...
I’ve been to plenty of bad interviews. Sometimes, only some questions are bad, but usually it goes further than that. Bizarre questions like “what’s the difference between a number and an array” are just a symptom of deeper issues. Let’s take a step back — why are we interviewing? To hire someone — in our case, a software developer — good at...
I’ve taken part in well over a hundred tech interviews now, on both sides. Some were fun, and some were pure cringe. I’ve been asked if I have kids (supposedly, people with children won’t have time to job hop), and if “I bet my ass I cost that much”. Fun times. But today I’d like to talk about cringe tech interview question posing as valid ones....
Many modern front-end libraries and apps obsess over their bundle size. It’s a noble pursuit — an app that uses smaller libraries has less bloat, loads faster, and the users are happier. We can agree to that. Measuring the impact of a library on the app’s bundle size sounds easy, but it’s absolutely not. Understanding the nuances of library size...
Every front-end project involves some automation to build it, test it, lint it, run dev servers, measure bundle size, and what not. npm scripts are fine for one-liners, but as the workflows grow more complex — run these things in parallel, then do something else, but only if building for production — you need a more coherent orchestration...
When our React apps get slow, we usually turn to useMemo to avoid useless job on re-render. It’s a hammer that often works well, and makes it hard to shoot yourself in the foot. But useMemo is not a silver bullet — sometimes it just introduces more useless work instead of making your app faster. In this article, I explore the less conventional...
I used to teach a class on React. There’s no better way to start a hands-on course than “Let’s write a simple component!”. But time after time I hear — “Vladimir, what’s a component, anyways?”. Bah, what a question! It’s a react thingie. React apps are made of components. Why do you care at all? When you grow up you’ll see. But at some point in...
Conditional rendering is a cornerstone of any templating language. React / JSX bravely chose not to have a dedicated conditional syntax, like ng-if="condition", relying on JS boolean operators instead: condition && renders iff condition is truthy, condition ? : renders or depending on the truthiness of condition. Courageous, but not always...
I love useRef, but it lacks the lazy initializer functionality found in other hooks (useState / useReducer / useMemo). useRef({ x: 0, y: 0 }) creates an object { x: 0, y: 0 } on every render, but only uses it when mounting — it subsequent renders it's thrown away. With useState, we can replace the initial value with an initializer that's only...
So you've decided to open-source your project. Amazing! Bad news first: writing code is only the beginning. The information for library authors on the web is surprisingly fragmented, so I've decided to put together a list of things to keep in mind when open-sourcing a JS library: Decent docs, an OSS license, TypeScript definitions and a changelog...
useEffect should run after paint to prevent blocking the update. But did you know it's not really guaranteed to fire after paint? Updating state in useLayoutEffect makes every useEffect from the same render run before paint, effectively turning them into layout effects. Confusing? Let me explain. In a normal flow, react updates go like this:...
Semantic versioning, is the way to version packages in JS ecosystem. I always thought I understood semver, but that illusion disappeared once I started maintaining libraries myself. Semver has tricky edge cases where it's unclear what the new version number should be: Should you bump anything after a refactoring? Can you have a refactor-only...
React context is a cool feature, and I use it a lot for injecting configuration and making container / child component APIs (think + ). Unfortunately, out of the box Context comes with a limiting and not very convenient API. In most cases, I choose to wrap both the provider and consumer with a custom component and a hook. Some of the issues I...
Ah, ref.current. Everybody knows that I love useRef — I've built custom useMemo with it, and I've used it instead of useState to optimize re-renders. But typing ref.current over and over is just annoying. Come on, Vladimir, startX.current is just the same as this.startX in a class, I told myself a million times, but it just doesn't work. I think...
React state is the bread and butter of a react app — it's what makes your app dynamic. React state lives in useState, useReducer or in this.state of a class component, and changing it updates your app. But then there's a vast ocean of state not managed by React. This includes ref.current, object properties, and, really, anything other than react...
Like many of you, I've read Dan Abramov's excellent article, making setInterval declarative with React hooks. It's a great introduction to hook thinking and gotchas, highly recommended to any react dev. But by now the insistence on being declarative in every hook ever has gone too far, and it's starting to annoy me. Hook libraries that don't...
Lately I've converted a lot of class components to functional. One question left me curious every time — why do I feel like splitting the old class state into so many useState(atom) — one for each state key? Is there any real benefit in it? Should I just leave a single useState(whatever this.state was) to touch as little code as possible during...
IE11 is not dead yet, and our library is supposed to run there and make russian grandmas happy. As you can guess, we rely on babel's preset-env a lot. We also don't want our code to be 55% babel helpers, so we use babel's transform-runtime — it should make babel import someHelper from '@babel/runtime/some-helper' instead of inlining it into every...
useContext hook has made React Context API so pleasant to work with that many people are even suggesting that we drop external state management solutions and rely on the built-in alternative instead. This is dangerous thinking that can easily push your app's performance down the drain if you're not careful. In this article, I explore the perils...
Doing code reviews for our hook-based project, I often see fellow developers not aware of some awesome features (and nasty pitfalls) useState offers. Since it's one of my favourite hooks, I decided to help spread a word. Don't expect any huge revelations, but here're the 7 facts about useState that are essential for anyone working with hooks....
We all love keeping bundle size under control. There are many great tools that help you with that — webpack-bundle-analyzer, bundlesize, size-limit, what not. But sometimes you you're lazy, or you're stuck choosing the tool, or the project is too small to justify spending extra time. Don't worry, I'll show you a way to check bundle size without a...
Suppose you're making a cool library that sums numbers in an array. You add a new option, inital, that lets users specify an initial value for the summation: sum([1, 1, 1], { inital: 10 }) // 13 Oh no! You made a typo — of course you meant initial, not inital. What's done is done, and you're stuck with a million users relying on your inital...
Today we'll talk about updating state inside useLayoutEffect in reaction to prop changes. Will it work? Is it safe? Are there better ways to implement such state changes? TLDR: it works, but leaves you with an extra DOM update that may break stuff. As we all know, useLayoutEffect is called before the browser has painted the DOM. This might lead...
As a guy who's somewhat responsible for a large chunk of front-end development infrastructure at our company, I've spent the last couple of months woried about the performance of our pre-commit checks. We have around 50 projects on a standard react + typescript stack, and a corresponding set of pre-commit checks: eslint + stylelint + tsc +...
Building dynamic arrays in JS is often messy. It goes like this: you have a default array, and you need some items to appear based on a condition. So you add an if (condition) array.push(item). Then you need to shuffle things around and bring in an unshift or two, and maybe even a splice. Soon, your array building code is a crazy mess of ifs with...
Normally, JS event are handled while bubbling up the DOM tree, and we've all had the pleasure to catch an event from a child node on its parent. You'd even be excused for thinking that's the only way DOM events move. Many also know there's something else — events start at the document root, then go down to the affected element in a phase called...
My current obsession with statically checking JS code got me to appreciate eslint even more. Recently, I've shown you how to use no-restricted-syntax to lint almost anything. Still, like any tool, eslint has its limits — often a precise rule bends eslint too much, and is not practical to support. For example, eslint can't look into another...
The other day I was doing my normal thing trying to force import '*.css' to be the last import in a file, which ensures a predicatbale CSS order. I spent hours looking for a eslint plugin to do that, but with little luck. Without getting into too much details: The built-in sort-imports can only group by syntax (eg import { a, b } before import...
The second quarter is coming to an end. I suppose a lot of my fellow developers are struggling to meet their ambitious KPI of "20% more test coverage". Fear not — I'll show you a couple of neat tricks that will up your coverage game in no time, so that you can go on with your life (a handy bonus for meeting your goals and exceeding all...
React refs appear to be a very simple feature. You pass a special prop to a DOM component, and you can access the current DOM node for that component in your JS. This is one of those great APIs that work just the way you'd expect, so you don't even think about how, exactly, it happens. Along my descent into React internals I started noticing that...
Edit: the technique initially proposed in this post was not concurrent-mode safe. I've added a new section describing a fix to this problem. Thanks to the readers who noticed it! useCallback has always been one of my least favorite hooks: it does not provide much value over useMemo (as we learnt in my previous post on hooks), it weirdly treats...
It's no secret that react's useCallback is just sugar on top of useMemo that saves the children from having to see an arrow chain. As the docs go: useCallback((e) => onChange(id, e.target.value), [onChange, id]);// is equivalent touseMemo(() => (e) => onChange(id, e.target.value), [onChange, id]); A less known, probably useless, but very fun,...
Timeouts are one of the key building blocks to make your app stable. In short, if you send a request to an endpoint and a response does not, for whatever reason, come soon, we act as if the request failed and fall back to plan B — try again, show an error message and let the user decide what to do next, or use cached data. This is a great remedy...
The other day I was working on a React-based library of huge, reusable SVG images, and I ran into performance problems. Just kidding, I've never had a problem I'm solving here, but I've had great fun working around it. I wanted to make components producing mostly static DOM as fast to render as humanly possible. And I'm not talking just about...
For some reason, many developers disdain design. We are programmers, we are smart and rational, and we think technically. Designers are weird and artistic, they wear black sweaters and long scarves, they are no match to us. I never quite understood how you can ignore design if you do any front-end job. Knowing core design principles will help you...
The second most important React optimization technique after shouldComponentUpdate and friends is remount management. Some portions of the UI can be hidden or shown — sidebars, drop-down menus, modals and draggable widgets are all prominent examples. The basic React pattern for conditional rendering is boolean short-circuiting: {condition &&...
The reckless coding culture of JS favors producing garbage. In real life, if you're environmentally conscious (hey there, my European readers), you probably do all sorts of crazy thinks to cut down on garbage — reject plastic bags in a supermarket, recycle bottles, keep the paper garbage in a closet until the special paper-garbage truck comes on...
Do not extend components. If there is anything React community agrees upon, this is it. Use HOCs. Use state managers (and their connector HOCs). Use render props. Do not inherit. Remember, composition over inheritance! Obey your guru. Once upon a time, a developer extended his component, and a lightning stroke him. This is a mantra. I like...
With all the enthusiasm around functional design in javascript community, we've come to reject the concepts whose names remind us of object-orientation. We throw constructors, methods and classes out of the window because they seem to smell of bank cubicles, water coolers and ERP. I've been on that train, but now I'm free from the prejudice....
Cheer up, today is a quick tip day. No rants, no motivation, no existentialism — just a few simple tricks you can use right now. We'll be talking about console.log and friends for debugging javascript, mostly in the browser. If you don't use devtools debugger — try it, but I'm not here to judge you (unless you use alert). There is at least one...
My previous post, a classic rant, how-bad-software-is-these-days kind, attracted unexpected and probably even unreasonable attention. This time I'm in for something different — I'm going to preach. Behold, and open your eyes, and open your hearts, and open your minds, as I am about to tell how we should live our lives to bring about a lifetime of...
In the midst of my September job hop I headed to Kazan for the weekend. I don't know exactly why — probably because I could. I had a hotel booked via booking.com, but once I arrived there the receptionist told me it was the first time he's heard of my booking, and he told me that they had no more rooms, and he told me that I'd rather find another...
I have spent three years developing in TypeScript, but sometimes it is owerwhelming. I'm sitting there with all those little "fuck-fuck-fucks" in my head, thinking of how I'd great it would be to burn the annotations, change the extensions to .js and get out of this nighmare already. But hey, if used properly, TS makes you happy, not depressed!...
I've been developing an AngularJS application for the past year — and voila! here I am, alive and well. I'm not some crazy old fuck who thinks AngularJS is a promising new technology. Nor have I been waiting to publish this post for 3 years. It's just how things turned up for me. Since there's no shortage of AngularJS apps in the wild, I've...
Microsof Office's docx files are actually zip archives with a bunch of XMLs and all the attached media. Super useful, everyone should know it! When I tell my colleagues, friends, or students about it, they don't take me seriously the first time. So, here we go again. If you have a docx (or xlsx, or pptx) file, you can unzip it with unzip...
In the previous post we learnt to serialize and concurrecy-limit promise-based operations in js. This time we dive further and handle rate limiting. What Exactly to Rate Limit Let's get terminological matters out of the way first. Promises represent operations that last a certain amount of time, while rate limiting is applied to discrete events....
I'm sure you can chain promises with doBefore().then(() => doAfter()) and even run multiple promises in parallel using Promise.any. However, chaining an unknown count of homogenous promises is trickier. Let me teach you to serialze promises like a pro! Suppose we want a list of all the cafes in a mid-sized european country.However, the API only...