
Research
Node.js Fixes AsyncLocalStorage Crash Bug That Could Take Down Production Servers
Node.js patched a crash bug where AsyncLocalStorage could cause stack overflows to bypass error handlers and terminate production servers.
if you're happy and you know it, leave a star
created by @vriad
One of the best things about MobX is that it lets you create and use observable objects without worrying about normalization. If you get a big blob of nested JSON back from an API, you can wrap it up as an observable and pass it into your React components. Badda bing, badda boom.
So why build a normalized cache on top of MobX? Because it's literally magic.
If you normalize all data coming into your application, there is a single copy of each "object" in your application. What do I mean by "object"? To understand that, let's look at an example.
// First let's create a Normi instance
const normi = new Normi();
// Now let's pass some data into it!
normi.merge({ id: '123', name: 'Zendaya' });
// => { id: "123", name: "Zendaya" }
Makes sense! Normi is built with TypeScript so all type information is preserved. Now let's pass in a more detailed version of Zendaya.
normi.merge({
id: '123',
bestSong: 'Replay',
bestMovie: 'Spiderman: Homecoming',
});
/* {
id: '123',
name: "Zendaya",
bestSong: "Replay",
bestMovie: "Spiderman: Homecoming"
}
*/
As can see, Normi has merged the two objects, since their id properties were equivalent.
let's look at an example. you're building a blog. your homepage fetches a list of posts and renders them as a list of links.
const posts = await getPosts();
// { id: string; title: string; }[]
Once a user clicks on one of the links, you fetch a "detail view" of the post:
const post = await getPost(id);
// { id: string; title: string; content: string }
As you can see the "detail view" contains the content field in addition to the fields from before.
Without normalization, you'd now have two JavaScript objects in memory that correspond to the same blog post. It's now possible for your representation of those blog posts to get out of sync. If you updated the title of a post, you would have to re-fetch both getPost() and getPosts() to ensure that all the data in your application is up-to-date.
For complex applications, this quickly gets unsustainable. You need to know exactly which objects get fetched by which APIs and trigger a set of "refetches" every time you update something in your database. This problem is compounded by the single-page application paradigm and client-side routing - data fetched at the beginning of a long session will stick around for a long time, because there is no need for a full-page refresh.
Normi is designed to be the easiest possible way to get the benefits of denormalization with none of the usual hassles. There's no need to define
The hard part is knowing when two objects correspond to the same node. By default, Normi only has two criteria for a node:
id propertyThis works great if you're using UUIDs to uniquely identify every object in your database. If you're using auto-incrementing integers (SERIAL in Postgres) then this default configuration may not work. You'll run into problems where two objects from different tables have the same ID.
If you use a different key to store object identifers, you can use that instead:
const normi = new Normi({ id: '__ID__' });
normi.merge({
__ID__: '1234',
size: 'Venti',
});
If you've used GraphQL or Apollo, you may be aware that Apollo's normalized cache generates a unique identifier by concatenating the id field and the __typename field. This works well for GraphQL APIs, where the __typename property is typically added into your data payloads automatically by your GraphQL server framework.
To configure similar behavior in Normi:
const normi = new Normi({ id: ['id', '__typename'] });
For any other use case, you're able to totally customize ID generation by passing a function into your params:
const normi = new Normi({
id: data => {
// generate a string from your object
if (data.uid) return data.uid;
if (data.id) return `__${data.id}`;
return `${Math.random()}`;
},
});
FAQs
A zero-config normalized cache for MobX
The npm package normi receives a total of 1 weekly downloads. As such, normi popularity was classified as not popular.
We found that normi demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Research
Node.js patched a crash bug where AsyncLocalStorage could cause stack overflows to bypass error handlers and terminate production servers.

Research
/Security News
A malicious Chrome extension steals newly created MEXC API keys, exfiltrates them to Telegram, and enables full account takeover with trading and withdrawal rights.

Security News
CVE disclosures hit a record 48,185 in 2025, driven largely by vulnerabilities in third-party WordPress plugins.