frontpage.
newsnewestaskshowjobs

Made with ♥ by @iamnishanth

Open Source @Github

Open in hackernews

Show HN: SuperUtilsPlus – A Modern Alternative to Lodash

https://github.com/dhaxor/super-utils-plus
91•dhax_or•1mo ago
Hey HN!

After years of wrestling with Lodash's quirks and bundle size issues, I decided to build something better. SuperUtilsPlus is my attempt at creating the utility library I wish existed.

What makes it different?

TypeScript-first approach: Unlike Lodash's retrofitted types, I built this from the ground up with TypeScript. The type inference actually works the way you'd expect it to.

Sensible defaults: Some of Lodash's decisions always bugged me. Like isObject([]) returning true - arrays aren't objects in my mental model. Or isNumber(NaN) being true when NaN literally stands for "Not a Number". I fixed these footguns.

Modern JavaScript: Built for ES2020+ with proper ESM support. No more weird CommonJS/ESM dance. Actually tree-shakable: You can import from specific modules (super-utils/array, super-utils/object) for optimal bundling. Your users will thank you.

The best parts IMO:

compactNil() - removes only null/undefined, leaves falsy values like 0 and false alone

differenceDeep() - array difference with deep equality (surprisingly useful)

Better random utilities with randomUUID() and randomString()

debounce() that actually works how you expect with proper leading/trailing options

Also genuinely curious - what are your biggest pain points with utility libraries? Did I miss any must-have functions?

Comments

gaaaaaaaarf•1mo ago
Nice work! Reminds me of https://github.com/angus-c/just

Suggestion: add more tests and run some benchmarks

dhax_or•1mo ago
Thanks for this! I've already started adding more tests. I ran some benchmarks and they were really impressive. I will get it out in the next release
addandsubtract•1mo ago
Not to be confused with the other Just: https://microsoft.github.io/just/
latchkey•1mo ago
Or this https://github.com/casey/just
dannyfritz07•1mo ago
I don't think we've really seen many successors to LoDash other than Ramda because the platform now has many of Underscore's functions built in.
7bit•1mo ago
> Like isObject([]) returning true - arrays aren't objects in my mental model.

Correct me if I am wrong, but Array factually are JS objects and "[] instanceof Object" is true.

Fair enough if that does not fit your mental model, but I would not use any library that treats facts like opinions.

ivanjermakov•1mo ago
Distinction is tricky since you can use indexing on plain objects, e.g.

    const foo = {};
    foo[0] = "bar";
rafram•1mo ago
Right. For the purposes of standard library functions that operate on array-like objects,

  { length: 1, 0: "item" }
is an array.
williamdclt•1mo ago
I agree with the author that it’s almost never what you want. But I agree with you that it’s the reality of the platform, ignoring it will cause its own problems.

I’d surface the footgun rather than trying to pretend it’s not there: isNonArrayObject and isObjectOrArray, or something like that

7bit•1mo ago
Absolutely agree. I also hate that empty arrays are true, which is different from other languages. But I agree that it's better to face the reality of the language than create a function that evaluates [] to false. It trains you a bad habitnand some day that will cause you to introduce a bug.
williamdclt•1mo ago
> I also hate that empty arrays are true, which is different from other languages

I don’t mind that actually! I don’t think I have much use cases for “empty array is semantically different from non-empty”. Usually I find null/undefined are better choices, an empty array is just a normal array, I don’t expect it to be handled differently

7bit•1mo ago
What do you think about empty strings being falsy in most languages including js?

Null/undefined is a better choice, but there's many occasions where you do not have the power of choice. For example with document.querySelectorAll, which returns an empty array if nothing is found. The simple thing to do is to just check for it's length or just iterate over it's nodes, but still. I prefer empty arrays being falsy.

Just to clarify, I'm not saying one is better than the other. I just prefer how it works in other languages like Python. But I still would rather work with the JS language properties, than import a library that changes how I test for empty arrays.

nothrabannosir•1mo ago
Akshually, implicitly casting any non Boolean type to true or false is no better than implicitly casting “0” to 0. :) B-)
7bit•1mo ago
No better based on what criteria? In what language? This is typical in Python and done even by core-devs. It is how the language was designed and it was designed to support that.
nothrabannosir•1mo ago
In the "akshually" sense. "Zen of programming" (or "I'm smart because I use the word monoid unironically").

"If is an anti pattern", "null values are an anti pattern", "`string' is an anti-type", "util libraries are an anti pattern", etc.

And of course "boolean is an anti type" but let's not get into that. :D

(Nor into the value of "idiomatic python" as an argument on healthy programming habits....)

7bit•1mo ago
Ah got it. Based on personal opinion. Thanks for explaining.
nothrabannosir•1mo ago
You’re welcome! ;)
williamdclt•1mo ago
> What do you think about empty strings being falsy in most languages including js?

I don’t love it! I think it’s inconsistent with empty arrays being truthy.

In practice, I see a lot more mishandling of empty strings than empty arrays (eg “!myvar” catching null and empty strings when it’s not what was meant) which hints that it’s not the right thing to do: an empty string is a valid string, whether its semantically different from non-empty entirely depends on the context and shouldn’t be baked into the langage.

Generally, I think implicit casts are not a great idea and I’d rather they didn’t exist (one of the few things I think Go got right).

> For example with document.querySelectorAll, which returns an empty array if nothing is found

Yes I think it’s doing the right thing. It’s indeed returning the list of elements, whether there’s 0 elements or more it’s still a valid list. As you say, you don’t usually need to handle it any differently from a non-empty array (just iterate), so I don’t think it should cast to a different value.

However if for example you were passing something like a whitelist as an argument, I’d expect [] to mean “there is a whitelist, allow only these items (ie allow nothing)” and null to mean “no whitelist, everything allowed”. These two things are semantically different, I think it makes sense to cast to different values.

I do see your point and it’s definitely at least partly a matter of taste. Again id rather there was no implicit conversion at all, removing the risk of mishandling altogether!

dcsan•1mo ago
your option is a bit more verbose but definitely more clear. confusing the underlying definitions of the language itself will lead to problems later.
PUSH_AX•1mo ago
Will it? Will it really?

I’ve been writing JS for so long I’ve forgotten all these language quirks, I feel like it’s fair for most people, these language choices are kind of meaningless in day to day, what’s meaningful is a function returning things that will make sense to most people. Or at least have two functions, languageStrictIsObject()

williamdclt•1mo ago
Yeah, in practice I would only encounter the case of arrays being objects when doing something highly polymorphic (eg reading some JSON that can be anything), which likely would have test cases for every type anyway.

But when I’m writing a reusable lib and I can’t perfectly abstract a gotcha, I design the API so that the dev _has_ to make an explicit decision rather than defaulting on their behalf (defaults are evil). So, isObjectOrArray and isObjectNonArray: you have to think about which applies. Another example is sorting: does it sort in-place or immutably? Make it explicit in the function name. Does a function expect a sorted array or will it sort itself? Make it explicit in the function name. And maybe provide both variants.

moritzwarhier•1mo ago
Lodash also has "isPlainObject". Not sure if that's as performant as using Array.isArray or even simpler trickery (see below), but it seems that this fixes it.

"isObject" is just not well-defined for other cases that might be interesting, in my opinion. Not just "null" or arrays.

Functions can have properties (although they don't have the object prototype or primitive type).

Class instances behave differently compared to plain objects when used with libraries or other code that inspects the shape or prototype of objects, or wants to serialize them to JSON.

If you deal with unknown foreign values that are expected to be a JSON-serializable value, you could go with something like

  isObject = (o) => !!o && typeof o === "object" && !Array.isArray(o)
But it does not deal with all the non-JSON objects, e.g. Map or other class instances that are not even JSON-serializable by default.

When data comes from parsing unknown JSON, the check above should be enough.

In other cases, the program should already know what is being passed into a function. No matter if through discipline or with the aid of an additional type syntax.

For library code that needs to reflect on unknown data at runtime, I think it's worth looking at Vue2's hilarious solution, probably a very good and performant choice, no matter how icky it might look:

  https://github.com/vuejs/vue/blob/547a64e9b93d24ca5927f653710b5734fa909673/src/util/lang.js#L293
Since the string representations of built-ins have long ago become part of the spec, it seems that there is no real issue with this!
bryanrasmussen•1mo ago
libraries of this sort, especially in JavaScript, often exist to enforce a more reasonable mental model rather than the model baked into the language.
7bit•1mo ago
I understand that. I just don't think that it is a good habit. Instead of just learning the languages and it's quirks now you form a bad habit and start to rely on one dependency for all your projects.
bryanrasmussen•1mo ago
this is generally the view I have on these sorts of things as well, although I must admit that my views are often out of step with what everybody else I work with feel on the matter.
dschuessler•1mo ago
> any library that treats facts like opinions

The word 'object' has different meanings. One includes arrays and the other does not. They prefer the latter. You prefer the former. I don't think this has much to do with 'facts' and 'opinions', but rather with the practicality of choosing a certain way to speak.

I’d liken it to the word 'sorting'. JavaScript libraries sort in a certain way that is simple to implement. However, this is so different from what we typically mean by 'sorting' that people came up with natural sorting algorithms. Are these people treating facts like opinions on how to sort? I’d rather say, they acknowledge the relevance of a certain way to speak.

_1tan•1mo ago
We use es-toolkit to replace Lodash - how would you compare your library?

We just migrated a React app with around 500k LOC and this worked quite well and flawless.

dhax_or•1mo ago
I've not used es-toolkit but from what I see you get lower bundle size, typescript support and a better performance with our library. I will be releasing the the benchmark soon enough so do watch the repository if you can
uwemaurer•1mo ago
I use es-toolkit. It is fully in Typescript. Every function can be imported without any extra overhead, for simple functions it just adds a few bytes then to the bundle. I doubt "better performance" since most helpers functions are just tiny and there is no room for significant improvements.

So I think trying to be better here is pointless, better focus on offering more helpful utility functions which might be missing in es-toolkit

redslazer•1mo ago
We migrated to remeda from Lodash and are pretty happy. https://remedajs.com/

What do you do differently?

jokull•1mo ago
I recommend https://remedajs.com/ - they're always making the types more accurate too. Like groupby has nonempty lists.
gcmeplz•1mo ago
The types look great on remeda, but one thing that looks intriguing about SuperUtilsPlus is the focus on being tree-shakeable. Lodash's lack of tree-shake-ability is a drawback to using lodash on the frontend.

edit: the types on remeda look great though! If I were doing a backend-only NodeJS project, I'd be super tempted to test it out.

bythreads•1mo ago
Just import what you use for lodash?, the theres not need for a treeshake situation?
yoz-y•1mo ago
What I’d like is a utility library like this, but instead of it being an actual library, be it some utility that generates a single file with exports of the few functions I need. Even just something that would make copy pasting them easier.

As in, I want actual zero dependencies, not even the library itself. The reason: I never want these to randomly update.

acbart•1mo ago
Couldn't you just pin a specific version dependency? My brain says there's some way to also pin to a hash, but that would require googling and I'm on mobile.
nodewrangler•1mo ago
The problem is that even if you pin to a version, at some point you’ll need to update node, typescript, or some other package, and then if this package doesn’t update, then you may have to migrate from it to something else. While js tries to enforce backwards compatibility, and npm, etc. help with the complex landscape, in practice with node, typescript, etc., even with LLMs helping, it can be a pita and hours or days of work to update at times. It’s just not worth it for things you could’ve just implemented yourself. There are exceptions to this, though.
mystifyingpoi•1mo ago
> at some point you’ll need to update node, typescript, or some other package

I experienced both sides of this discussion (project that always pulled :latest disregarding any kind of versioning, and project that had node_modules commited inside the repo) and both extremes suck, but I lean towards the second one. I'll totally take a few days of pain over not knowing whether prod will work today or not.

hinkley•1mo ago
This is why running your own mirror is what most large companies do. Guarantee no take-backs.
mystifyingpoi•1mo ago
Pinning is a good strategy (I'd say that it should be the default one), but depending on your level of paranoia (think left-pad), you might consider just downloading the lib as it is, and storing it in source control forever.
graypegg•1mo ago
I do sort of miss bower [0] for this reason. It was really just a way to download javascript and plunk it into your application. It was standard practice to check all of your vendor dependencies into SCM. [1] Of course a good chunk of it was transformed through something like Gulp or Grunt before being added to the bower repository so you were unlikely to maintain those once checked in, but there was still quite a few packages (small jquery image gallery plugins and the like) that were just some un-transformed javascript someone typed up and threw at bower verbatim.

[0] https://bower.io

[1] https://addyosmani.com/blog/checking-in-front-end-dependenci...

parentheses•1mo ago
OOC, what is the benefit of having a "library" that requires such manual labor to maintain and upgrade?

You'd miss out on CVEs because you don't use the common dependency paradigm.

You'd also miss out on bug fixes if you are not detecting the bug itself.

Help me understand because I'm with you on less dependencies but this does feel a bit extreme.

hofrogs•1mo ago
Why would small functions like "difference", "groupBy", "flatten", etc. have CVEs and require bug fixes? Implementing those correctly is a one and done thing
jsheard•1mo ago
You'd be surprised: https://positive.security/blog/lodash-ramda-underscore-vulne...
hofrogs•1mo ago
Looks like these are mostly based on "reserved" attributes (with double underscores that have no special meaning in the language, just make unintentional collisions less likely), a modern solution utilizing JS Symbol type (where needed) would have no such issues
michaelsbradley•1mo ago
Why not copy & paste the code you need into a vendor/ subdir?

If the vendored code needs to be updated because of a change in your build tools or whatever then you’ll likely be making similar changes to other parts of your project.

yoz-y•1mo ago
This is the approach I'm sometimes using, but it would be nice to have tooling around that :)
fsloth•1mo ago
Nobody wants anything _ever_ to ”randomly update”. Why this is the default setting on so many development setups boggles my mind.

I really havent figured out why professional systems insist running on the bleeding edge - it’s your feet are bleeding here I believe. 10 year … 15 year old code is generally excellent if you know it through and thorough.

skydhash•1mo ago
As my experience grows, I'm getting fonder of stances like Debian or Common Lisp, which favors stability. Once you've solved a problem, it's not fun having your foundation morphs under you for no other reasons than bundling features and security updates.
chrisweekly•1mo ago
CVEs are a thing. If vulnerabilities are discovered in your dependency graph, choosing to ignore them can have severe consequences.
fsloth•1mo ago
I don’t believe anything I wrote above promotes the idea of ignoring vulnerabilities as a standard procedure.

CVE database is an excellent way to be informed about vulnerabilities and there are services to automatically map CVE reports to code bases.

chrisweekly•1mo ago
Ok, but the context for the conversation is external dependencies, and you expressed a preference for code aged 10-15 years. I'm just saying that a codebase that's 10-15 years old, with any dependencies at all, is going to be rife with vulnerabilities. Thus the choice is either staying current or living with vulnerabilities.

What's the alternative? Are you suggesting that backpatching transitive deps dating back over a decade-plus tineframe is a viable maintenance strategy?

fsloth•1mo ago
I'm suggesting the "default mode" would be that updating is explicit rather than automatic.

The "10-15" year old comment can be taken in the context of language specifications for example. C++11 is a totally fine language standard, and since backward compatibility is the only reason for C++ to exist at this point there is no intrinsic benefit in using a later version.

chrisweekly•1mo ago
> "I'm suggesting the "default mode" would be that updating is explicit rather than automatic"

This, I agree with. Though for modern codebases, leveraging tools like Dependabot is very helpful. Deliberate upgrades, with automation to make it practical.

programmarchy•1mo ago
shadcn distribution model for utils is a good idea. i wanted something for react hooks as well and was surprised that didn’t seem to exist either.
ryancnelson•1mo ago
Biggest pain point: wtf is lodash? I don’t care if it’s in your readme, but maybe tell us in your HN hype post
cronelius•1mo ago
lodash is extremely common knowledge in the js/web world. you’re asking a chemist to explain atoms before sharing their big discovery
ryancnelson•1mo ago
No I’m asking a commercial that pops up in what I’m watching and says “ask your doctor if ciallis is right for you.” and gives no context but someone washing their tesla.
podgietaru•1mo ago
I don’t know. Maybe if it’s getting a lot of traction it’s beholden on you to look up what it is.

I don’t understand everything on the HN frontpage either.

nativeit•1mo ago
I dunno about anyone else, but someone washing their Tesla fits my mental model of impotence perfectly.
robinson7d•1mo ago
Do the example functions (isObject, isNumber, differenceDeep, randomUUID, debounce), along with the name (“SuperUtilsPlus”), and sentences saying “utility library” and “JavaScript” really not give enough context to get an idea of what this library is for?

And so if Lodash is what they’re trying to replace, is that not enough info to infer what Lodash might be?

The pharma ad comparison seems more than a little hyperbolic to me.

epolanski•1mo ago
To use your analogy, this is more of "Show HN: Cialis - A modern alternative to Viagra".

You either care about Viagra and read or move on.

ryancnelson•1mo ago
the irksome bit was this: lodash's page, first sentence, says "A modern JavaScript utility library delivering modularity, performance & extras."

this github's readme says "alternative to lodash". other than being named "superutilsplus", someone who clicked on it would need to then go google for lodash to see it's another js utilities kit, to then figure out they don't care.

I stopped professional javascript development when i stopped having an office next to Ryan Dahl at Joyent, so, yeah i haven't cared for about a decade. Thanks for explaining about atoms, though, my esteemed chemists.

cronelius•1mo ago
HN is not a feed of pharmaceutical ads. HN is a place where industry experts in many industries exchange projects and news in _their_ language. HN is going to be a difficult place to live if you are unwilling to google or chatgpt for things you don't understand. Most of us are here explicitly to discover things we've never seen before – there are other places on the web to have everything spelled out
AstroBen•1mo ago
Anyone who doesn't know what lodash is wouldn't be interested in this. It's expected knowledge for the target audience
rgreek42•1mo ago
Weird comment
cronelius•1mo ago
I made twitter post 3 or 4 years ago making fun of Lodash team for _still_ not shipping loadash 5 and they didn't like it very much. They started working on Lodash 5 in like 2015 and it still hasn't shipped. Guess we make our own now
insin•1mo ago
The published version appears to be CommonJS only:

    $ node index.mjs
    import { isString } from 'super-utils-plus'
             ^^^^^^^^
    SyntaxError: Named export 'isString' not found. The requested module 'super-utils-plus' is 
    a CommonJS module, which may not support all module.exports as named exports.
You might also need to update some of your type checks to handle wrapper objects like new String() - Object.prototype.toString.call(...) is your friend.
rafram•1mo ago
> You might also need to update some of your type checks to handle wrapper objects like new String()

There’s genuinely never a reason to use new String(). You should treat non-primitive String instances as bugs.

the_sleaze_•1mo ago
Can you explain a little? I've never heard this.
rco8786•1mo ago
I wonder why the authors decided to make `flatten` only go one level deep, and have `flattenDeep` that goes N levels. AFAIK most other implementations of Array.flatten do it recursively through however many levels exist.
meeech•1mo ago
don't discount the value of a good docs site. that was one of things i loved about lodash that made it so easy to use, and to discover all the functionality it offered. So if you looking to replace it, would be good to have similar docs.
thih9•1mo ago
About pain points / feature requests:

Is there an idiomatic way to duplicate a hash while replacing one of its values, preferably something that supports nesting?

Whenever I work with react and immutable structures, this comes up and I hack something simple.

I don’t do FE on a regular basis though so my perspective may be skewed.

sethaurus•1mo ago
These days that's pretty well-supported in the base language:

    const updated = { ...existing, someKey: someNewValue };
You mention nesting. That starts to look messier:

    const updated = { ...existing, someKey: { ...existing.someKey, ...someNewValue } };

There's a whole cottage industry of little libraries to make this ergonomic/fast in the general case (copying immutable objects with nested changes). `immer` is a popular choice. But the reality is that it gets complicated to do this generically; in my view it's usually better to just use the base language where possible, even if it means sprouting some util functions for the various kinds of updates you end up doing.
antifa•1mo ago
There might be a function called produce in one of your immutable/react lib.
deadcoder0904•1mo ago
https://radashi.js.org/ is also a good alternative

Why Lua Beats MicroPython for Serious Embedded Devs

https://www.embedded.com/why-lua-beats-micropython-for-serious-embedded-devs
1•willhschmid•3m ago•0 comments

What happens if we have our conversations with AI in public?

https://old.reddit.com/r/microsaas/comments/1lynaw7/what_happens_if_we_have_our_conversations_with_ai/
1•markdoppler•3m ago•1 comments

AI the Ripper

https://hugston.com/articles/AI_Ripper
1•trilogic•3m ago•0 comments

Can a daily nap do more harm than good?

https://www.rte.ie/brainstorm/2025/0704/1503253-napping-benefits-disadvantages-sleep-intertia/
1•austinallegro•7m ago•0 comments

Show HN: Euler and Fourier = Cognition?

https://ryukulogos.github.io/RAIN-html-easy-explanation/
2•RyukuLogos•9m ago•1 comments

Defold editor scripting in 1.10.4: scene editing

https://defold.com/2025/07/11/editor-scripting-update/
1•vlaaad•11m ago•0 comments

When AI Codes, What's Left for Me?

https://corecursive.com/coding-agents/
1•ibobev•12m ago•0 comments

How do you keep meetings productive and cost-effective?

https://capdrainapp.com
1•ronny_rebellion•12m ago•1 comments

Atopile – design circuit boards fast – with code

https://atopile.io/atopile/introduction
1•poly2it•13m ago•0 comments

Show HN: HNping 'remind me later' for HN via web push

https://hnping.com/
1•Galorious•23m ago•0 comments

Reading Neuromancer for the first time in 2025

https://mbh4h.substack.com/p/neuromancer-2025-review-william-gibson
1•keiferski•30m ago•0 comments

Who Is Pope Leo?

https://www.americamagazine.org/faith/2025/07/10/who-pope-leo-robert-prevost-251107
1•joules77•30m ago•0 comments

Leading your engineers towards an AI-assisted future

https://blog.thepete.net/blog/2025/06/26/leading-your-engineers-towards-an-ai-assisted-future/
1•r4um•35m ago•0 comments

Thoughts on Motivation and My 40-Year Career

https://charity.wtf/2025/07/09/thoughts-on-motivation-and-my-40-year-career/
1•r4um•36m ago•0 comments

Assumptions

http://theprogrammersparadox.blogspot.com/2025/07/assumptions.html
1•r4um•37m ago•0 comments

Sega Enterprises Ltd. vs. Accolade, Inc., 977 F.2d 1510 (9th Cir. 1992)

https://en.wikipedia.org/wiki/Sega_v._Accolade
1•Bluestein•42m ago•0 comments

UK graduates share their job-hunting woes amid the AI fallout

https://www.theguardian.com/money/2025/jul/13/student-debt-graduates-share-job-hunting-woes-ai-fallout
3•mykowebhn•46m ago•0 comments

Nearly two-thirds of UK workers turning to drink because of job pressures

https://news.sky.com/story/nearly-two-thirds-of-uk-workers-turning-to-drink-because-of-job-pressures-survey-says-13395997
3•austinallegro•49m ago•0 comments

Gmail AI hallucinates, distorts email contents

https://www.t-online.de/digital/aktuelles/id_100811852/gmail-fantasiert-googles-mail-programm-verfaelscht-fremde-inhalte.html
5•disentanglement•50m ago•0 comments

Show HN: TXT OS – Open-Source AI Reasoning, One Plain-Text File at a Time

https://github.com/onestardao/WFGY/tree/main/OS
7•TXTOS•55m ago•2 comments

Empirical evidence of LLM's influence on human spoken communication

https://arxiv.org/abs/2409.01754
3•ransom_rs•56m ago•1 comments

I built Findly.tools – a successor to 1000.tools

https://findly.tools/
1•drdruide•57m ago•1 comments

A (Limited) Defence of Footnotes

https://www.kryogenix.org/days/2025/07/03/a-limited-defence-of-footnotes/
2•jruohonen•1h ago•0 comments

Retrieval Embedding Benchmark

https://huggingface.co/spaces/embedding-benchmark/RTEB
2•fzliu•1h ago•0 comments

Stop memoizing Hash lookups in Ruby

https://nithinbekal.com/posts/ruby-hash-memoization/
2•thunderbong•1h ago•0 comments

Summary of Bluesky Whitepaper

https://twitter.com/RealmOfSoftware/status/1904941497910505833
1•krsoninikhil•1h ago•0 comments

Vibe-Engineering: When AI Does All the Coding, What Do We Do?

https://img.ly/blog/vibe-engineering-when-ai-does-all-the-coding-what-do-we-actually-do/
2•tosh•1h ago•0 comments

Show HN: We developed an AI tool to diagnose car problems

https://autoai.help
3•mariyan250•1h ago•0 comments

Ask HN: I own wtf.store -what to build that makes people say WTF (in gud way)?

2•deep_thinker26•1h ago•1 comments

Windows Update forced new version of Chengjie which is unusable to users

https://old.reddit.com/r/Windows11/comments/1lvelyb/warning_to_windows_11_24h2_chengji_users_for_july/
3•charlieyu1•1h ago•1 comments