
Ask HN: How do you manage complexity in large JavaScript applications - harshitj
Hi All,<p>I was just wondering how you guys manage complexity in large JS Applications? Since JavaScript is so flexible and HN is full of very smart people, I&#x27;m curious to know how everyone handles it.<p>I&#x27;m also pretty sure that for someone who is just starting out, this would be tremendously useful for them to know.
======
lollipop25
> How do you manage complexity in large JavaScript applications

By not making them large in the first place.

Take for instance the Facebook home when you're logged in. It looks like one
unified app. But what you might not know is that it may be comprised of
several different "applets" that are totally independent of one another. They
may possibly not use the same framework, nor share code, and could possibly be
built by several teams which are proficient in different languages and tools.

iirc, Spotify's app isn't built as one huge app. It's several different
"applets" running in iframes. This ensures that each applet is totally
isolated (so they don't kill each other even if they use different frameworks
and versions) and self-contained (so they're testable individually, reducing
the need for integration tests).

~~~
diehell
Are there any articles that i can read that discuss into this @lollopo25?

~~~
lollipop25
[https://www.quora.com/How-is-Javascript-used-within-the-
Spot...](https://www.quora.com/How-is-Javascript-used-within-the-Spotify-
desktop-application)

------
gonyea
Modularity and test coverage.

Also: garbage data makes every aspect of your business a living hell. Clean
data throughly before storing it and migrate data as business rules change.
You should be able to make A LOT of assumptions about your data without having
to parse it a dozen ways.

------
St_Alfonzo
I use ES6 Modules to organize and structure a large codebase. If I write code
for the browser I export it with a tool like Browserify.

Maybe the website [http://superherojs.com/](http://superherojs.com/) will help
with your question.

------
blah_blah
A bunch of very smart people are trying Elm, PureScript, funscript,
typescript, funscript, Scalajs ... might be worth checking them out

~~~
i0nutzb
Let's add another layer of complexity, this will solve everything!

~~~
harshitj
If using something like TypeScript or Elm can abstract away all the manual
work required with building, bundling etc. It just might be worth it.

------
bikamonki
Complexity is a broad concept.

------
creature
There's a number of techniques you can use, but most come back to fundamental
principles: keep things small and self-contained as possible, try to decouple
elements of your program, try to keep things consistent (and have one standard
way of doing things). There's also the craft-level principles too: use a
framework (one framework, and use it consistently), write tests for things,
leave helpful comments, automate what you can (like code listing,
minification, and asset packaging).

Frameworks are a big help – partially for the tools they provide, but also for
the consistency. "We have a lot of code, but it's all structured in a standard
way" makes things easier to understand. It's also a way of having confidence
in the architecture: you know many other people have built successful apps
with it, rather than something you've invented yourself.

The concepts in Redux are very appealing to me: your application has one
state, and that state gets changed via actions. You have a function that,
given a state and an action, produces a new state. Your application can render
itself from that state. This makes testing straightforward: your business
logic tests boil down to "Given this starting state, and this action, my
output state should look like this." Similarly, your UI is now easy to test:
"Given this state, my component should render like this," covers displaying
information, and "When I interacted with this element, was an action emitted?"
covers user interaction. Traditionally hairy areas are now more
straightforward: "I need to test with a logged-in user" or "I need to test a
successful payment" is all about the data in the state.

Another technique you can use is a publish/subscribe architecture: individual
parts of your application publish events, and can subscribe to events they
care about. Now, your InboxCounter widget doesn't have to know anything about
how messages are received or displayed; as long as it listens for
"message:added" and "message:removed" events, it can display an accurate
count. Similarly, the AJAX polling for new messages doesn't need to be coupled
to the message display or the counters or other elements; it just has to check
for new messages, and publish events when new ones are received. This should
make it easier to add new components and refactor old ones (as long as you're
emitting the same events, nothing else should have to be updated), but it can
be hard to figure out what events get emitted, and where they come from. Tests
help.

On a much smaller level, using promises instead of callbacks can help reduce
"pyramid code" \- sections of the codebase with extreme indentation. They also
make it easier to handle failure cases; writing "Make these 3 co-dependent
AJAX requests, and if any fail then display an error message" will be more
concise and clearer with promises.

Finally, don't over-complicate things. Frameworks, dependency injection, and
the like add a lot of upfront complexity to a project, but reduce it later on.
If all your application needs is an occasional "When X happens, show/hide this
DOM element" then simple jQuery event listeners will be a lot quicker to build
and easier to understand. Don't build a Swiss watch when what you needed was
an egg timer.

