
A Newly-Generated Create-React-App 2.1.5 App Has 1,568 Dependencies - _0nac
https://twitter.com/garybernhardt/status/1097307043881308161
======
acemarke
Note that the listed discussion is specifically about projects generated by
the Create-React-App tool, not React itself. React has always been usable by
just adding a pair of `<script>` tags to any HTML page.

Dan Abramov pointed out [0] that:

> in terms of feature set (test runner, devserver, compiler with support for
> bundle splitting and optimizations, error overlay with editor integration,
> static code checker) it’s comparable to a small Xcode.

> It’s valid criticism that tools like Xcode are installed once whereas react-
> scripts is per project. But the upside is you never have the “different
> projects demand different Xcode versions” problem. And everything runs on CI
> thanks to full encapsulation.

> I’m hoping approaches like Yarn Plug’n’Play will give us best of both
> worlds. Shared install for the same versions between projects but with
> isolated and versioned tooling.

[0]
[https://twitter.com/dan_abramov/status/1097309141075456000](https://twitter.com/dan_abramov/status/1097309141075456000)

~~~
pier25
> React has always been usable by just adding a pair of `<script>` tags to any
> HTML page.

Yes but good luck with React.createElement(). React without JSX is really a
pain to use (or Preact, Inferno, etc).

Vue is much more straightforward for those simpler cases where you don't
need/want to setup Babel, Webpack, etc.

~~~
acemarke
There's a number of options available if you don't want to use JSX.

For example, if you prefer to use small wrapper functions like
`h(MyComponent)` and `div()`, there's `react-hyperscript-helpers` [0].

More recently, Jason Miller published `htm` [1], which provides near-JSX
syntax using ES6 template literals, and no build step required. It appears to
be a very viable alternative to JSX in many ways.

[0] [https://github.com/jador/react-hyperscript-
helpers](https://github.com/jador/react-hyperscript-helpers)

[1] [https://github.com/developit/htm](https://github.com/developit/htm)

------
_asummers
A former boss of mine had a sign above his desk: “Transitive dependencies are
the lifeblood of stuff. We don’t build stuff, we build software.”. While I am
not a JS developer, I am distrustful of every dependency brought in and
aggressively work to eliminate the only kind of useful ones. They’re debt
brought into the code base and must be constantly evaluated for security
concerns, interactions with other dependencies, and upcoming changes being
incompatible with your code, which may in turn cause you to be unable to
upgrade other dependencies.

Not having to write code is great, but when you bring something in it becomes
code you must maintain for however long it is in your project. The utility
calculus is variant for all projects and even different phases of the same
project. But the calculation should be done often and ones that fall below the
utility threshold should be removed.

~~~
pcmaffey
Sign above Newton's desk: "If I have seen further it is by standing on the
shoulders of Giants."

We can strive for sustainability and autonomy, but we're forever dependent on
each other's work. As they say, it's turtles all the way down.

~~~
echelon
Yes, but there is a lot of nuance here.

Introducing dependencies is a quick way to get to market since you don't have
to build a universe from scratch.

Once you've gotten to market, you have to support your thing. This is when
dependencies start to have a non-zero cost. When you'd rather spend
engineering efforts on building new features, you instead have to do regular
house cleaning to make sure your thing continues to work and have a happy
upgrade path.

The larger the engineering organization you work in, the more apparent this
becomes. Smaller orgs can sometimes brush the ugly under the rug. Larger ones
bump into issues constantly. I'd wager that 5% to 10% of engineering might be
dealing with maintenance of dependencies.

(fwiw, I'm mostly speaking in terms of my experience as a backend engineer.)

~~~
_asummers
You are seeing to the heart of my argument. Thank you for that. I agree on the
5-10% mark, and find it's true even in smaller orgs that have a mature enough
product. Once the product solidifies, having a bunch of different dependencies
dictate which direction you can go is not in the best interest of the company,
and should be reevaluated accordingly.

------
jxcole
It's a little ridiculous to view this as a problem. I am currently working on
a small personal project in my spare time with 775 dependencies. Quickly
perusing the dependencies the reason there are so many is because I am using:

* Webpack

* Unit testing (Mocha)

* Code coverage (Istanbul)

* Browser transpilation (Babel)

* Type safety (typescript)

Now for an apples to apples comparison I used to work on c#/.net. Complaining
about these dependencies would be akin to me complaining that I couldn't
manually audit the unit testing dlls that VS is using to do code coverage for
me. Of course, no one ever audits these DLLs. A more interesting analysis is
to look at how many non-dev dependencies you have (I have none, I doubt this
basic react package has more than just react for the production code).

Of course one could argue "someone might stop maintaining this project", but
this is equivalent to saying "I won't use open source". In fact, in my
experience the opposite is true, with closed source paid software becoming
obsolete more regularly than open source alternatives. If a company decides
something isn't making money they will usually can it while with open source
at least someone has the opportunity of picking it up when an author loses
interest.

~~~
gary_bernhardt
Dev dependencies are as dangerous as production dependencies and always have
been. Read this from 1984:
[https://www.archive.ece.cmu.edu/~ganger/712.fall02/papers/p7...](https://www.archive.ece.cmu.edu/~ganger/712.fall02/papers/p761-thompson.pdf)

Those 1,568 create-react-app dependencies are maintained by people you have no
formal relationship to, and are all versioned independently. Visual Studio is
one monolithic package released by one of the largest companies on earth.
Microsoft is not going to back door you and it has a huge incentive to stop
anyone else from directly back dooring you via Visual Studio. On the other
hand, the maintainer of the event-stream NPM package, with ~1.5 million weekly
downloads, recently gave control to a stranger. They successfully back doored
it and evaded detection for over a month.
[https://blog.npmjs.org/post/180565383195/details-about-
the-e...](https://blog.npmjs.org/post/180565383195/details-about-the-event-
stream-incident)

~~~
wolfi1
now with the nuget ecosystem VS projects also depend on external dependencies
you have no formal relationship to

~~~
borland
yep. In theory a dotnet project pulling in nuget packages is in the same class
as a node project pulling in NPM packages.

In practice, it's _tremendously_ different.

As mentioned, a do-nothing react app has 1500 dependencies, all managed by
who-knows-how-many different companies and individuals

A do-nothing aspnetcore app has maybe a few dozen dependencies, and with the
exception of Newtonsoft.JSON, all of these are managed and supported by
Microsoft.

When you scale that up to a real app, I don't even know what you get with
Node/npm? 2500 dependencies? With aspnetcore you probably end up adding 10-20
more dependencies, and some of them are probably written by Microsoft.

So, your "potentially untrustworthy package count" in node is about 2000
packages, whereas for aspnet it's about 10 packages. You can review and pay
attention to 10 packages. 2000? Not so much

Aside: A java/maven project probably falls somewhere in between, but closer to
the aspnet scenario. Instead of a few dozen dependencies you might have 50,
but it's still realistically possible to review them all, and they're far more
likely to come from trusted publishers such as the Apache foundation.

------
tluyben2
I am (usually) not a JS dev, but we have quality standards which are, to some
extend, regulated in my business (banking/payments), so to use this, I would
not only want to, but to some extend _need_ to understand all (ok, maybe not
all, but at least the ones that seem to not be maintained very well or the
ones that come from lone devs who might find another hobby and just quit
maintaining) these 1568 dependencies and audit them for security every update.
I would need to make sure they are maintained and if not decide if we will
maintain them (if we are on a certain version of a NuGet package (we use .NET
Core mostly) and the maintainer quits but somewhere in our stacks something
depends on it, we have to make this decision, but we or the packages we use
simply do not have that many dependencies). I do not want to dismiss other
companies by saying 'apparently they don't care' but in the React/Node (JS)
space in general, that feeling does creep up quite often when I read HN.

~~~
hombre_fatal
Though this submission is talking about development dependencies rather than
runtime dependencies. For example, the scaffolding it generates builds a
Javascript app that runs in the user's browser.

Still a potential problem, since each transitive dependency even gets to run
arbitrary code during install on the developer's machine, but a different one.

~~~
marcus_holmes
The problem here is that any code run during development could generate code
that ends up in production. Even if the dependency isn't used in production,
there is a "compile step" (though it's technically transpiled) during which
all sorts of mayhem could ensue.

~~~
hombre_fatal
Absolutely. It's like a static site generator having a bunch of dependencies.
I just wanted to refine the distinction, though it doesn't really change much.
But you can at least be more prudent here than you could with 1,600 production
runtime dependencies, like doing your development in an isolated environment
on your own machine.

------
stevebmark
"JS developers keep reaching for huge JS packages. Just import small ones"

"JS developers install too many small packages."

Whooooooo cares. When you come up with the maximum arbitrary acceptable
packages (including nested dependencies) for a project, and then also the
arbitrary minimum LOC needed to publish a package (for all you leftpad
haters), then throw your numbers in the toilet and stop talking.

I love that Babel, Prettier, Jest, etc use plugins as individual npm packages.
I love the ecosystem it has created. I love that we have a big ecosystem that
improves developer experience.

~~~
peteforde
Genuinely curious: how long have you been developing web apps, and what
stacks/platforms did you work with previously?

I ask because your reaction goes against everything I've ever felt, and I
sincerely want to understand.

[https://www.youtube.com/watch?v=1K5SycZjGhI](https://www.youtube.com/watch?v=1K5SycZjGhI)

~~~
stackola
I've been working in web dev since 2008 and have never been happier with the
ecosystem or more productive.

~~~
peteforde
Cool. Still excited to hear from @stevebmark!

When you started in 2008, were you self-taught, college/university or
bootcamp? No wrong answers.

Have you been working primarily in JS the whole time?

Did you do front-end, back-end or some blend of the two?

------
tga
It looks like the left-pad incident has collectively taught us nothing and has
had no lasting effects. One of the things that bothers me the most is over and
over casually downloading 1568 independently controlled packages from a free-
for-all repository (also privately owned and controlled, but that's a
different discussion).

create-react-app is a complex tool put together by I team I largely trust.
What I want on my machine is a static build of their work, not the whole
sausage making factory in 1568 pieces. Once I would have the binaries, the
whole of npm and the JavaScript ecosystem could go away altogether and I would
still be able to build and deploy my apps.

The package, in its published form, would be vetted by the create-react-app,
who have a much better idea of what's going on in their dependency tree than I
do. If they decided they need that many dependencies, it is up to _them_ to
manage the complexity. That said, it would probably make their lives easier to
depend on 10-20 packages, statically built by people they trust, and so on.

Even if the result of this would initially be very similar to today (still
running the same code of those 1568 packages), it would make me trust this
stack a lot more.

------
andrewstuart
Yes but it does alot of stuff.

It's not surprising or concerning.

That's what it takes to get modern things built - lots of other things.

~~~
breck
Exactly. Even if it had 10m loc and 10k dependencies, that’s not a problem at
first sight.

In fact, the 1.5k dependencies in this example is a __drop in the bucket
__when you consider all the dependencies that your react app needs to do
anything useful (http, dns, tcp, ip, browsers, OS’s, et cetera).

I’m not defending React here, I don’t know enough about it, I’m just saying
1.5k dependencies for a hello world app might be bad, but __it depends on the
details __.

~~~
fendy3002
And repeating as usual, it is caused by lack of standard library for js
environment. All of things mentioned could've been packaged into 1-2
dependencies. But instead we need to independently add each one.

Similar case with babel and webpack, that each plugins (and loader) is a
separate dependency. I don't know if it's more efficient or modular for
development, but it is surely bloat the packages.

------
Waterluvian
I don't exactly understand the point of create react app. Are there people who
churn out apps so regularly that this tool has value?

I tried it and in order to satisfy everyone's needs it seems like overkill
tooling for most needs.

~~~
Etheryte
For context, I'm a lead frontend dev in a company of a few hundred people.

Most people don't remotely know how Webpack works. And they shouldn't have to!
Same for most other developer tools. You need a few people who can dig out
issues if they arise, but most of your people will be concerned with actually
building things on top of those tools.

When every team starts a new project from every few months to every few years,
having a boilerplate setup quickly becomes very valuable. The added benefit
that third-party boilerplate has is that you don't have to maintain the whole
lot yourself.

Needless to say these upsides don't come without issues, security and
accountability being the big elephants in the room, but popularity helps here,
too. The boilerplate is used by a lot of people, in organizations both big and
small. If an issue arises, you can usually collectively work out the problem
very quickly. It doesn't make the issues go away, but it gives you a good
balancing point.

As a tradeoff versus either setting up every project manually or maintaining
your own boilerplate project, it's definitely worth consideration — it might
not match your needs, but it's a strong option.

~~~
Waterluvian
Thanks for sharing. I'm not going to be one of those, "well you _should_ learn
how it works" kind of people. If people make useful, maintainable products
with these tools, great.

I think maybe I just struggle with the concept of being that hands-off with
the tooling. I don't think I could cede control to some one-size-fits-all
solution. For example, what happens when you run into some important library
that doesn't tree shake or minify properly? What do people do? Do they just
pick different libraries for the wrong reason? Do they just deploy an un-
optimized application?

Not knowing how the stuff you depend on works feels really scary to me.
Reminds me of the Star Trek TNG episode about "The Custodian" where the colony
came to depend on a tool that nobody knew how to fix, so their lives were
shaped by the tool's abilities, not the people's desires.

~~~
sorahn
The flip side of this, is I know how it all works, and I don't want to deal
with it anymore. I spent 2 quarters at my last job digging through all the
webpack/babel stuff just to come up with something that didn't work as well as
CRA does out of the box.

And on top of that, it's all different now. I'm not as interested in trying to
maintain all of that, on top of maintaining my app. CRA is a fantastic tool
for this.

------
linkmotif
I just don’t see how this matters. Looking at it this way is just not
interesting. This is the whole point of dependency management: making
dependencies so easy that this sort of thing happens. One must ask: what’s the
dependency graph for the complete build, after tree shaking etc. it’s
definitely not thousands of modules. And if so—so what?? That’s the whole
point!!

The real issue is security, but that’s another issue. It’s remarkable you can
just push code to npm without signing it. Every time I push a commit to GitHub
and then release it on npm it really gives me the creeps. Fortunately we have
CSPs.

~~~
gary_bernhardt
You acknowledge security as "the real issue" in your comment. I don't know how
to square that with the first sentence in your comment, "I just don't see how
this matters." It matters because of security, like you said.

~~~
linkmotif
Install a CSP and you’re done? (assuming we’re talking about front end code)

~~~
gary_bernhardt
That's not the kind of security problem we're talking about here.
[https://blog.npmjs.org/post/180565383195/details-about-
the-e...](https://blog.npmjs.org/post/180565383195/details-about-the-event-
stream-incident)

~~~
linkmotif
Huh? This is an issue affecting backend JS. We are discussing front end
applications.

~~~
hombre_fatal
Even if this code is only run on the developer's machine, you're trusting
1,600 entities to not pwn it one day.

It's worth some concern.

As the copay attack shows, that everyone uses these libraries doesn't let us
rest assured. There are virtually zero eyeballs on the code of transitive
dependencies because you would have to extract tarballs to read code. And
attacks can be extremely targeted. The copay attack was only discovered
because of a deprecation warning in the attacker's code that someone reported.

~~~
linkmotif
That is true. Thank you. But is that the totality of the danger, then?

------
jarym
... I continue to use smartclient.com for my front end work.

It continues to kick everything from a productivity perspective and the
framework is fantastic (for business-y apps).

People used to tell me it was too heavy weight. People used to tell me jQuery
or Angular were better.

No external dependencies. NPM not needed. Might be a bit old in some places
but so what.

~~~
padseeker
It may be great for you. But it will not go well when someone else needs to
support it.

It might be old? GWT? Just go back to developing Web 1.0 applications and see
how that goes. GWT is antiquated. I realize the churn associated with front
end can be maddening, and you don't always need a Single Page App, but from a
usability perspective you are really behind the times.

~~~
acemarke
My first actual web app I ever built was with GWT + SmartGWT, back in 2011-12.
The decision made sense at the time, because I didn't have any JS experience,
and the JS ecosystem wasn't nearly as mature at the time.

Over time, though, the actual time to make any kind of change to the app
became incredibly painful. The loss of the GWT DevMode plugin back around
Firefox 27 hurt too.

We just finished rewriting that app with a modern React+Redux implementation,
and I took great glee in deleting the entire GWT portion of that codebase. The
changes have already paid off by letting us add some additional functionality
that would have been a distinct pain to implement in the old codebase.

Sure, the fact that it was the second time through was a factor, but the
iteration speed and codebase structure are truly both vastly improved over the
original.

Another team has a SmartGWT app that they're planning to migrate in some
fashion as well. Unfortunately, they locked themselves in badly by using
SmartGWT's server-side black box that hooks into a DB to send data to the
client. It's going to take them a while to start teasing that apart.

~~~
isostatic
It amazes me how many people suggest that $2015_technology is behind the
times, on a site that - aside from a javascript voting button - would happily
exist in 1995.

------
Scooty
I don't really understand how headlines like this are helpful. Is there an
ideal number of dependencies? How do we decide that 1568 is too high? Is it
better or worse than 156 dependencies that each have 10x the LOC? How should
the CRA devs address the bad big number? Rewrite all their dependencies from
scratch and bundle them with CRA?

Instead of guilting developers for their dependency count, maybe we should be
auditing open source project dependencies or suggesting better tips for
vetting dependencies.

~~~
xg15
> Is there an ideal number of dependencies

Maybe we could at least argue about the number of digits?

------
xiphias2
The solution would be a node standard library project that contains the slowly
moving parts of the 1500 dependencies, which means that it doesn't need too
much maintainence.

I don't understand why the companies that depend on webpack haven't built a
project like this yet (and made sure that the important projects use that
library), but I believe it's just a matter of time.

~~~
baddox
That’s a great way to have even more competing libraries.

[https://xkcd.com/927/](https://xkcd.com/927/)

~~~
xiphias2
Where are those 15 efforts? I don't see any effort to take a hard look at
combining the most used few hundred libraries into a collection of a few
libraries.

It's hard and boring work also.

~~~
baddox
Underscore and Lodash are obvious examples. I don't know if the project
maintainers' stated purpose is specifically that, but they are clearly
creating big libraries of common utilities. And, surprise surprise, two
extremely common problems with frontend NPM projects are: 1) unintentionally
importing the entire library instead of the few functions you use, and 2)
having many different versions of the libraries in your output bundle because
of other dependencies.

Hence things like this exist:

[https://www.npmjs.com/package/babel-plugin-
lodash](https://www.npmjs.com/package/babel-plugin-lodash)

[https://www.npmjs.com/package/lodash-webpack-
plugin](https://www.npmjs.com/package/lodash-webpack-plugin)

------
smackfu
You can’t say “it is good design to have small composable building blocks” and
then complain about the _number_ of those blocks.

------
pictur
I don't think this will be a sustainable ecosystem. The software is even built
on fast consumption now.

------
bayesian_horse
Javascript dependencies grow on you, quickly...

------
lab
Cool beans!

------
tasubotadas
Nice.

------
aboutruby
So, only needs a 0.06% chance of a package having compromised code (e.g.
bitcoin stealer, ssh/pgp keys stealer, keylogger, mitm, etc etc.)

~~~
jstewartmobile
Apparently, the trade thinks its 1970s-style orgy-bathhouse is fine just like
it is-- _thank you very much_.

------
jstewartmobile
When you look at what a mess the web is as a platform, 1,568 dependencies is a
modest amount of asphalt to fill as many potholes as it does.

In JavaScript land, you need an external dependency for freaking left-pad[0].
In freer countries, that cutting-edge 1970s technology[1] is built-in.

[0]
[https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/](https://www.theregister.co.uk/2016/03/23/npm_left_pad_chaos/)

[1] [https://stackoverflow.com/questions/293438/left-pad-
printf-w...](https://stackoverflow.com/questions/293438/left-pad-printf-with-
spaces)

~~~
crooked-v
I agree.

There's an effort to get at least a standard library namespace, but it's at
month 8 of just deciding on the semantics of how to import:
[https://github.com/tc39/proposal-javascript-standard-
library](https://github.com/tc39/proposal-javascript-standard-library)

~~~
tasubotadas
Oh, God. Finally, they have at least started talking about stdlib. It's
bizarre how a modern language could exist without a standard lib.

