[HN Gopher] NPM Vulnerability Discussion on Twitter ___________________________________________________________________ NPM Vulnerability Discussion on Twitter Author : ColinWright Score : 127 points Date : 2022-05-10 09:38 UTC (13 hours ago) (HTM) web link (www.solipsys.co.uk) (TXT) w3m dump (www.solipsys.co.uk) | BigJono wrote: | Fixing security issues is nice, how about we go a step further | and learn to write a one or two liner instead of inundating every | project with 400,000 indirect dependencies? | Macha wrote: | I'm not sure how to avoid this sometimes. | | I have a Rust project I've been working on. | | It has dependencies for: | | axum: the web framework in use | | serde, serde_json: Serialization of API responses | | sqlx: To talk to sqlite | | time: Standard datetime format with localisation and serde | support | | tera: templating | | tracing: async logging | | uuid: UUID generation | | Of these, I feel they're reasonable dependencies. You could | maybe quibble about uuid (which itself only depends on rng + | serde with the features I've enabled), or tracing maybe, but | they provide clear value. | | Anyway, those direct dependencies expand out to 300-odd | transitive dependencies. | | So what do I do? Do I write a templating engine, HTTP server | implementation, SQLite driver and JSON library from scratch to | build my little ebook manager? | 65 wrote: | 300 is nothing compared to the typical Node project. It's | typical for a basic React project to have over 14,000 | dependencies. | zachrip wrote: | Can you please source this? A react project can be so many | things...do you mean create react app? A custom react app? | aphexairlines wrote: | create-react-app starts with 1506 deps: | $ npx create-react-app my-app $ find my- | app/node_modules -name package.json | wc -l | 1506 | jameshart wrote: | 90% of which are development tools - eslint, testing, | typescript, webpack, etc. | | The actual runtime dependencies of a react app are | basically just react and react-dom. | infogulch wrote: | Are dependencies that run on your development machine any | _less_ of a maintenance or security concern? | jameshart wrote: | No, but the number being quoted is the sum of two | different security concerns - and it's attributing the | concern to 'react apps', when actually react itself is | pretty clean in terms of dependencies. | hsbauauvhabzb wrote: | Browsers recently implemented uuid natively, not sure if | that's a js spec change but do check :) | Macha wrote: | Doesn't help in this case, since it's server side code. | Tainnor wrote: | 300-odd seems reasonable (or at least unavoidable, given | modern realities). JS projects typically have much more, and | additionally, you don't even get deduplication of modules, so | you may have three different versions of the same module on | disk. | criddell wrote: | I don't think you can reason about quality in a modern | Javascript project. Keeping a close eye on thousands or | tens of thousands of modules isn't practical. | | If Software Engineers were more like "real" engineers (ie | PEs) they could never sign off on a project built like | this. | [deleted] | bayindirh wrote: | No. We must move fast, break things, and trust the network | (because it's reliable and all that thing). | | Implementing your good code with no dependencies is heresy! | It's a relic of the past. | | </rant>. | | On a serious note, you can implement a lot of things with a | standard library of any language, and only time consuming | machinery should be incorporated as external dependencies, but | somebody didn't get the memo, I guess. | _fat_santa wrote: | I think these packages are just holdovers from "Before ES6". I | can see it be reasonable to pull in a package like this back | before the functionality was implemented in native JS. All | these packages are just holdovers that are only used by: | | * Legacy Projects that pulled them in way back when and never | migrated to the native API's | | * Inexperienced developers not knowing this is part of standard | JS now. | | You can't really do much about the former. For the latter | though, NPM would be wise to plaster a link to MDN's docs on | some of these packages. | EamonnMR wrote: | * Tutorials written in the pre-ES6 world being copied and | used in the ES6 world. | danlugo92 wrote: | But "isEven"??? | | That's one line of code in your utils module... | kuschku wrote: | In typescript? Sure. In vanilla JS? It's more complicated. | How do you handle someone inputting undefined/null/a | string/a random object/NaN/etc? | | For isEven, you first need isNumber. And that's where the | complexity lies. ({}) % 2 == 0 // false | ([]) % 2 == 0 // true "" % 2 == 0 // true | "a" % 2 == 0 // false "1" % 2 == 0 // false | "2" % 2 == 0 // true undefined % 2 == 0 // false | null % 2 == 0 // true | leodriesch wrote: | typeof x !== "number" ? false : x % 2 === 0 | UncleMeat wrote: | Somebody in your codebase is going to use !isEven(x) to | test for isOdd and introduce a bug. IMO, it should crash | if passed a non-number. | lmkg wrote: | Actually it's the other way around. The isEven package | has one dependency, which is the isOdd package. | | I am literally not joking. | https://www.npmjs.com/package/is-even | johnchristopher wrote: | https://www.npmjs.com/package/is-odd-and-even | | I don't know what to say. /** * | is-odd-and-even * Github: | https://github.com/fabrisdev/is-odd-and-even */ | import isOdd from 'is-odd' import isEven from 'is- | even' /** * @param {number | string} i | The number to check if it's odd and even * | @returns {boolean} True if the number is odd and even, | false otherwise */ export default function | isOddAndEven(i){ return isOdd(i) && isEven(i) | } | UncleMeat wrote: | IsOdd and IsEven are so famous that it would not surprise | me at all if there a bunch of joke modules using them. | UncleMeat wrote: | Independent of the insanity that is the npm ecosystem, | the API design skill of handling invalid input in a bug- | resistant way is important. If somebody sent me a code | review with isEven implemented as "typeof x !== "number" | ? false : x % 2 === 0" I'd tell them to fix it. | onion2k wrote: | _How do you handle someone inputting undefined /null/a | string/a random object/NaN/etc?_ | | Your isEven function should check that it's operating on | a number. Eg "const isEven = (i) => typeof i === 'number' | && i % 2===0;" If it's not a number then calling isEven | on it doesn't make sense. If the user wants to check if a | string is even then they can convert it before making the | call. | jasonlotito wrote: | The irony of using the isEven as an example of what you | should just write yourself and then providing an example | that returns a truthy value for isEven(3). | onion2k wrote: | No idea what you mean. ;) | BigJono wrote: | You don't handle it. Garbage in, garbage out. | laurent123456 wrote: | Or garbage in => throw an exception and crash the app. | This stuff should be fixed as soon as possible instead of | invalid data slowly spreading in every layers of the app. | BigJono wrote: | Assuming you're importing it as a black box abstraction, | then absolutely. | | 'isEven' really shouldn't be a dependency though, either | through npm or internally. 'x % 2 === 0' works fine for | integers and can be inlined, or if you're using it a | bunch and want slightly cleaner code, you can define it | as a lambda alongside the code that uses it. Then | everyone can see exactly what it's doing with the full | context. | | The real issue is overabstraction. Even if you do | everything "right" and have it as an internal dependency | with all the correct error handling, it still makes the | code a pain in the ass to read. | bcrosby95 wrote: | No. | | If the goal of isEven is to handle user input, it is | woefully misnamed. | zachrip wrote: | Right, it should be "isUserInputEven" /s | zachrip wrote: | https://twitter.com/lrvick/status/1523827220023853057 | | If you're trying to protect people, why release an exploit | straight to the public instead of responsibly disclosing? | | Edit: Looks like it's already known, hard to know that from the | tweet context. | progval wrote: | It's not a new one. | https://news.ycombinator.com/item?id=30403848 was _exactly_ the | same exploit. | NicolaiS wrote: | The issue has been publicly known for years. | | The more focus we can get the better - hopefully NPM will add | MFA at some point... | aasasd wrote: | Reminder: when 'colors' and 'faker' packages printed stuff in the | output in an endless loop, NPM and Github banned the author and | took over the packages. | | When 'node-ipc' overwrote all files on disk, NPM just waited | while the author himself published an amendment and posted that | the package 'only created a text file, no biggie'. | darepublic wrote: | faker was a disease that I fought against in the places where I | was unfortunate enough to inherit it in the codebase. lots of | devs not knowing better thinking it really made our tests more | robust -- it didn't, in fact, just more flaky. also faker's | functionality can easily be shimmed or rolled yourself if you | want to. I will continue the fight, there are many other super | popular npm packages whose value is dubious at best, cause | dependency tooling headaches, and are like viruses in the web | ecosystem. and the fact this faker guy sabotaged his own | package is great because even before that I was against it, and | now it is just easier to convince people not to import this | clown lib | EGreg wrote: | serial_dev wrote: | > We should treat things like operating systems do: have | collaborative security assessments for each package BEFORE it | is published. | | This would not work for small open source projects, and every | successful open source project starts out as a small project | that nobody vetted yet. | | I have smaller, but popular open source packages that I know | are used by many people,and most of those projects (even now, | after a year being public) get zero actual contributions. If | my most popular packages don't receive pull requests, how | would I find a trustworthy expert committee to judge all my | other silly little packages for free? | | Also, why would I make the projects I work for fun and for | free purposefully a painful, sluggish, bureaucratic | experience for everyone involved? | EGreg wrote: | It's a matter of scale, as I said :) | | At some point, projects have to bring in more "adult | supervision" | cmeacham98 wrote: | Sorry, but I can't watch your youtube video until it has been | thoroughly vetted to the same standard as commits to the | linux kernel or peer review in science. As a matter of fact, | I'd have to say your video is bad for society. | | Surely you see how this is a self-defeating argument? Of | course higher-stakes projects where inclusion of incorrect or | malicious inputs in the end result could have significant | impact on a lot of people will have more stringent checking | than social media. Is your ideal world really one where all | forums of human communication are peer reviewed? | MetaWhirledPeas wrote: | What YouTube video? I haven't read that comment yet; still | awaiting results from the Online Content Vetting | Foundation. Yours flew through the process though. | Congrats! | | In all seriousness though, I do agree somewhat with the GP. | Inherent vetting can be good. But it's also a tool used | against us for manipulation. An example of this would be | app stores. Heavily vetted, but you are force fed the apps | they want you to see, and they have every right to deny you | access to apps they find undesirable. | | We need systems of reputation and trust to emerge, as they | always have, and we need the freedom to choose them. Tools | like Twitter allow largely unvetted content, sure, but they | also allow users to curate their own circle of trust. This | comes with risks of course, but I trust it more than some | omniscient entity handing me content like mana from heaven. | EGreg wrote: | That's because they are vetted by ONE organization, that | privately owns the store. It is actually an example of | private capitalist ownership, again. | | In science, no one "owns" physics. No one "owns" articles | on wikipedia. The ideal is to have multiple reviews | represented and all of their major legitimate concerns | should be addressed before publishing something to the | public. Think of concentric circles where the inner | circle isn't just Apple or Google but a good mix of | experts with different views. | | The hard part is resolving disputes between experts, or | determining if a criticism is legitimate. This is what | "edit wars" are like on wikipedia. Perhaps in this case, | both points of view should be included side by side. | | In a capitalist market system, though, explaining nuances | of WHY Trump's or Biden's administration did something, | or including the entire context of a gaffe video, would | make it uninteresting to their audience. Imagine if Fox | News would fairly report the results of studies about | single payer healthcare around the world - their audence | would bounce. They face intense market pressures to cater | to their audience, this is WHY they report as they do and | WHY they tell their straight news anchors to "rein it | in". | | The one exception may be Tucker Carlson over there, who | is able to somehow maintain a show while going against | the entire military-industrial complex and establishment, | unlike Sean Hannity. It is a rare phenomenon to see | someone with such a highly promoted time slot have such a | contrarian position. But if it sells to an audience, I | guess it works. CNN totally jumped the shark when they | discovered they can cover the malaysian airline flight | for months 24/7 and their ratings went up. They went from | being a straight news network to pandering for ratings | too. None of the open source platforms or wikipedia would | sell out like that. | EGreg wrote: | It is a matter of scale. | | In the video, I bring this up to Noam towards the end. He | actually disagrees, that audience is a form of capital. He | says it is influence, but not capital. Even though one can | do the same operations with it as with any capital, | including exchanging it for other forms of capital etc. | | You are just USED to celebrity culture, and following what | Jonny Depp or Will Smith does can even overshadow a war in | Ukraine or humanitarian crisis in Yemen. Four Libyan | ambassadors matter more than millions of Libyans. | | On Wikipedia or in NGinX there are no celebrities, except | maybe the founders. And it is far far more useful and | popular than their closed-source capitalist alternatives: | Britannica/Encarta and Internet Information Server. They | power more machines and serve more people in more ways. | | And you bet that there are a lot of operating system | maintainers that put software like nginx and php through | their paces before giving their members access. | | If you don't like a centralized organization vetting | things, then have various distros, like Linux. The point is | that the author shouldn't also be the one vetting each new | version and what changed. Security researchers should be. | | Your argument for "free speech absolutism" would fail in | science and any endeavor that actually matters to people. | For humor, entertainment and idle discussion, maybe we can | have celebrities. | | But yes -- my video would normally not matter if not for | Noam Chomsky's amassed reputation and audience. The content | in my video would be far better published as part of a | collaborative discussion rather than an off-the-cuff one. | But a chat between two non-celebrities would be fine for | society... people could watch it for entertainment, or | whatever. It wouldn't move markets or convince people of | crazy theories about 9/11 or QANON pedophiles. | | There is a limit to how much power should be concentrated | in one place. | cmeacham98 wrote: | You have grossly misunderstood my comment if you think I | was arguing for "free speech absolutism", which I think | is an insane idea. | | To be completely honest, this entire comment reads to me | as rambling largely unrelated to my first comment. | moss2 wrote: | More-nitors wrote: | (not op) little things are taken seriously/ serious stuffs | are taken lightly | misnome wrote: | It's like bikeshedding. It's easier to deal with the | smaller problems. | exikyut wrote: | A random connection to bikeshedding being mentioned | yesterday in a totally unrelated thread: | https://news.ycombinator.com/item?id=31315883 | (interesting comment is the large block of text 3 replies | deep) | | Bit random, but my brain likes linking connections | between things. Not sure if useful? | infamouscow wrote: | Vendor and audit your dependencies. You shouldn't rely on | GitHub to protect you from security problems. | mort96 wrote: | While I agree in principle, that usually means you'll 1) | frequently blindly update all your dependencies, which | doesn't really give you much security benefit, or 2) use old | dependencies long after security vulnerabilities have been | discovered in them. The first point does give you some | security benefits by reducing the chance that you'll hear | about a malicious package before you upgrade to it, but it's | not exactly great. | | I don't know what the solution is. I don't think there is a | solution. We can't have 5000 dependencies from 2000 random | individuals on the internet and still be safe. But if you | want to avoid that situation, you're locking yourself out of | the vast majority of the NPM ecosystem. | infamouscow wrote: | Maybe the ecosystem needs to discourage unnecessary | packages imports. | flatiron wrote: | I know PGP isn't perfect but why aren't packages signed by their | maintainers? | franciscop wrote: | Overhead, and fear of losing the key and being locked out feels | like two valid reasons, I'm sure there are more I'm unaware of | (probably should add lack of familiarity, hence the lack of | knowledge). | jacques_chester wrote: | To my knowledge NPM doesn't currently have a mechanism for | signing by authors. Packages are signed by NPM itself on | upload, which defends somewhat against repository compromise. | cordite wrote: | Who will check the signatures when so few have signatures? | | What dev thinks oh I can't upgrade because of this error, | stackoverflow says use this flag --disable-signature- | verification so I do and now I can develop again | flatiron wrote: | Any place with a devops team would not disable that. | progval wrote: | For what it's worth, Debian packagers check signatures when | downloading from PyPI. | bornfreddy wrote: | I am starting to think that what we need is package | _distributions_. That is, forked popular packages that are hand- | vetted by a group of maintainers, just to make sure that some | random malware doesn 't find its way into the dependencies. If | you want the latest and greatest, or want your custum | dependencies checked, you pay. Otherwise it's free. | | I'm quite sure that the market for this is really big. Does | something like this already exist? | Ekaros wrote: | Isn't that kind of antifactory? Still, that also opens up the | question of timely updates to solve possible security | vulnerabilities. | yjftsjthsd-h wrote: | That sounds like a Linux distro with the base OS factored out; | the only difference between that and, say, Debian, is that | Debian is a kernel + core userspace and not just application | libraries. I'm not aware of anything _quite_ like that already | existing, but OS distros are sufficient prior art for me to | think that it could work. | | EDIT: Actually, there _are_ package managers + package | collections that intentionally can be installed on top of an | existing OS; nix /nixpkgs and pkgsrc are probably the big ones. | I'm not 100% sure that those are what you want today, but it's | likely that if you could get maintainers to add your desired | packages they'd be accepted there. | boarnoah wrote: | It also describes software ecosystems like the apache | software foundation, dotnet foundation or even just community | vetting like PHP has with Tidelift (which is a pretty clever | idea on its own) etc... | imdsm wrote: | Myles has a good point about public email to account emails being | different sometimes | (https://twitter.com/MylesBorins/status/1523811989797093376). | There was a way to resolve account usernames to email addresses | through a quirk of the user interface up until last year. | Fortunately, they're really good with dealing with bug bounties | and had it fixed less than week after I reported it. That said, | domain based accounts for something like this is still a big | vulnerability. | | Perhaps something akin to the UK OFCOM amateur radio license | requirement would work, requiring people to update/confirm their | details at least once every five years, or in this case, yearly? | _fat_santa wrote: | One of the problems I see are the super popular holdover packages | before ES6 was standardized on. The tread mentions the `foreach` | package. And remembering back, many previous supply chain attacks | were on these small packages like: `iseven`, `isodd`, etc. | | I don't fully understand why packages like this are so popular. | My guess is it has to be a combo of legacy projects pulling those | deps in and inexperienced developers not knowing that these | features are now part of standard JS. | | While this would cause controversy, I think that NPM should lock | all these dependencies down and not allow any modifications. The | modules would basically be passthroughs to native ES6 | functionality. I'm not saying NPM should lock down all legacy | packages, just the ones that implemented ES6 functionality | (isBetween, isEven, isOdd, forEach, etc) | sdevonoes wrote: | > I don't fully understand why packages like this are so | popular. | | It actually works like this: Author X develops `iseven`, | `isodd`, etc. No one really downloads such packages. Author X | then develops `importantPackage` which does do something useful | developers out here download. The thing is `importantPackage` | relies on `iseven` and `isodd`. Now `iseven`, `isodd` are | downloaded alongside `importantPackage`. Profit. | | My point is, we should recognize certain NPM authors as toxic, | but I guess "freedom of speech/code" stops us from doing so. | Example of such an author: https://github.com/jonschlinkert/ | broken8ball wrote: | This guy would lose his shit if npm locked down his packages. | I'm probably just venting but he's been nothing but rude to | me any time I've opened a legitimate issue on any of the | larger downstream libraries of his. Not to mention, his | Twitter is something else. | mhitza wrote: | At least at some point I've randomly stumbled over a GitHub | account that had published many NPM packages with one-two | function source code. They marketed themselves as a big | contributor to the NPM ecosystem, which was directly based upon | the number of NPM packages published and the number of monthly | downloads. Some packages seemed to take off because people just | do a npm install instead of replicating a one line function, | while others I think were more popular nodejs projects of this | user where they tried to force as many of their own | dependencies as they could. | | TL;DR "SEO" spam to market ones own nodejs expertise, would not | be out of the question | skrebbel wrote: | Hahahhahh isBetween, _why_ | | Compared to that, left-pad is rocket science | daurnimator wrote: | https://github.com/yefremov/isnan | | An entire module for just `return value !== value;` | _Algernon_ wrote: | I'm gonna create a package for isX() for each x in the set | of integers. Please use my packages for all comparisons | from now on. | Izkata wrote: | is-thirteen is six years old: | https://www.npmjs.com/package/is-thirteen | __s wrote: | & ofc there's https://developer.mozilla.org/en- | US/docs/Web/JavaScript/Refe... | jefftk wrote: | Which wasn't everywhere in 2017, when isnan was created: | IE11 didn't (and still doesn't, though it's less | relevant) have isNaN() | | (Not supporting a culture of taking a dependency for this | sort of thing, though) | jaywalk wrote: | Just to be clear, because your comment made no sense to | me: what IE11 doesn't support is Number.isNaN(). It | definitely does support (and has since IE3) plain | isNaN(): https://developer.mozilla.org/en- | US/docs/Web/JavaScript/Refe... | jefftk wrote: | Regular isNaN is very tricky, and almost never what you | want: it first coerces its input to a Number, and then | checks if that is NaN: | isNaN Number.isNaN ----- | ------------ {} true false | [true] true false undefined | true false "{}" true | false | jaywalk wrote: | But none of those things you listed are numbers. The | isNaN output is exactly what I want in pretty much every | case. | jefftk wrote: | isNaN does not tell you whether something is not a Number | either. Applying isNaN to any of these returns false: | null, true, false, [], "", "cabbage". | dr-detroit wrote: | _fat_santa wrote: | Nevermind on that one. I just checked NPM and thankfully that | package does not exist. | krembanan wrote: | ES6 really has nothing to do with isEven and isOdd | jamal-kumar wrote: | truly... those are just modulo operations | aa-jv wrote: | >I don't fully understand why packages like this are so | popular. | | I consider 'iseven' and 'isodd' to be signs that Javascript is | a hellaciously engineered piece of crap that should be avoided | at all costs. They're popular because Javascript _is garbage_. | haswell wrote: | JavaScript supports the modulo operator and the native syntax | for this: let isEven = theNumber % 2 == 0; | | There are reasons to dislike JavaScript, but this isn't it. | The native solution is about as standard as it gets. | jbverschoor wrote: | You're not expressing what you mean by %.. I'm all against | these packages, but in Ruby we have a good standard | library. | krembanan wrote: | It's... the modulo operator | jbverschoor wrote: | Yes. But you're not expressing what you mean. You don't | want the remainder. | | It's like doing a for(i=0; i<items.length:i++) { | e=items[i] } to iterate over each element instead of | something like foreach, or a lambda. | haswell wrote: | Of all the possible examples to choose, I would not have | guessed a classic for/each would be at issue. | | How is that for loop not expressing what it means? for is | used to iterate over something. There are legitimate | reasons to choose for even when forEach is available. | | Does this not express what I mean? if | (amount > balance) return "insufficient_funds"; | | Chances are, I'll put this in a method anyway, and that's | what a language enables me to do - to create meaning that | is contextual to my program. | | Abstraction can help simplify complex problems, and | that's what it is good at. But when literally everything | is abstracted away, it becomes harder to reason about | what the program is doing without also learning about | what the particular abstraction does (e.g. implicitly | handling negative numbers, etc). | | A well implemented standard library can be a joy to use, | and some people choose languages for this reason. Some | languages very intentionally provide a very lightweight | standard library, and that's just fine. All of this | shouldn't absolve the developer from understanding some | of the very basic constructs of the language they choose | - a lack of which will lead to bugs and vulnerabilities. | | If I choose JavaScript (or it's chosen for me), it | behooves me to understand the basics vs. farming this out | to some node package that just made my app harder to | reason about and vulnerable to supply chain attacks for | essentially no value. | ColinWright wrote: | I don't usually get drawn into this, but I have an answer | to this because I've seen something similar in | production. | | jbverschoor said (edited for brevity): | | > _Yes. But you're not expressing what you mean._ | | > _It's like doing a_ > for(i=0; | i<items.length:i++) > { e=items[i] } | | > _to iterate over each element instead of something like | foreach ..._ | | haswell replied: | | > _How is that for loop not expressing what it means?_ | | It's true that the _for_ loop is accomplishing the goal, | but it is specifically running through the elements from | 0 to _length._ | | But sometimes what you want to do is, for example, apply | a function to every element, and the fact that they are | in a structure indexed from _0_ to _N-1_ is not relevant. | Your intent is to do a thing for every element, not to | run down a list doing the thing. | | There is a difference in intent, and using _foreach_ | instead of a _for_ loop quite specifically expresses | that. | | Small examples like this are never convincing, but there | really is a difference between "Run down this list" and | "do this thing for every element". The output is the | same, but the intent is different, and expressing that | intent is important in larger projects. | haswell wrote: | That intent is implicit, and using _for_ or _forEach_ | does not by itself provide enough information about | intent. I agree that using one vs. the other can be a | strong hint. The surrounding code provides the rest of | the story. | | It may be true that running from 0...length is not the | most important part, but it may also be true that I need | more flexibility and control while iterating, and may | still choose to use _for_ as a result. | | But I think we're getting a bit off track (and I helped | get us here...). | | jbverschoor's comment was a followup about the | expressiveness of the modulo operator vs built-in | convenience methods. | | At least in the case of JavaScript, there isn't an | _isEven_ available. If it was, an argument could be made | that using it is more expressive. Since it doesn't, the | argument can be made that the most expressive option is | the idiomatic one. Certain code fragments become | idiomatic for a reason. | | I interpreted the comments about _for_ and the perceived | lack of expressiveness in using it against this backdrop, | and my point was just that _for_ still has a time and a | place. It may be that jbverschoor recognizes this, but I | think the comparison doesn't quite help when examining | the use of modulo. | ColinWright wrote: | I suspect we are largely in agreement. The example is not | necessarily a good one, but I think we agree that the | intent expressed by "foreach" is different from the | intent expressed by "for ()", and while that difference | might not matter, and might not be large, and might be | carried equally by the context, it is real. | | Going back to the original, there is a difference between | "isEven(n)" and "0==n%2". Sometimes (and this is | definitely true in some code I write) there is a | conceptual difference between asking if something is | even, versus asking if it leaves a remainder of 0 upon | division by 2. Yes, they can be proven to be equivalent, | but the underlying intent is different. | | BTW, I agree entirely that in these cases it's really | mostly pointless, but the principle carries over to | larger examples. Trying to see that there is a difference | is probably worth it, even if we agree that it doesn't | really matter in these trivial cases. | | Oh, and for a compiler I used to use it really did matter | that you used "foreach" when you could, versus using "for | ()", because it could dispatch things in parallel in the | former case, and couldn't in the latter. So expressing | the intent in the code itself and not just in the context | really can matter. | haswell wrote: | I'm a big fan of Ruby and yes, Ruby handles this | elegantly. | | However, some variation on n%2==0 is idiomatic in a large | number of languages, both modern and old [0]. | | This includes Lua, Java, Python, Scala, Perl, PHP, Swift, | and many others. | | It is true that there are numerous languages with built | in convenience methods in their standard libraries, but | that does not by itself mean that n%2==0 is problematic | and certainly this idiom is deeply entrenched. | | There is nothing preventing a developer using those | languages from wrapping this in a function, and indeed | this is probably a good idea if it's something you find | yourself using repeatedly throughout your code base, just | like any other often-repeated code snippets. | | - [0] https://www.rosettacode.org/wiki/Even_or_odd | russtrotter wrote: | The old C bum in me says this should really be a bitwise | AND with 1 but I'm sure modern compilers and JS JIT/V8 | runtimes optimize MOD 2 to the same. | repiret wrote: | I spend most of my time writing C for embedded systems. | You should focus first on making life easy for the people | reading your code. Use `% 2` and `* 4` when those are the | things you mean, rather than `& 1` and `<< 2`. Compilers | have been able to do those strength reductions on their | own for years, and in most cases even if the compiler | didn't, the cycles you'd save aren't worth it. | leodriesch wrote: | I don't get why anyone would introduce a dependency this small | to their codebase. | | It's a much better choice to just copy the source code and | possibly license into your own code to just eliminate the | overhead. | | It's not like any of these packages depend on being updated for | security reasons or anything. | duxup wrote: | I find that I do that more often now than ever. | | Most times I get the urge to pull in a rando package I find I | really only need a few things it does. I check it out. Read | it. Write my own. | | I almost never need "all the things" outside the situations | where I am using a big framework. So reading it, getting | inspired / ideas from someone who did the thing and then I | write a much more narrow focused version for myself. | megous wrote: | And you can easilly add the features you actually need. :) | Merad wrote: | 4-5 years ago (when the popularity of node was skyrocketing | but es6 was still relatively new) I remember some people | arguing passionately that it was good to maximize code reuse, | i.e. better to pull in a package with one utility than to | write 5 lines of code in your own application. I think it was | mainly a symptom of the gaping holes in javascript's standard | library... thankfully that attitude seems to have mostly died | off. | chrisfosterelli wrote: | At risk of criticism, I'll bite. I used to think this way and | include a lot of small dependencies in most projects I worked | on. | | The thinking was as follows: Of course you could just copy | the code, but then that increases LOC in my codebase that I'm | responsible for. More code is more work. Lines in a | dependency are the responsibility of someone else. If there's | a bug, even in a small function, the community can identify | it and fix it. I can get new features I might not have known | I needed. I can benefit from all of these fixes indefinitely | into the future without ever having to have any mental | overhead about that code. So can everyone else; it's good to | maximize code reuse. | | I don't think I've ever used something that could be an | obvious one-liner like `isOdd` but for lots of only slightly | more complex stuff like left-pad, email format validation, | GPS coordinate math functions -- all stuff that's really less | than 30 lines -- it was really nice to just not have to think | about the implementation details of that and get back to | solving your problem. I could have reviewed the code or | written it myself but it's just more work when remaining at a | high level `leftPad()` call let's me stay focused on my | original task. | | That said, I've since realized I was wrong of course. Trying | to maintain projects that haven't been touched in more than a | year led to hours of fixing dependency issues. We switched to | using dependabot, which is better, but just makes it obvious | how much work it actually is to keep dependencies up to date | week-to-week. Then there's all of the security issues. These | days, for small packages, I advocate for reviewing the code | from these packages, ensuring we understand it, and then | copying it in directly with a comment for attribution. We | generally try to keep dependencies low; still more than in | other languages but at least some thoughtfulness about | whether it's "worth it". I think a lot of the community has | shifted similarly, but there's still a lot of older projects | with older dependencies. | pilif wrote: | _> Of course you could just copy the code, but then that | increases LOC in my codebase that I 'm responsible for._ | | Once your company is owned by a supply chain attack or by | an RCE in one of your dependencies, you will learn that you | are in-fact very much responsible for the code in your | external dependencies. | tylersmith wrote: | This drives me crazy. If your software is using a library | that library is part of your software whether you | originated its code or not. If you are responsible for | the software then you're responsible for the LOC in every | library your software depends on. | remram wrote: | > possibly license into your own code | | This can be complicated. Depending on another package is | usually very safe, at least as safe as "dynamic linking", but | including code in your own source tree needs licenses to be | compatible. Even then, you might have to change your license | to "BSD-3-Clause + ISC" or similar composite and you will get | complaints from users. | bin_bash wrote: | I think a lot of it is from a single engineer: sindresorhus | | He's a prolific open source author that traditionally had a | lot of modularization in his packages--though I think he has | started to move away from it recently. He talks about it | here: https://blog.sindresorhus.com/small-focused- | modules-9238d977... | | Most projects will include at least one package by him in the | dependency tree. | nobleach wrote: | For years, the bane of my existence was always lodash. | Import one tiny utility and it brings along 15 of its | closest friends. You can't get away from it. It was built | so incredibly modularly, that it has to import a bunch of | other things. Now most folks will quickly rush to its | defense and tell you that Webpack should be able to tree- | shake it well enough. My actual experience is that it was a | tremendous waste of my customers' bandwidth. Seeing LoDash | as a dependency of anything I use is an immediate NOPE for | me. I've yet to see anything it provides that I couldn't | just do myself. | | It's an unpopular opinion for some silly reason. It's like | when Guava or Apache Commons was included on every single | Java project in the 2010s. "It's just so much easier to use | a well-tested library". That line of thinking is what got | us here. | sanitycheck wrote: | I'm the opposite, I tend to be relieved when I see lodash | as a dependency. In any normal sized project I'm probably | already using it, or it's already a dependency of a | dependency. I trust it a lot more than a hundred tiny | libs by random authors, both in terms of sketchy | behaviour and reliability/performance. If I need to | target platforms which don't support modern JS I vastly | prefer to stick to lodash than use a bunch of polyfills | of unknown quality. | | The individual functions are installable separately from | NPM, and lodash-es should tree-shake quite well, but I do | know what you mean about it dragging in its internal | dependencies so you end up with a 15kb of lodash code for | a single thing. I probably wouldn't love to use it | client-side on an ordinary website, were I to make one. | sanitycheck wrote: | Funnily enough, I was just digging through my current | project's dependencies and he's slipped in via a Rollup | plugin which uses his "globby" package, which in turn uses | his "slash" package.. Slash is about 5 lines of code, which | is roughly 4 more than most people need for what it does. | | I vastly prefer to use libraries with 0 dependencies but I | never quite manage it, so I end up with the same problems | as everyone else. | thatwasunusual wrote: | > I don't get why anyone would introduce a dependency this | small to their codebase. | | This might be controversial, but I think it has to do with | less experienced developers, beginners, who doesn't know how | to find out via "pure code" if a number is even or not, or | even if something is a number (IIRC, there is an isNumber | package out there as well). | | I see this in other languages as well, but not in a | "JavaScript scale", but that could probably just mean that | the language's availability and popularity decides the number | of "stupid packages." | ZetaZero wrote: | If a developer doesn't know how to write their own | "iseven", I don't want their product. | | Maybe you could argue other for other reasons to use these | packages. | haswell wrote: | I suspect a lot of this use doesn't go into products, it | goes into projects. | BigJono wrote: | Let's call a spade a spade. It's a bunch of noobs that have | become the majority and created a culture of dependency- | first development. | | I haven't worked with anyone for years that doesn't start | troubleshooting an issue by reaching for a random | dependency. They just don't even bother learning Javascript | or the Web APIs or CSS anymore. Without a solid base of | fundamentals every trivial problem seems insurmountable so | they just don't even try. | ratww wrote: | If we're going to call a spade a spade, then let's go | ahead and say that the majority of the packages that are | always referenced in those discussions (is-even, is-odd, | etc) is maintained _and primarily used_ by a minority of | developers that are very well known in the ecosystem. | | This minority makes money out of their popularity in the | NPM ecosystem. Having 1000 NPM packages is better for | your reputation than having 100. And having all 1000 | packages with lots of weekly downloads is better than | having just a portion of that. | | But how do they achieve that? Well, they have 1000 NPM | packages, so each one depends on 5 to 10, that then | depends on a few handful more. You have packages for | checking if an HTTP status is a certain number, you have | packages that have colors as constants, you have is-even, | is-odd and so on. All that exists to maintain that closed | ecosystem. | | So out of the 1000 they basically have 20 useful tools | and 980 garbage packages that exist only to maintain | their own ecosystem. | | Most people isn't using is-even or is-odd directly. They | imported some other packages that are quite useful, but | often need 10-20 sub-dependencies. Another interesting | thing is that those shitty packages aren't really that | important in applications. They're often used in build | tools, CI and testing, tools for making CLI tools, and | the sort. | | The crazy thing is that a lot of people using is-even/is- | odd aren't really "noobs": they're probably experienced | developers that said "fuck it, I'll use some random tool | from the web" when facing some random a problem. | cobertos wrote: | A few developers will register multiple packages that are | essentially the same package with small tweaks. They | choose the names in a way to get the right keywords to | hit from npmjs's search | bostik wrote: | > _Having 1000 NPM packages is better for your reputation | than having 100. And having all 1000 packages with lots | of weekly downloads is better than having just a portion | of that._ | | Should we treat them as spammers and polluters, then? | Because if what you describe is true, that deserves to be | called out and mowed to the ground. | ratww wrote: | Definitely. | | It is more akin to SEO spamming than black market | spamming, though. They're polluting NPM in the same way | SEO farms spam Google. It makes life difficult for | everyone, but it's still a gray area in terms of | legitimacy. Which is why nobody really talks about it. | sdoering wrote: | I don't know if this is true, but if it were true you'd | have a veritable "tragedy of the commons" [0] situation | were privatization of (some) gains leads to the creation | of negative externalities for the rest. | | If incentives were aligned differently, different results | might have resulted. Probably with different | externalities (or unintended consequences). | | [0]: https://en.wikipedia.org/wiki/Tragedy_of_the_commons | ?wprov=s... | thatwasunusual wrote: | > Most people isn't using is-even or is-odd directly. | They imported some other packages that are quite useful, | but often need 10-20 sub-dependencies. | | IMO, that's even worse, because that means that a lot of | people are using stupid and vulnerable packages without | knowing it. | | I wish there was some sort of better control over the NPM | directory, where someone could block/downvote (or | whatever) packages that doesn't deserve to live. How this | would - or should - work in practice, I have no idea, but | it's just getting scarier by the day to import a package | in your application. | ratww wrote: | The problem is that those fame-chaser maintainers aren't | the only ones doing it. Babel does it. Webpack does. | ESLint does it. Before them others did. | | If we ban those, we'd have to ban Babel and Webpack | too... Oh now, wait a minute, now that actually sounds | interesting... | Tainnor wrote: | That's a more charitable (and more reassuring) | interpretation than "developers don't know the modulo | operator". | | That said, it still leaves a sour taste as this | effectively implies that a certain set of JS developers | is very happy to abuse their (maybe initially rightfully | earned) prestige to gain even more prestige while leaving | behind a mess for the whole ecosystem. I don't understand | why this is tolerated. The Node community needs to have a | serious discussion about why certain packages are allowed | to spread garbage, create forks of the relevant packages | that rip out "is-even" etc. and then eventually converge | to these forks. But to this day, I don't see the | community taking this problem seriously enough. | | Now, supply chain attacks and "too many dependencies" are | a potential issue for every language with dependency | management (see also log4j, etc.), but no other ecosystem | seems to be have such a high frequency of issues and | (widely used) "is-even" packages are simply not a thing | in any other mainstream language (some languages, like | Swift, include similar functionality in the standard | library, which is totally fair). | ratww wrote: | The reason it is tolerated is because the philosophy of | "thousands of small packages" has spread far and wide. | | For every person calling it out like we're doing here, | there are ten others praising maintainers able to whip | ten semi-useless packages per week. | | It's not just random maintainers making small packages. | The core infrastructure of Javascript is in it. Babel is | made of hundreds of packages, which all live on the same | repository (because of course the maintainers don't want | the hassle of maintaining multiple things). Some of those | packages don't even have _anything_ of importance in it, | just metadata, a couple flags and some boilerplate [1]. | The package is just a way of organizing code. Webpack, | ESLint and others aren 't exactly better. | | EDIT: And of course I got downvoted :) | | [1] | https://github.com/babel/babel/blob/main/packages/babel- | plug... | cxr wrote: | You're tacitly giving the people you despise leverage | when you say things like: | | > The core infrastructure of Javascript is in it. | Babel[...] | | Babel is not core JS infrastructure. It may be close to | fundamental to the modern NodeJS development experience, | but JS exists happily (and _capably_ ) without any of | that stuff (including package.json, for that matter). | ratww wrote: | Fair enough! True, Babel is only "core" for a subset of | JS developers, not for the language. | | I don't really despise anyone in Babel, though, I'm only | criticising their packaging method. Babel isn't doing the | million-packages thing to gain popularity. | zzyzxd wrote: | Comparing to: | | 1. search for a package that does X | | 2. scan the search result and find the package that really | does X | | 3. learn to use the package's API | | 4. import the package in the code | | 5. use it | | Isn't it much easier to just copy-paste code from | stackoverflow? There's also a good chance that the you can | get some very good explanation and interesting discussion | around the implementation there. | ratww wrote: | Well, yes. | | There's also Github Copilot, which pretty much replaced | almost my entire usage of Stack Overflow. | | But the thing is that with a rando package is that one | doesn't have to review the code. Sure, the code is also | coming from somewhere else. Sure, it might never get | updated. Sure it might be full of bugs. Sure, it might be | more dangerous than copying from StackOverflow. But out | of sight, out of mind. | | In the end the overuse of packages isn't about saving | time or "doing the best for business" or "ensuring that | the code is maintained by someone else". It's purely | about covering our asses. | Vinnl wrote: | Generally, I don't think they're particularly popular, but a | package that _depends on them_ is popular. Or in fact, a | package that depends on that package (that depends...) is. | freeqaz wrote: | This page just shows an empty white page for me on mobile Safari. | Is the site down? Does anybody have an archive link? | ColinWright wrote: | Try shrinking it, searching for text, or scrolling. It's a | chart, and a small part of the top left corner is empty. | freeqaz wrote: | Thank you very much! | getcrunk wrote: | Is there an easy tool maybe something for ${bundler} to take your | package.json and rewrite everything to refer to static versions | hosted on your own cdn? | | At least that way upgrades, malicious or otherwise are opt in for | production | | The other thing would be ideally a crowd funded resource to vet | particular versions of popular packages. | TAForObvReasons wrote: | For NPM use https://verdaccio.org/ . It can proxy the public | registry. Install your project and it will pull and cache the | dependencies. Once cached you can remove the uplink and it will | only serve the cached version | buzzwords wrote: | I see a lot of comments here pointing to new/inexperienced | developers. As one of those guys, I have to say JS community is | not that great at keeping blogs/docs/tutorials up to date. Take | react for example the learning section is quite out of date and | no one develops using classes anymore. | baisq wrote: | The only thing I take away from this is that you should not use | custom domains for your email, at least for important stuff. | 3np wrote: | ...or just make sure you keep them under your control...? | | Losing access to an account at a major mail provider seems more | probable than losing control of a domain you paid for. | KMnO4 wrote: | Eh, it happens. I pay over $200/year for my domain + GSuite. | It's a luxury I enjoy, but a luxury nonetheless. | | If I couldn't afford that anymore, I'd probably go back to | Gmail. I'd probably think to switch over many of my email | addresses (for services that I use), but some may slip the | cracks when the domain expires. | SuperCuber wrote: | How much does your domain cost? Most TLDs cost under $20, | and GSuite costs like $60 a year... I pay like $60 for | domain + mail combined (with fastmail) | lrvick wrote: | I checked the password-reset flows for most major NPM | contributors that use regular webmail accounts like Gmail too. | | < 10% had useful 2FA enabled. Most were just password reset | questions or had a backup email to some old expired and re- | registerable forgotten earthlink accounts etc. | | I do this stuff all the time. I looked up the password reset | questions controlling the zoom.us domain 2 years ago and | collected an insulting $200 bug bounty for it. Zoom, like NPM, | didn't do signed binaries, so this would have been brutal | combined with other issues I found. | | The solution is what all sane OS package managers do: code | signing. | | NPM has rejected this at least as far back as 2013 when they | refused a PR by someone that implemented it for them: | https://github.com/npm/npm/pull/4016 | | I don't know what else to do but keep publicly trolling them at | this point until code signing is implemented. Unsigned code is | a free pass for remote code execution when an account gets | taken over. | | Meanwhile Debian maintains hundreds of signed nodejs packages | proving it is very doable by a low budget team. NPM seems to | just want to reduce deveopler friction at all costs :/ | pimterry wrote: | Doesn't really even need to reduce average developer friction | - they've proven a few times that they're happy to add extra | security requirements just for publishers of high-visibility | packages. | | "Once you cross 100,000 weekly downloads, all new publishes | must be signed" would keep the easy on-ramp for small | packages but dramatically reduce the risk of major attacks | against all the big targets (like the example here). | | Not as good as signing everything, but a good start that can | be iterated on later. | JackC wrote: | The question in that thread, and this later thread,[1] is how | to know which keys are valid to sign a package. | | For example: I go to release a new version and I've lost my | private key, so I roll a new one -- this will happen often | across npm's 1.3 million packages. Do I then ... log in with | my email and update the private key on my account and go | about my business? What process does npm use to make sure my | new key is valid? Can a person with control over my email | address fake that process? How are key rotations communicated | to people updating packages -- as an almost-always-false- | positive red flag, or not at all, or some useful amount in | between? If you don't get this part of the design right -- | and no one suggests how to in those threads -- then you're | just doing hashes with worse UX. And the more you look at it, | the more you might start to think (as the npm devs seem to) | that npm account security is the linchpin of the whole thing | rather than signing. | | It's not just npm; that thread includes a PyPI core dev | chipping in with the same view: "Lots of language | repositories have implemented (a) [signing] and punted on (b) | and (c) [some way to know which keys to trust] and | essentially gained nothing. It's my belief that if npm does | (a) without a solution for (b) and (c) they'll have gained | nothing as well." It also has a link from a Homebrew issue | thread deciding not to do signatures for the same reason -- | they'd convey a false expectation without a solution for key | verification.[2] | | [1] https://github.com/node-forward/discussions/issues/29 [2] | https://github.com/Homebrew/brew/pull/4120#issuecomment-4068. | .. | dane-pgp wrote: | > What process does npm use to make sure my new key is | valid? Can a person with control over my email address fake | that process? | | It seems there should be some multi-factor process. | | Developers need to register a password, an email address, | and a YubiKey/TOTP token. If they lose access to the email | address, they can log in to their account with the password | and token. If they lose the token, they can be issued a new | one with the email and password (or recovery codes). | | As long as the account stays secure (i.e. an attacker | doesn't manage to keylog the developer's NPM password and | email password) then the NPM account can be trusted to add | new package signing keys. The npm client then needs to | trust metadata from NPM which vouches for these new keys. | lrvick wrote: | Debian already maintains hundreds of signed NodeJS packages | using classic PGP web of trust, with a team of volunteers | that lack NPM microsoft money. I don't understand how NPM | has any excuses at this point | | The web of trust PGP signing approach works reasonably well | to protect most linux servers in the world since the 90s. | You can complain about it and say there should be a better | UX toolchain for it, and I would agree with you. Thankfully | the sequioa-pgp team has made huge progress here and it is | a shame they are not getting due support for their heroic | and near thankless efforts to make this better. | | Still, even with todays GnuPG tools, abandoning pgp for | supply chain integrity and replacing it with nothing is | crazy. Imagine if we abandonded TLS because early | implementations sucked. Use the best tools we have then | fight to make them better. That's just good engineering. | | The software eng commuity at large basically said "Look we | just stopped signing code and nothing bad happened... oh | wait bad things are happening. Too late to change now!" | | This was a reasonably well solved problem, but entities | like NPM will need to have the humility to admit that | rejecting best effort cryptographic authorship attestation | was a mistake. | UncleMeat wrote: | You could make it optional and never permit key updates. | Then downstream users could decide to only depend on signed | code. The downside of this is some people will lose their | keys and never be able to update a project ever again. The | upside of this is that businesses that prioritize this can | be more confident that an account takeover isn't shipping | them evil code. | yjftsjthsd-h wrote: | For all that people love to hate it, GPG's web of trust | could cover this. Lost your key? That's fine; go convince a | dozen peers that that's what happened and you're really you | and they'll cross-sign your new key. | sofixa wrote: | Is code signing really a solution here? It seems more like a | bandaid to me, because someone without MFA on their account | probably also doesn't have the best security around their | code signing. In any case, isn't it often handled by CI/CD? | If you get access to the developer's account, you can release | malicious code, dutifully signed? | XorNot wrote: | Technically what's needed is attestation: I don't care if | the author signs it, I care that trustable third parties | have reviewed it. | | Most people would have no problem marking a couple of big | firms and orgs as trusted reviewers and only showing | packages to be used if signed by them. | jka wrote: | To be honest, rather than magical blessed keys held by a | few orgs, I'd feel more comfortable with a slightly | larger number of individual reviewers (and prosaic keys), | each with some kind of visible distance metric related to | the codebase they're signing artifacts for. | | For example: "ah yes, a core contributor, a frequent code | reviewer, and two downstream consumers of this library | have signed off on the changes in this release. even if | one of them is having a distracted day/week, that's good | enough for our team to be comfortable upgrading it today | since it's a minor version upgrade" | jacques_chester wrote: | What folks call signing is, if you step back, basically | another kind of attestation. It's an attestation of | authorship. | jacques_chester wrote: | > _< 10% had useful 2FA enabled._ | | I expect this to change. NPM will roll out mandatory MFA for | the most-downloaded packages[0] (RubyGems as well[1]). I | expect this will rise to a 100% requirement at some point | because Github's decision to require MFA by the end of 2023 | will massively raise the waterline of folks who have the | capability to MFA and experience with MFA. | | [0] https://github.blog/2021-11-15-githubs-commitment-to-npm- | eco... | | [1] https://github.com/rubygems/rfcs/issues/35 | dncornholio wrote: | > I don't know what else to do but keep publicly trolling | them at this point until code signing is implemented. | | I don't think your trolling is doing you any favours anymore | (sigh, that guy again). Kicking a dead horse etc. Maybe just | let it go? | merlinscholz wrote: | Yes, better use Gmail and loose your whole account in a few | months/years | baisq wrote: | Yes, it's better that your account gets locked and everybody | loses access to it than it is to allow someone else access | it. | seanwilson wrote: | > Buy expired NPM maintainer email domains | | How do people manage selling or changing a domain they've been | using long-term as their primary email address for sign-ins like | this? To stop a new owner of that domain from taking over | accounts sign-ins that use that email address, you'd need to | reliably update all your sign-in details with anything you've | signed up to? | | You could use a password manager to track everything you've | signed into before to help with this but that's error-prone. | | Alternatively, this forces you to keep paying for the old domain | indefinitely? | moritonal wrote: | Yes, that's exactly what you have to do. There's no way to raze | land on the internet. | readmorebooks wrote: | This also highlights how often developers seem to ignore | mortality. When a person expires, soon will their domain | registration follow. | cheshire137 wrote: | The link just loads a blank white page for me on mobile. Would | have preferred a direct Twitter link. | finiteseries wrote: | Scroll ~1000 pixels to the right and then zoom out 10x so you | can click a node, skip the weird diagram, and just use Twitter. | ColinWright wrote: | As it says elsewhere in this discussion, it's not just a blank | white page. | | Try scrolling. Or searching. Or scaling. | | There's a chart there, and you can scan the entire thread, or | just click on a node to go directly the the tweet you want to | see. | krono wrote: | The chain of trust is a lie, external dependencies are as much a | trade-off in security risks as they are in production cost, and | your belief in the good intentions of a person/entity does not | shield you from their unintentional mistakes or oversights. | Sephr wrote: | NPM is a shitshow. At one point you could literally take over | people's packages by asking the NPM staff nicely. | | Source: https://twitter.com/sephr/status/1524080664106086400 | dr-detroit wrote: | WesolyKubeczek wrote: | Now I want this to be the default twitter ui so much. | azemetre wrote: | I found it very confusing, is the chart trying to be a | timeline? | noway421 wrote: | I think the main thread is on the left with the reply/qt sub- | trees on the right. You can only read the first column. I | quite like the layout, if there's only 1 main thread that i | need to be aware of it's quite nice. This layout probably | won't work if there's more than 2 people in a conversation. | | The layout is actually not that much dissimilar from what | twitter already has, just more info from non-main threads and | better visibility for orphan leafs. | coffeeling wrote: | It tries to map the entire tree in one view. | ColinWright wrote: | At the time the snapshot was taken that _was_ the entire | tree, so it doesn 't just "try", it succeeds. | ColinWright wrote: | No. | | The chart in all forms (there's more than one) shows each | tweet as a node, and arrows showing which tweets are replies, | and which tweets are "Quote-Tweets". | | If A->B, then B is a reply to A. | | In this particular version I've taken the longest thread and | laid it out on the left, allowing the other descendants to | flow to the right. Another layout is to have the initial | tweet at the top and lay it out as a simple tree (technically | DiGraph), but that often leaves the top left corner empty, | leading people who initially open it to think it's empty and | close it without scrolling. Yes, they do, that's happened | before here on HN, including in this discussion. | | Does that help? Are you still confused? It's just a chart | showing tweets, quotes, and replies. | perihelions wrote: | Do you happen to know what tool made this? Is it just | Graphviz? | ColinWright wrote: | I wrote a script to pull the thread recursively, reformat | it into a DOT file, feed it to GraphViz, and upload it. | perihelions wrote: | Thanks! (I didn't realize you were the author). | ColinWright wrote: | You're welcome. | | I have several tools that do this sort of thing, | including a 'bot that can be invoked automatically on | mastodon. I don't do that on Twitter because popular | discussions get seriously out of hand ... there was one | that I stopped tracing after if got to 3500 tweets. I | have some heuristics in mind to help control that, but | it's all still very experimental. | | I also have a pig-ugly, pre-alpha, bug-ridden discussion | system that works directly on a DiGraph, but when it was | submitted to HN sometime ago reactions were ... | (significant pause) ... mixed. | hyfgfh wrote: | Non-essential dependencies are for the weak and every single | company that I worked for. | ColinWright wrote: | Yes, I know, some of you will hate the layout with a passion. But | this kind of diagram is the only way I can make sense of the | back'n'forth that sometimes happens. | | If you prefer Twitter's rendering then just click on a node and | that tweet will open for you. | | _Edited to fix a typo ... thank you Jonn. Oh how I hate auto- | corrupt._ | akkartik wrote: | What do you think trn/slashdot/HN-style threading is lacking? | ColinWright wrote: | Any kind of sense of where I am in a discussion. | | If you find the trn/slashdot/HN-style threading better than | the 2D graphical layout then I doubt I can explain to you why | I find it (the threading) lacking. | thinkingemote wrote: | I like it. The spatial element gives some pointers towards | order in time too. I think ordering by importance (most quoted, | replied) takes precedence. | zwp wrote: | This old dog is reminded of trn(1), "threaded read news". | | See top right: https://upload.wikimedia.org/wikipedia/commons | /d/d8/Trn_cons... | shagie wrote: | That does bring back memories... and would be a nice way to | visualize Twitter. | Zealotux wrote: | I enjoy this layout and I only wish it had some sort of check | for background color contrast accessibility. | ColinWright wrote: | Yeah, the colours are a complete hack. There are _so_ many | things this needs to make it more usable, but I have neither | the time nor the skillz. | shabbyrobe wrote: | I love this visualisation. Is the script to generate it | publicly available? | ColinWright wrote: | Currently not, there are significant problems that I'm trying | to solve before making it available. No, I'm not trying to | make it perfect, but I'd like it to be actually usable before | opening the code. | skulk wrote: | Your algorithm to embed a graph in 2D is intriguing: | https://i.imgur.com/7xhl7VY.png | | What kind of curve is this? | ColinWright wrote: | It's just using GraphViz. | 1970-01-01 wrote: | I find the diagram very easy to quickly understand everything. | Well done! Haters gonna hate no matter what you do. | junon wrote: | Actually prefer this to Twitter. Easier to read. | ColinWright wrote: | It is until the discussion gets really big. When there are | several hundred tweets there's no good way to layout the | graph. Then you need folding, but even then, folding in the | 2D environment gives you a much better sense of the | discussion. | ratww wrote: | To be fair, when there are several hundred tweets involved | it's even more difficult to to follow on Twitter. Your | format is better. | 3np wrote: | I don't suppose the source that generated it is available? :) | ColinWright wrote: | Not yet ... working on a few issues. | darepublic wrote: | What I would like essentially a curated npm, es and esm modules | only and some other rules better vetting packages and their | dependencies. At first almost no existing npm packages will be | suitable to make the migration but I expect with just a bit of | work and automation we can migrate over versions of the behemoths | as well. Working with this package manager your builds can be | simpler because you only deal with and target es modules. goodbye | common js! goodbye leftpad! see you in hell!! ___________________________________________________________________ (page generated 2022-05-10 23:01 UTC)