Hacker News new | past | comments | ask | show | jobs | submit login
Installed electron / react, it has 1861 dependencies. This is a problem (twitter.com/colineberhardt)
76 points by ColinEberhardt 4 months ago | hide | past | favorite | 83 comments

I don't really see the size of it all, or the dependency count, as a problem considering what Electron+React are doing. It's a modern framework with its bundler, plus a browser engine with a bunch of wrappers for interacting with different OSs, and all the tooling necessary to build apps for Windows, OSX and Linux. That's akin to downloading the salient parts of Xcode, Visual Studio, and gcc and complaining about how many dependencies they're all built on. That probably runs into the tens of thousands. Modern software has many moving parts.

The wall of warnings, deprecations, messages, errors you can apparently ignore (fsevents and iltorb, I'm looking at you) is the real issue for me. I want confidence in what I build, and NPM does not give me very much at all. I'd be fine downloading 1861 packages if they all worked together properly without telling me there might be problems.

PS Colin - I think we've met a few times in the Town Wall long before lockdown. Hello from the other person on HN in the NE. :)

It's a huge problem because when you consider what it's really doing (what people want from it) it's not much.

All people want from Electron is a GUI system that works on all platforms. In theory there are several libraries that do that but they lack the features people want (QT, GTK).

In a sane world, it will be a single dependency: the GUI library.

You have to be careful when you consider what the system is doing before you justify its complexity. It might be doing a lot of useless work.

For example, what does webpack do? esbuild has proved that webpack is useless and spends its time doing useless work. Bundling with esbuild takes a fraction of a fraction of a second, where as webpack can take anywhere from 30 seconds to several minutes. Yea, it's doing "work", but it's not the work you actually want to do.

All people really want from Electron is the render engine from Chromium and the V8 JS engine, but without the sandbox, so that it can access the file system and do a few other things.

How many of these hundreds of dependencies are contributing to that end? Very very few, if any.

The "modern" web frontend development environment is really bad. Making excuses for it does not help.

> All people want from Electron is a GUI system that works on all platforms

No. What those people want is web tech as a GUI library. That's two very different things.

A cross-platform GUI library with good customization and theming options and support for custom controls that isn't reliant on the (Google) Web Specs (w3c) is what's really missing from the ecosystem.

JavaFX meets that requirement.

A GUI app that uses JavaFX requires exactly one dependency: the GUI library itself (OK, JavaFX is split into a few different modules). Often you'll add a few open source helpers, e.g. if you want a Material Design theme.

> A GUI app that uses JavaFX requires exactly one dependency: the GUI library itself

... and Java.

Yes, that's true. A minimal runtime can be quite small by modern standards (~20mb) but it's not free indeed. Only C or C++ can be "dependency free" in this regard because it's the only languages where operating system vendors are guaranteed to ship the standard library with the OS. All others have to bundle.

Go is better in this regard because it doesn't even expect much from the OS: everything is bundled.

These days you bundle everything with Java apps too. Or at least that's the direction the JVM authors want people to go in (see: jlink and jpackage).

It's not a single binary like Go, but in practice that's rarely an issue. Most normal programs have more than one file making them up.

Chromium also comes with a lot of API's, for example webGL and WebRTC.

That's not necessarily a good comparison. Electron comes as a binary, so it already has all its own hundreds of dependencies integrated.

The dependency hell wit JS projects is real, and upgrading can become a major timesink and pain if you are not maintaining and upgrading the project constantly.

There also exists a surprising amount of ridiculously unnecessary packages that many worthwhile ones depend on.

One such example is `is-odd` that is hovering around 500k weekly downloads https://www.npmjs.com/package/is-odd

On that page there's a related project called is-even . I pray for maximum laughs that is-even depends on is-odd, and just negates the return value of is-odd...

Edit: it actually does! Hah!


It's even worse in this case. Following the Github link, you'll get to an archived repository inside an org that the author created as a joke. In his own words: 'This is a joke. You'll only see this org if you are attempting to troll me about repositories I created when I was learning to program.'

It got in there and is now part of the foundation of tons of other projects.

Maybe it doesn't matter but at the very least this ecosystem seems very immature (in the psychological sense).

There was a lot of discussion about this when left pad broke the internet. One of the arguments for it was that it’s easier to reason about what a one line module does.

Until you have 2000 of them and can no longer reason what the system does or what the interactions between them are.

What definition of ”dependency” are you using to estimate that GCC has tens of thousands?

gcc alone doesn't. xCode, Visual Studio, and gcc probably do. Although I don't really know that for sure.

Okay, but still thousands for gcc then?

I bundle and distribute GCC for an OS distribution and I can count 5 dependencies for building GCC from source (not including a host toolchain), two of which are also runtime dependencies. That means if you're installing GCC, you also need to install binutils and a C library. GCC itself, of course, bundles a number of dependencies like the gcc toolchain driver, the cc1 and cc1plus compilers, the collect2 linker front-ender, plus a number of runtime libraries both for the toolchain and for bundling into the executable. If you're targeting C++ that adds a couple more runtime dependencies which can optionally be bundled with GCC. Of course, everything also depends on the host runtime.

Some OS distributions split GCC into multiple packages with interdependencies, putting for exaple the C preprocessor into a separate package from the compiler proper (which is odd, considering it's the same executable, but there are historic reasons).

So, an exact number of dependencies for GCC, depending on how it gets packaged for your development host, can range from 3 to 14 or 15.

Certainly not. I barely remember my LFS school project, but I don't think i installed more than a dozen libs for the second Gcc compilation (the one w/o the host system). And half of those libs were used for "make test".

I guess any individual function defined outside of main() can be considered a dependency, the question is just whether it's you or someone else who's in charge of maintaining it

You are correct that in Node.JS a module is just a function that can be re-used in more than one app. But as making a module is the only way to separate your code into several files and folders in Node.JS - Node.js developers also make "modules" that can not be re-used in other apps - so while one app depends on them, other apps can't depend on them and they are not published on the NPM registry... One cool thing about Node.JS modules is that you can import/require them inside main! So whether or not a function is in main or not only says how the developer likes to structure/place the functions. It's rare, but the best programmers I know likes to have all "dependencies" inside the same file - so basically they do not use any dependencies ...

> I guess any individual function defined outside of main() can be considered a dependency

No its not. I don't think even people naming their object list "DEPS" in their makefile don't think object files are dependencies.

Dependency count isn’t a good measure because different ecosystems have different default sizes to split something out.

Number of unique maintainers, on the other hand, is more consistent across languages and represents a real risk re supply chain safety, since compromising any maintainer is a route to a hack.

> Hello from the other person on HN in the NE.

Oh wow, small world! Looking forwards to returning to the Town Wall at some point in the future.

Continuing my morning rant on here a little ...

I'm an experienced developer, I have a pretty good ideas of what these boilerplate projects are trying to achieve. However, at the moment I'm helping Python dev get up-to-speed with web development.

They are creating a desktop app, and wanted to use MS FluentUI, a React UI component library.

I'm now trying to teach them JavaScript, webpack, TypeScript, React, ESLint, ... Help them resolve dependency issues. Explain bundlers, the various different module systems ... the list just keeps getting longer!

> I'm helping Python dev get up-to-speed with web development. They are creating a desktop app, and wanted to use MS FluentUI, a React UI component library.

Creating a desktop app isn't web development, it's desktop app development.

You've got to teach web dev from the basics outwards. We (developers) have taken a platform for "document" delivery and layered it with tools for app development. Teach it this way. Start with simple content - including a little style, enough layout to get going, some rollovers or form helpers, and basic accessibility. Then talk about templating (static sites, or server-side apps). Then talk about single page apps. Then talk about desktop apps.

What is it with modern frontend development that people think you can just quickly "get up-to-speed" with it? Nobody would accept these complaints of complexity had you said "I'm just trying to get these web developers up-to-speed hacking on the linux kernel", they would advise you to start them on something simpler, to get to learn the languages and tools gradually.

I agree there's more complexity than there should be, but you also dump them in the most complex stack that can be dreamed up in the field.

Various swathes of programming benefit from being able to make use of abstractions that hide details.

e.g. embedded development is difficult, but Arduino makes starting out more accessible. Beginners are able to get an LED blinking on a development board without needing to understand all the details.

While expecting to fully comprehend all the complexities of some unfamiliar system is unreasonable, I think it's reasonable to hope for a development experience where what you need to know to be able to contribute is covered by a small surface of well-made abstractions.

Why not use QT with Python? Why include Typescript or ESLint if they're a Python dev getting used to the ecosystem? Why choose a boilerplate with a bunch of things you don't seem to want or need?

Because we want the application to have a modern look and feel, and this Python developer has a genuine desire to start learning about modern web technologies.

> Because we want the application to have a modern look and feel,

you think that e.g. Telegram or MauiKit apps don't look modern ?



An electron desktop app makes sense for applying knowledge of web tech, its kind of silly to complain that Electron + React + TS + ESLint isn’t an ideal pedagogical platform for web tech, and is overwhelming to a bewbie with lots of different moving parts.

(Also, while React is my go to web framework because I’ve learned it well from necessity at $DAYJOB, it’s not particularly modern.)

Is it fair to say that the expressed concerns are only your own?

As I see it, people with genuine desire to learn don't see details such as "number of dependencies" or "linters" as impediments to anything at all.

Perhaps because it allows people to use the app remotely and perhaps collaboratively without changing much code. Once you go down the path of a native app, it's difficult to go back.

> I'm now trying to teach them JavaScript, webpack, TypeScript, React, ESLint, ... Help them resolve dependency issues. Explain bundlers, the various different module systems ... the list just keeps getting longer!

I think teaching people all that, all at once is the actual problem, not that all those systems are not impeccable (which they aren't). Maybe as developers we should figure out what are the things that are truly important, and draw the line at that, and then treat the rest as optional.

I truly wish that things we do are simpler, but they are not going to get better by wishing. But even that is not my biggest grief, it's that the pain is often self inflicted. Developers love using everything possible and making everything into something they can't live without (in part because it's a way to look down on people that don't know or use something), but it's not true. So, ESLint is a great tool, but a beginner does not need to know about it. I think you do need to suffer a bit before you can appreciate a tool like that. Webpack is a... well, it does things that we need, but a beginner does not actually need to know what goes on when they run their dev server.

Slim things down and it's fine as long as they're still doing the real thing. Kids don't go to school and start with the square root of a negative number. They don't even teach them what a negative number is.

Yep, totally agree. For now we are focussing on plain-old-JS with VueJS. Nothing more. It's just frustrating that the UI component library we want to use (FluentUI) requires React & TS, which in turn require a bundler / build system, which leads to a world of pain!

You can use any Typescript project in plain Javascript, it all compiles down to and runs as Javascript in the end. You obviously don't get the guarantees of static typing but you should be able to use React FluentUI in plain JS. FluentUI also seem to offer a web components distribution which you could probably use handily in Vue if you were so inclined.

One have to be reminded that you do not need webpack, TypeScript, React, ESLint et.al. to make a web app. For best platform/hardware support it's best to use the native components built inside the browser, like textarea, select-box, etc. If you use a popular component framework/library it's likely that it has only been tested on one or two platforms, and will be abandoned in a few years so it won't work on the latest gadgets.

If you want to make a web page or web app fast, with good performance, easy maintainability, small in size/bandwidth, and superb hardware support - go with "vanilla" web components. If you want to follow the latest fashion in web development and have a cool resume then pick a framework (but make sure it's not the most mainstream/enterpise - that's not as cool)

The concerns about security and licensing expressed in the tweets are real... but the analysis didn't go deep enough.

For example, electron includes Chromium, which includes a number of copyleft-licensed libraries... In order to fulfill the license obligations, complete corresponding source code for these libraries must be accompany (or be made available) for each electron app.

what if we create an engine that finds similar objects and merges them together, so it find redundant code and creates slices that are only called from within whatever file needs that part of the code. basically a don’t repeat yourself engine..

It really feels like Python devs are casting stones from glass houses whenever they complain about the boilerplate required to setup a modern JS development environment. In Python, the correct way to setup a new project seems to change every six months. And the most future proof package manager seems to be Poetry, which is directly inspired by Yarn.

I am a JavaScript / TypeScript / Web developer and I am throwing stones within my own glass house!

How about:

   pip install mypackage 
No? it's too 2010?

I've been a developer for some time now. All I know is a lot of developers love unnecessary complexity. It's even more true in the JS world to be honest.

Javascript modules were supposed to make everything easier yet some people still manage to write insane boilerplates and tools on top of that and bring back complexity where it is not needed.

>No? it's too 2010?

The issue with blind use of pip is that it will inevitably break something in your system when a dependency upgrades too much. Hence virtualenv, and later pipenv.

And setting up a Python project is more than just dependency management. Do you want an egg/wheel/etc? Do you use setup.py, or is it deprecated? Speaking from experience, the docs for various Python tools simply don't agree on these things, and it's very hard to set up a project "correctly" without someone helping you.

Do this on a brand new MacBook (or for a bigger challenge, try it on a MacBook that already has a bunch of Python development tools installed). Count how many Google searches you need to make before you have a reproducible and isolated development environment you can share with a junior teammate.

As someone who is fairly new to Python and have lost hundreds of hours on different project in this exact same situation. I've found Dockerized development containers (VS Code Remote Containers) to be a very good solution. Nothing leaks out. Everything is reproducible. But then again I do only web stuff.

Needing a container (outside of a system publishing reference builds) is evidense of a problem.

The fact that a container is easy today just enables and hides the fact that it's a bit ridiculous to need one for half of the things we now use them for. Same for snap, flatpack, appimage, etc.

Rather than have a handle on my surface and interface with the os, I'll just bundle an os with my calculator app.

All because they're using a newer version of some library that maybe has an extra param on one function to automatically zero-pad or something.

And "they" isn't necessarily the developer of the calculator app but could be the developers of any of the hundreds of dependencies.

We all know all the excuses how we got here. We all know how each individual step along the way has it's excuse. Yet, it's not a great place we got to.

Every time we have to have someone fix one of our relatively few python projects I rue the day I wrote them in python -- it often takes hours just to get it so the code runs on their machine.

Electron is Flash for the Desktop.

History is repeating. Instead of investing into hard work and portability with programmers, the management decides to take the short part which looks cheap. The result are bloated, memory hungry applications which do not integrate well into the operating system and native toolkits. The last part is maybe not so much noticed on Windows but Linux and Mac users notice it. These companies save money with Electron and the customers have to pay with hardware, reliability and usability. In times of soldered main-memory the memory consumption is a huge issue for everyone. I recommend using native toolkits like Gtk, Qt or Win32 (currently maybe WinUI?) and using appropriate languages (language bindings for important languages are available).

Some nice application developers actually store data locally, therefore the applications are working fast and self-reliant. Imaging a chat application which doesn't lag and doesn't repeatedly load the conversation from the server just because you're scrolling upwards. A little bit off-topic ;)

> History is repeating. Instead of investing into hard work and portability with programmers, the management decides to take the short part which looks cheap.

I agree with this point of view for bigger companies that do chat and music streaming apps. Nonetheless if you're a __much__ smaller company who needs to do cross-compat. applications and has problems hiring personnel (either due to lack of, or too expensive) technologies like Electron saves them a lot of trouble, money and time...

Well, I guess it's JavaScript to blame. But well, maybe it's unfair to blame JavaScript which was implemented in 10 days and not meant for large/serious applications. How much can you expect from 10 days worth of work of a single man? But the reality is that now almost everyone is trying to build something if not everything with JavaScript. The reason behind all this might be all the sudden, we have so much computing power to abuse.

> How much can you expect from 10 days worth of work of a single man?

You are aware that ECMA exists? And that JS has been updated quite a bit to align with modern use cases.

Imagine a chat application you had to install instead of just going to a website

>Imagine a chat application you had to install instead of just going to a website

This is a bit of a bizarre argument. When using a chat app on a web site, your browser downloads the source, unpacks it, then executes in a runtime on your machine. You're doing the same thing, otherwise the app wouldn't work.

You also had to first download and install the web browser used to download and install the chat app.

Imagine allowing a web site to be my gateway to chatting with people not on that web site.

Imagine letting a web site decide what features I should have in my chat client.

Well, that is the fundamental split between specifying a bunch of features and letting people write clients, vs closely linking the features and clients together.

When I can update my web client every day with a new feature, the advantage of not having an open standard is higher, I can invent new features in days rather than the years it's taken IRC to add things

I think you're conflating the problem of too many direct dependencies with that of too many transitive dependencies.

We go about the rest of our lives using abstractions through interfaces. Those abstractions use abstractions. e.g. To build and use a pencil there are hundreds or even thousands of transitive dependencies. From the wood and graphite to the rubber and metal, each of the inputs like axes to cut wood or to create those other components, and so on.

With software we just do a better job tracking the “lineage” of these transitive dependencies, so the numbers seem large.

The real problem seems to be the ergonomics of all the direct dependencies. The number of transitive dependencies wouldn’t matter if the direct dependencies were in aggregate ergonomic to work with.

Transitive dependencies absolutely do matter.

Even in the "real world" overly complex and distributed supply chains are a source of problems - and much the same problems as sprawling dependency trees: They are the cause of unnecessary environmental pollution (by shipping components around the world for purely financial or organisational reasons), they decrease transparency (because it's difficult to understand what kind of companies at the very end of the supply chains actually produce your parts) and they introduce risk of failure.

As with software abstractions, those are problems that are easy to ignore by the designers of the end product, until they hit. We're getting more aware of those risks by now, thanks to COVID and geopolitical tensions putting stress on supply chains.

As a dev, it's important to remember that abstractions are a tool, not a mechanism for responsibility washing. When you develop a product, you're responsible for all code of it, not just the parts you wrote yourself.

> Even in the "real world" overly complex and distributed supply chains are a source of problems - and much the same problems as sprawling dependency trees: They are the cause of unnecessary environmental pollution (by shipping components around the world for purely financial or organisational reasons), they decrease transparency (because it's difficult to understand what kind of companies at the very end of the supply chains actually produce your parts) and they introduce risk of failure.

Such as pertinent real world parallel. Although, it seems that today, the global supply chain seems to be suffering from a "leftpad" issue when it comes to electronics as a few factories in Taiwan and South Korea produce chips used almost everywhere, and some of the factories are in trouble for various reasons.

Even simple stuff. There has been a problem for years that it's actually hard to prove what's actually in a jar of honey on a grocery store shelf, even in a country with strong consumer safety regulation. Is it even honey or is it fake? Where did it really come from and how was it actually produced and what ingredients are actually in it? There is a label that claims to answer all of that, but it often actually doesn't.

I am really hoping efforts like Blazor Desktop allow for us to escape this kind of hell.

You can already build really powerful component systems by combining the current iteration of blazor with stuff like WebGL.

You only need to screw around with just enough javascript to interop the canvas from C# land. Then, from that point forward all you need to worry about is C#/HTML (Razor) and CSS.

With this approach we have been able to construct ridiculously complex web interfaces that sit directly on top of some monster state machine implementations.

Think about the dependencies involved above in terms of vendors. If you do it right, you can answer to just Microsoft. I know not everyone agrees with doing business with them, but having a single vendor stack is so compelling in the B2B space when your customers are very security sensitive (e.g. finance).

There is always the concern of transitive dependencies, but SQLite is already inside your car so you probably have to trust that one by default... I'm open to arguments on others.

Why wait for Blazor when Qt is a thing?

I really hope Microsoft realises the only place for Blazor are PWAs.

It may look brittle to a newcomer, but it in my actual experience it is way less brittle than Python, Java or C++ ecosystems. The size is mostly due to packages shipping three different module types in multiple flavors.

I am upset about having node_modules in my source tree, however. A global package cache should be a thing.

You can have a global package cache today with Berry (Yarn 2/3) although there are still a few tools (say, serverless package) that break without node_modules where they expect it to be. It's gotten a lot better though over the last few months.

I have never had to decide which exact Maven version (Java build tool) to use in team and on CI server when developing in Java. Most of the times you can safely use any version of Java that is higher than currently required in project.

My team wasted a lot of time finding version of node/npm/yarn that works on CI and on all developer machines. Purging whole node_modules and installing everything again used to be weekly occurrence. It is much better now but poor design of JS ecosystem still makes me nervous when I have to update node, npm or bigger dependency.


I'm not saying nothing in the ecosystem ever breaks. I'm saying that despite it being unstable, it is much more resilient than it is brittle. It does look crazy at first glance, you have to experience it to believe it.

Has anything improved at all since the last time an article like this was posted?

No, my feeling is that it is getting worse. Dependency graphs are getting bigger, our tooling is getting more complex.


I mean… it’s easy to complain right?

Everyone wants a free ride: beautiful modern UI, fast, easy to use, cross platform, free.

If it’s so bad, why is it getting worse?

…because people like free stuff, and no one actually wants either a) a crappier (but better tooled) solution or b) to pay for a better solution.

Its not that no one cares about these hard problems… it’s just that no one actually cares enough to be more than complain about it for free.

It is what it is.

The chances that it will magically resolve itself without a major shift in how developers build things is zero.

The problem isn’t the frameworks.

It’s that people use them.

You know what's easier than complaining? Finding excuses.

Windows keeps getting worse and worse. People pay money for it, and yet Microsoft is putting ads in it.

So clearly the problem is not limited to people wanting "free" stuff.

It's also a matter of choice when consuming libraries like expressjs, which the linked article referes to.

For example, hapi (https://hapi.dev/), a feature comparable web server framework to express, has zero external dependecies.

There are a lot of responsible maintainers of great packages in the node community which keep dependencies to a minimum. It's up to the consumers to use and value them, not just default to the likes of express.

Not much ..

There is esbuild which help eliminate webpack hell, but most shops still use "Create-React-App".

There are some lite weight alternatives to React (like Preact), but most shops aren't using them yet.

I can't really think of anything else that could count as an improvement.

One of the saddest things is that Electron is less portable than the old guard. Java GUI toolkits, wxWidgets, QT, GTK, even Flash ran on tons more platforms than Chromium/Blink/NodeJS/Electron ever has.

Cross-platform development has always been difficult, and I'm not sure Electron really makes anything easier.

"What Intel giveth, React taketh away."

(Updated for this decade.)

I'm more and more tempted to create a readable, minimalist document format that can be compiled into a binary file.

Web stuff and the dom is too cluttered, too many ways to do the same things, too much things should be made obsolete.

Js is also a bad language, js engines are monstrous, to ambiguous.

Flexibility is okay, as long as it doesn't come with a high cost.

Electron is an abomination that should die as soon as possible. My solution is to never run Electron apps like I always avoided Flash stuff and don't do JAVA.

If you want to have many dependencies, try React native development!

Try Qt. Save some memory too.

What is the solution?

The solution is a good set of standardized libraries that do the job well enough, and are either delivered as part of the environment or downloaded as a single unit. Then everybody can learn use the one good thing instead of hundreds of redundant, overlapping things.

That runs counter to the usual JS ecosystem philosophy of delivering almost nothing and letting everybody make up their own. That's a fun environment for hobbyists exploring and cobbling things together, and a pain in the butt for professionals trying to get work done.

It would be a huge amount of effort and everybody would hate the result, so I don't see anybody rushing out to do it. Instead, we get this: a framework that installs a large subset of the entire NPM database every time you start clean. As a framework it mostly hides that ugliness, unless you look at the install process and ask "Why is it so noisy?"

I would say the solution is culture.

All individual developers should recognize and avoid things that lead to this state.

All or at least most should have a common sense of what is good and what is bad, what is attractive and elegant, what smells.

That is not something you can dictate. It has to be something the majority simply recognizes and agrees about, so that they create less of the bad things, and every new developer absorbs the same sense from their childhood googling, the examples set by indisputably valued projects, and school & co-workers.

Right now some of the most valued projects set some of the worst examples.

It has to be cool and admirable to be efficient and robust, and right now it's not.

There is just no way I see to bring this about. You can only do your own tiny part and wish for the rest of the world to improve. Unless you run google or other huge body of coders, you can't change the entire culture. It just changes over decades however it will.

>this is a problem

I don't see it as a problem, but rather a strong signal depicting the general quality of the entire ecosystem and why you should steer clear of the whole mess in the first place.

The problem is two folds:

- Node.js std lib is paper thin. You can't even parse a http request multipart body without bringing in a separate package...

- NPM has always been a mess, but it's seems it was all by design in order to make node.js depend on that (commercial) package manager.

Node.js creator biggest regret was its dependency to NPM.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact