This is the list of websites I liked. Of course it’s not full yet, but I’ll continue to add links from all my bookmarks across multiple devices.
As a guy who likes notebooks, I never bothered about pens that I use. Until a few weeks ago, when I needed to quickly write down something in my Moleskine Cahier, and a pen I was using didn't want to write despite it was full of ink. I decided to buy a better pen, and bought a pack of Pilot PBS-GP-F-L pens.
And they're just great. Write fine and always, always very good.

Lazygit is a terminal client for git. Fast, easy to use, you should give it a try.
A collection of styled barcodes.




Summary: Using make can greatly simplify the maintainance of your project. If any command requires more than a few words to type, consider adding it to a Makefile.
It’s common to use package.json scripts to run commands in node-based projects, for example, npm run dev.
Recently, I came across several articles discussing the use of make and decided to give it a try.
As a result, I’ve started using make in all of my frontend projects, and I really like it. Here’s a simplified example of a Makefile for one of my work projects:
devpod: # start a devcontainer and ssh into it
devpod up .
devpod ssh lmst
dev: # run in a dev mode
npx vite
type:
npx tsc --noEmit
size:
npx vite build
npx size-limit
test:
npx tap
I think it’s better than scripts in a package.json file, because of:
- Multi-line commands.
- Comments: each line can be commented. You can describe why you run one command before another. In a
package.jsonfile, all your commands are placed on a single line - Works great with non-Node.js commands. In one of our projects, we use Selenium for integration tests, and I no longer struggling to remember how to install all dependencies and run tests
For development I use devcontainers + devpod setup, and connecting to a devcontainer is pretty much to type:
devpod up .
devpod ssh projname
Now I’m just typing make devpod, and after a few seconds I’m inside a devcontainer.
In a team, this approach will work only if each of team’s members uses a platform with a make available. On linux and Mac, it’s already included. On a Windows system you need to install make by yourself.
A small tutorial on how to start using “make”
It’s pretty easy to get started with make -just create a Makefile in the project’s root directory.
Makefile consists of targets. For example, in the make build command, build is a target.
Let’s add a type target, so we’ll be able to use make type to run typescript checks in our project:
type:
npx tsc --noEmit
Nice! To build our project, we’ll use build target. Typically, we want to check types and then build the project. For this, we can use dependencies:
type:
npx tsc --noEmit
build: type
npx vite build
Now, if we run make build, actually these commands will be executed:
npx tsc --noEmit
npx vite build
Variables
Some commands differ by just one flag, such as running typescript type checks mentioned above either single time or in watch mode:
npx tsc --noEmit
npx tsc --noEmit --watch
We can duplicate these commands:
type:
npx tsc --noEmit
type-watch:
npx tsc --noEmit --watch
Or we can use variables:
type:
npx tsc --noEmit $(WATCH)
type-watch: WATCH = --watch
type-watch: type
Here, the type-watch target just sets a WATCH variable, and re-uses type target.
A “docs” Pitfall
If you run a target and there’s a file or directory with the same name exists, make will think that this target is up to date and won’t do anything!
A classic example here is a docs target - most probably you would like to run make docs to generate the documentation, but if your documentation is placed in the docs directory, you’ll see this message:
make: 'docs' target is up to date.
To always run the specified target in such scenarios, we need to use a special .PHONY target:
.PHONY: docs
docs:
npx vitepress
Links
This is the list of movies I’ve watched and liked. I’m starting it right now (2025-03-10).
Paprika

I didn’t understand it, but it was very interesting.
Pantheon

This is the great one! I had been under impression from it for a few days after watching.
Долгая ночь

Плохие дети

The day of the Jackal (2024)

The day of the Jackal (1973)
I read the book when I was a teenager and decided to watch 1973 version before starting the 2024 series.

Longlegs
This one is strange. I should have dropped it for sure, but there was something hypnotizing that kept me watch until the end.

In this article, I’ll tell you how to create a type for all HTML elements’ events, like onClick, onDragstart, etc.
Suppose you want to create a wrapper component around some div tag. And you want to accept event handlers as component properties, like this:
const component = CreateMyComponent({
onClick: (e) => { ...},
onDragstart: () => {...},
})
For this, we need two things: types for html element events and template literal types.
HtmlElementEventMap
This is the type that maps event names to their callback types.
How I’ve found it? I searched for “typescript dom event types”, and the second link redirected me to the DOM manipulation page in the typescript documentation. There was a link to DOM type definitions, where I searched for string “click”.
interface HTMLElementEventMap extends ElementEventMap, GlobalEventHandlersEventMap {
}
The most interesting part lies in the GlobalEventHandlersEventMap type (the full source of DOM-related types):
interface GlobalEventHandlersEventMap {
"abort": UIEvent;
"animationcancel": AnimationEvent;
"animationend": AnimationEvent;
"animationiteration": AnimationEvent;
"animationstart": AnimationEvent;
"auxclick": MouseEvent;
"beforeinput": InputEvent;
"beforetoggle": Event;
"blur": FocusEvent;
"cancel": Event;
"canplay": Event;
"canplaythrough": Event;
"change": Event;
"click": MouseEvent;
"close": Event;
"compositionend": CompositionEvent;
"compositionstart": CompositionEvent;
"compositionupdate": CompositionEvent;
"contextlost": Event;
"contextmenu": MouseEvent;
"contextrestored": Event;
"copy": ClipboardEvent;
"cuechange": Event;
"cut": ClipboardEvent;
"dblclick": MouseEvent;
"drag": DragEvent;
"dragend": DragEvent;
"dragenter": DragEvent;
"dragleave": DragEvent;
"dragover": DragEvent;
"dragstart": DragEvent;
"drop": DragEvent;
"durationchange": Event;
"emptied": Event;
"ended": Event;
"error": ErrorEvent;
"focus": FocusEvent;
"focusin": FocusEvent;
"focusout": FocusEvent;
"formdata": FormDataEvent;
"gotpointercapture": PointerEvent;
"input": Event;
"invalid": Event;
"keydown": KeyboardEvent;
"keypress": KeyboardEvent;
"keyup": KeyboardEvent;
"load": Event;
"loadeddata": Event;
"loadedmetadata": Event;
"loadstart": Event;
"lostpointercapture": PointerEvent;
"mousedown": MouseEvent;
"mouseenter": MouseEvent;
"mouseleave": MouseEvent;
"mousemove": MouseEvent;
"mouseout": MouseEvent;
"mouseover": MouseEvent;
"mouseup": MouseEvent;
"paste": ClipboardEvent;
"pause": Event;
"play": Event;
"playing": Event;
"pointercancel": PointerEvent;
"pointerdown": PointerEvent;
"pointerenter": PointerEvent;
"pointerleave": PointerEvent;
"pointermove": PointerEvent;
"pointerout": PointerEvent;
"pointerover": PointerEvent;
"pointerup": PointerEvent;
"progress": ProgressEvent;
"ratechange": Event;
"reset": Event;
"resize": UIEvent;
"scroll": Event;
"scrollend": Event;
"securitypolicyviolation": SecurityPolicyViolationEvent;
"seeked": Event;
"seeking": Event;
"select": Event;
"selectionchange": Event;
"selectstart": Event;
"slotchange": Event;
"stalled": Event;
"submit": SubmitEvent;
"suspend": Event;
"timeupdate": Event;
"toggle": Event;
"touchcancel": TouchEvent;
"touchend": TouchEvent;
"touchmove": TouchEvent;
"touchstart": TouchEvent;
"transitioncancel": TransitionEvent;
"transitionend": TransitionEvent;
"transitionrun": TransitionEvent;
"transitionstart": TransitionEvent;
"volumechange": Event;
"waiting": Event;
"webkitanimationend": Event;
"webkitanimationiteration": Event;
"webkitanimationstart": Event;
"webkittransitionend": Event;
"wheel": WheelEvent;
}
Template literal types
Template literal types allow us to use string interpolation in type declarations.
For example, this is how we can create a onClick literal type:
type DomEvent = 'Click'
// type DomEventHandlerName = 'onClick'
type DomEventHandlerName = `on${DomEvent}`
Implementation
All we need now is to loop over all events and create a on type for each of them:
export type HTMLEventHandler = {
[K in keyof HTMLElementEventMap as `on${Capitalize<K>}`]? : (evt: HTMLElementEventMap[K]) => void
}
We used Capitalize helper type, which capitalizes the first character in a string.
Finally watched, very nice.
Recently I was needed to add a quick tooltip to a span element in a project with vuetify and vue2. My first try was to use vuetify’s v-tooltip, but, you know, it didn’t work after 3 minutes of copy-pasting code samples from docs.
So I just googled something like “HTML native tooltip”, and found an example of a tooltip on stackoverflow, which impressed me with its small amount of code and nice results.
Demo
The solution is to use data-attribute and attr() function:
[data-tooltip]:hover::after {
display: block;
position: absolute;
content: attr(data-tooltip);
border: 1px solid black;
background: #eee;
padding: .25em;
}
<div data-tooltip="Hello, World!">Hello, World!</div>
Often CSS-only solutions look very tricky, but this one is very good, I like it.
