Bytes
Quick Bytes - Random info that’s too short for a full post will be shared here.
-
npm Dependencies
- last updated: Apr 02, 2026
I always wondered why sometimes package-lock.json changes? How package.json and package-lock.json are connected. I messed around the behavior to have a understanding as follows:
For example:
On package.json
"dependencies": { "chalk": "~5.6.0" }On running
npm install, it creates an entry in package-lock.json as follows:"node_modules/chalk": { "version": "5.6.2", // locked version by npm based on package.json's intent "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", "license": "MIT", "engines": { "node": "^12.17.0 || ^14.13 || >=16.0.0" }, "funding": { "url": "https://github.com/chalk/chalk?sponsor=1" } }How the version on package-lock.json was pinned as “5.6.2” while package.json has “~5.6.0”?
It has to do with patch (~) version on the package.json. At first,
npm installchecks if there is already a package-lock.json entry for this package.- If there is not, it checks the registry for the latest version in the npm registry that satifies the condition x >= 5.6.0 and x < 5.7.0.
- If there is, (ie: getting a updated branch with latest package-lock.json), then it checks the locked version (package-lock.json) still satisfies range in package.json.
If someone manually edited package.json to 5.7.0 without updating lock file, then locked 5.6.2 no longer satisfies the new range, so npm resolves from the registry and updates the lock file. If you want npm to throw error instead of automatic update of package-lock.json then use
npm ci. It shows out of sync error.npm error `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing. npm error npm error Invalid: lock file's [email protected] does not satisfy [email protected].0What are the similar ways of versioning?
On package.json
"dependencies": { "chalk": "^5.6.0" }- semver (^) version on the package.json. At first,
npm installchecks if there is a package-lock.json entry for this package. If there is not, it checks for the latest version of the chalk in the npm registry that satifies x >= 5.6.0 AND x < 6.0.0.
What is meant by pinned version?
- mentioning the version without semver (^) or patch (~), as in exact version. This results in package-lock.json having the same version as of package.json
"dependencies": { "chalk": "5.6.0" }TLDR; package.json is more of intent, package-lock.json does the locking of the version based on the package.json’s intent and registry, package-lock makes sure the team gets the same versions.
-
Structure of node modules
- last updated: Apr 02, 2026
when we do
npm install, npm defaults to hoisted as installation strategy.[--install-strategy <hoisted|nested|shallow|linked>] [--legacy-bundling]There are other strategies as well. As follows:
hoisted
that means, when you do, let’s say
npm install express. The dependencies of the express as installed in the node_modules as follows:node_modules/ express/ ← you installed this ✓ body-parser/ ← express's dep, hoisted, you never asked for this accepts/ ← express's dep, hoisted, you never asked for thisNow on the code, you can access body-parser like:
import bodyParser from 'body-parser' // Works ✓This above is called phantom dependency, since it is added by express and can be accessed in the code even though it is not installed by the user, rather it is by express. We can access
body-parserbecause of the hoisted structure of the node_modules where packages are aligned as siblings to each other.If by chance, if express removes the dependency of the body-parser, then it results in error if it is used in the code.
nested
node_modules/ express/ node_modules/ body-parser/ ← buried inside express node_modules/ bytes/ raw-body/Now on the code, you cannot access body-parser like:
import bodyParser from 'body-parser' // FAILS xsince, it is nested and nodejs cannot able to access the import file.
shallow
node_modules/ express/ node_modules/ body-parser/ ← buried inside express bytes/ raw-body/import bodyParser from 'body-parser' // FAILS xsince, it is nested inside express nd nodejs cannot able to access the import file.
linked
This is more of experimental installation as of April 2026.
node_modules/ .store/ [email protected]/ [email protected]/ [email protected]/ express/ ← body parser, bytes, raw-body are all symlinkedimport bodyParser from 'body-parser' // FAILS OFC xStrategy Top level Inside Phantom Deps Disk hoistedeverything deduped nothing possible efficient (deduped) shallowonly your direct deps everything else as siblings (2 levels deep) blocked moderate nestedonly your direct deps each package owns its deps recursively blocked duplicates linkedsymlinks to .store actual code in .store blocked efficient (symlinks) -
Debugging trace
- last updated: Jul 09, 2025
In javascript,
console.traceis underrated debugging tool that helps to trace the caller function.console.traceprints out the stacktrace/call stack of the function call that will help to trace out the calling function.For example: If there is a helper function that is used in several places in the complex codebase, using console.trace on the function helps to trace out the caller function when debugging.
function sanitizeHtml() { console.trace("sanitize html"); } sanitizeHtml(); // line 5 // ... sanitizeHtml(); // line 7 // ... sanitizeHtml(); // line 9 // ... sanitizeHtml(); // line 11VM1567:2 sanitize html sanitizeHtml @ VM1567:2 (anonymous) @ VM1567:5 # line 5 VM1567:2 sanitize html sanitizeHtml @ VM1567:2 (anonymous) @ VM1567:7 # line 7 VM1567:2 sanitize html sanitizeHtml @ VM1567:2 (anonymous) @ VM1567:9 # line 9 VM1567:2 sanitize html sanitizeHtml @ VM1567:2 (anonymous) @ VM1567:11 # line 11 -
Ring Buffer out in the wild
- last updated: Nov 09, 2024
Ring Buffer/Circular Queue/Circular Buffer is a data structure for effectively managing queueing for low latency/time critical tasks, overwriting the old value when the queue is full and wrapping around without needing for dynamic size allowing continuous flow of data.
A more advanced version of the ring buffer is all over the place. A few examples could be:
- Device Drivers use it as a transport between software and hardware components
- io_uring (used by linux kernel for async I/O) uses two ring buffers — submission and completion queue to manage/signal I/O requests
- Real-time stream and media processing — managing media on the buffer to be processed
At a lower level, locking and unlocking resources is expensive, which results in delays for performance-critical applications. To avoid this, a ring buffer CAN BE implemented as a lock-free data structure without needing to use mutex, semaphores.
Lock-free data structures are thread-safe for concurrent usage without having to use mutual exclusion mechanisms like semaphores or locks.
Concurrency Handling
- For a Single Producer Single Consumer (SPSC) setup, there is a less chance of data corruption since it’s single producer and consumer. Although atomic operations can be designed to ensure correctness.
- For Multiple Producers Multiple Consumers (MPMC), additional techniques needs to be employed to combat data races since it is accessed by multiple threads. Atomic Operations, Memory Barrier or other techniques can be used.
There are different lock-free techniques available to ensure correctness and avoid corruption without explicit locking. The
io_uringimplementation uses memory ordering and barriers to get around without locking the shared memory.A ring buffer in the shared memory enables inter-process communication (IPC) among different processes. It can act as a transporting mechanism between threads or user-kernel space.
Building Data Pipeline on top of Ring Buffer could result in low latency, high performance message queue.
io_uring how websockets costs us 1m on our aws bill lock-free programming
-
Collation in Database
- last updated: Oct 13, 2024
Collation in Database is the set of rules to govern how characters are searched, compared and sorted in the database. It includes case sensitivity, accent-sensitivity and storing multi-lingual, emojis, special characters. It is mostly applicable for string datatypes (TEXT, VARCHAR) than others.
Why this is important? because every database treats the characters in a unique way.
Like,
- MySQL don’t support case sensitive search out of box (can be configured to do so).
- Postgres, SQLite includes it out of box.
Databases allows us to specify collation on the time of
- creation of the db or table
- specify per query, per column basis.
For example:
In MySQL, if you want to perform search by case sensitive,
SELECT * FROM names WHERE username = "TesT"; // returns "test", "Test", "tESt"The default character encoding for MySQL is
utf8mb4_general_ci(MySQL 5.7) orutf8mb4_0900_ai_ci(MySQL 8.0)where,
utf8mb- full unicode support in which it occupied 4bytes. (Note:utf8is different fromutf8mb4,utf8lacks support for all unicode characters. it is not longer recommeded)ci- refers to case insensitiveai- accent insensitive
To make our query aware, we can set collation to
utf8mb4_unicode_csorutf8mb4_binor another case-sensitive collation.where,
cs- case sensitivebin- binary (compares byte by byte, no other rules)
To perform query aware case sensitive search:
SELECT * FROM names WHERE username COLLATE utf8mb4_bin = "TesT"; SELECT * FROM names WHERE username COLLATE utf8mb4_unicode_cs = "TesT";Collation plays a important role in dealing with multilingual databases effectively for making search, sorting operations consistent with lingustic rules. It is mostly decided at the time of initializing the database.
-
fragments and http
- last updated: Sep 15, 2024
#Fragments x http x SEO x OG Images
Recently i’ve learned fragments are not sent to backend server nor parsed by social media crawlers (for seo/og image) in a hard way…
In this site /bytes url now looks like /bytes/communication-protocols.
In the tried and reverted back version, i had the url look like /bytes#communication-protocols where the OG image is being replaced for every section id.
<h2 id="communication-protocols"> <a href="#communication-protocols">test</a> </h2>guess what.. social media (like twitter card, linkedin) and SEO crawlers don’t wait for the script (javascript that updates the OG Image url based on #fragments). Search engine doesn’t crawl the page based on fragments either, thus no indexing for SEO.
if you make request from
http://example.com/test#testto the backend, the request doesn’t include the fragments. This behaviour is designed by http 1.1 spec even from the starting spec where request uri should not include fragments due to security considerations.It is meant for client side navigation only, not for server side (including crawling servers).
-
iOS mobile fallback
- last updated: Sep 15, 2024
To add fallback for styles in iOS devices - mobile
@supports (-webkit-overflow-scrolling: touch) { /* css classes/selectors */ }For example:
background-attachment: fixeddon’t work in safari mobile, add fallback for mobile iOS like@supports (-webkit-overflow-scrolling: touch) { body { /*switch to scroll which is default - iOS mobile*/ background-attachment: scroll; } } -
communication-protocols
- last updated: Sep 09, 2024
Listed down the number of ways to transmit/exchange data between server and browser, we might use:
- traditional way (http request/response)
- chunked-response (streams data)
- SSE (streams - text only, base64)
- Web Sockets (streams)
- grpc web (needs proxy)
- Web Transport (alternative to web sockets BUT major browser support is lacking - as of 2024)
- WebRTC (to send audio/video/text-blob) - designed for p2p but can be extended to client-to-server by treating server as its peer connection
send/recv data between browser to browser itself (new tab/window/browser/remote browser)
- Broadcast Channel
- Webrtc Data Channel (text/blob), Webrtc Media stream (audio/video/screen sharing) - p2p connection
- MessageChannel (iframe to main, main thread to workers, tabs, window and vice versa)
- PostMessage (iframe to main, main thread to workers, tabs, window and vice versa)
-
types of concurrency
- last updated: Aug 20, 2024
There are two types of concurrency in general.
- co-operative
- non-co-operative
co-operative
Co-operative since the functions decides when they willingly to pause by the using “await” and execute further instead of executing at some arbitarty point (ie: flow would be disturbed if it executes next lines of the code which depends on the result of the network call arbitrarily instead of waiting on the network call)
- more like “concurrency on controlled manner”
- explicit yielding since we are explicitly using await keyword to pause
Non co-operative
There’s non co-operative concurrency where context switch happens arbitrary implicit yielding instead of explicitly yielding to execute (usage of await keyword means explicit yielding).
implicit yielding would be os threads/go routines where runtime scheduler handles the yielding internally without needing to
awaitexplicitly to control the concurrency ..- more like “concurrency on unhinged manner”
- implicit yielding since it depends on how os system thread scheduling/go-routine handles it.
Related Bytes:concurrency-sketch -
concurrency sketch
- last updated: Jun 09, 2024
Concurrency is illusion of parallelism. parallelism comes under concurrency techniques but it may execute concurrently but not necessarily in parallel. The actual execution (concurrent or parallel) depends on single-core or multi-core, os ability to manage threads etc. In conclusion, all parallel programs are concurrent but not all concurrent programs are parallel..
Related Bytes:types-of-concurrency -
Design Patterns out in the wild
- last updated: Jun 09, 2024
I was tired of seeing some unrelated examples when it comes to explaining design patterns like cars, students etc. And looked for a technical explanation which I couldn’t find it all in a single place. And below are the list of examples for the design pattern that I have seen/used so far in the modern software/web
- Singleton - Initializing DB, Redis, firebase instance
- Factory - Initializing like with options createConfig() for dev/prod/staging env
- Builder - constructor with many params to use builder pattern. In Jest, we use builder pattern via expect().toBe();
- Abstract Factory - For example we are writing a application for both online/offline we can define a factory like this: Connectivity -> ConnectivityLocal or Remote
- Bridge Pattern - Capacitor Plugin For Android/IOS/Web (Platform Independent)
- Prototype - cloned object instead of creating new
- Adapter - In modern web dev, if you want to deploy to different hosting sites like cloudflare/vercel, you will use the adapter as target in vite that converts your build to appropriate api of the hosting environment.
- Proxy - new Proxy() in js to change the few language features of js (get/set) etc.
- Decorator - python has @decorator; Decorators dynamically alter the functionality of a function, method, or class without having to directly use subclasses or change the source code of the function being decorated
- Observer(like pub/sub) + Iterator (Rxjs)
- Strategy - It may prove useful for specifying policies in framework design. Using STRATEGY, clients may parameterize the implementation. For example, error-handling is typically delegated to the application. Such a design may be realized by letting the client provide a strategy to be invoked upon an error. By those means, the error may be handled in an application specific manner, which may stretch between simply ignoring the error to logging it or even reboot the system (Patterns in C book)
- Mediator - Middleware (Auth, CORS etc)
-
form accessibility
- last updated: Oct 30, 2023
For
<form>,- use semantic html tags like
<label>,<input>with appropriate type,<select>rather than div all around <fieldset>and<legend>to group elements- to group/associate label and input, use for and id attributes on it
- to handle error in the forms use (aria-invalid, aria-describedBy with appropriate id)
- to navigate to the next form element, use enterkeyhint (look up on MDN), it will improve UX when using virtual keyboard (for example: mobile keyboard) along with event listeners for handling keydown events.
- make sure to handle events (keyboard events) (for example: if used
<div>to create checkbox, ensure keydown space/enter is handled, aria-checked, role, focusable).. ie: if creating custom components, make sure to add appropriate role, aria attributes, handle aria states, events, label, focusable. - Test using NVDA / TalkBack
- Remember Placeholder text is not a replacement for labels
- use semantic html tags like