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 things we could have done better.| Vladimir Klepov as a Coder
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 years to come? That's the question we'll try to answer today.| Vladimir Klepov as a Coder
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 feel like I learnt a lot in the process — things that would help me as a candidate in the future, and might help you land your next job.| Vladimir Klepov as a Coder
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 harder — reactive state only works inside component files, so the rest is handled by a completely separate mechanism — stores. The tutorial do...| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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 the current generation of analytics, and I had to take some action at any rate, I decided to pull the trigger and make a jump to an open-source al...| Vladimir Klepov as a Coder
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):| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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 solution. In many projects, this means bash — it can handle anything, from the trivial && to if .. fi mostrosities in separate shell scripts.| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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 life you just have to find the definitive answer to this question, and for me this time is now.| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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 called on first render — useState(() => ({ x: 0, y: 0 })) (I've explored this and other useState features in my older post). Creating functions is v...| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
React context is a cool feature, and I use it a lot for injecting configuration and making container / child component APIs (think <RadioGroup /> + <RadioButton />). 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 highlight are more relevant to library maintainers, but most apply to app development as well.| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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 state.| Vladimir Klepov as a Coder
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 expose imperative handles at all are less useful, and using them comes with a real performance cost. How so? Let me show.| Vladimir Klepov as a Coder
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 refactoring? Today, we'll discuss if having many useState(atom) is better than one single useState(object) — and, exactly, why. (Spoiler: it dep...| Vladimir Klepov as a Coder
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 file. After making some build chain updates I went to see if the transpiled version was OK. And guess what I noticed? Some babel helpers were stil...| Vladimir Klepov as a Coder
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 of using contexts, and provide several tips to help you optimize context usage. Let's go!| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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 single extra dependency on mac and linux!| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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 + sometimes, jest. This suite was taking anywhere from 10s on a starter project to 50s on a monstrous app — not fun. I set out to fix this — and I did.| Vladimir Klepov as a Coder
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 no way to tell what can be in the final array, and in which order. Something like this (yes, I'm building a CLI lint runner):| Vladimir Klepov as a Coder
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 "capture", and only then "bubble" back up (not all do — more on this in a minute). See MDN article on events for more details on this mechanism.| Vladimir Klepov as a Coder
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 module. Some smart plugins (like plugin-import) can work around that, but it's not something I'd be comfortable doing myself. Luckily, I know several tri...| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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 expectations warranted).| Vladimir Klepov as a Coder
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 there was more to the ref API than I always thought. I dug deeper, and in this post I'll share my findings with you and provide a few neat ref trick...| Vladimir Klepov as a Coder
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!| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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 for all kinds of flaky-web trouble: slow networks, clogged backends, overloaded databases — your user will never have to watch a spinner forever.| Vladimir Klepov as a Coder
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 updates — I wanted to optimize mounting. Of course, normally you'd just skip remounting and hide / show the component with CSS, but that's not fun eno...| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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:| Vladimir Klepov as a Coder
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 Thursday. But when it comes to JS, the general sentiment magically becomes "let's litter like crazy, then let the engine designers do their thing a...| Vladimir Klepov as a Coder
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.| Vladimir Klepov as a Coder
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. Great, useful ideas are hidden inside the fancy OOP terming, and I'm here to expose their niceness. We shall begin with Dependency Injection.| Vladimir Klepov as a Coder
Cheer up, today is a quick tip day. No rants, no motivation, no existentialism — just a few simple tricks you can use right now.| Vladimir Klepov as a Coder
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 good software. This is an uphill battle, people will not come in droves to cheer you up on what a great job you did, but we must stay strong and f...| Vladimir Klepov as a Coder
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 place to stay.| Vladimir Klepov as a Coder
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! Here are my top 3 tips to ease the pain.| Vladimir Klepov as a Coder
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 decided to share some tips for taming Angular (the Terrible one) and staying sane (yes you can).| Vladimir Klepov as a Coder
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!| Vladimir Klepov as a Coder
In the previous post we learnt to serialize| Vladimir Klepov as a Coder
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!| Vladimir Klepov as a Coder
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 this article, I'll share the things I love and hate about my current job.| Vladimir Klepov as a Coder