3rd party libraries

What are your opinions on the use of 3rd party libraries?

In my humble opinion, I’d rather not re-invent the wheel if there’s already well-known libraries in the community accepted for certain reasons.

For example:

  • Tween.js - Tweens.
  • lodash/underscore - Commonly used JavaScript helpers.
  • jQuery - DOM helpers.
  • Three.js - Lots of good WebGL stuff.
  • HammerJS - cross platform touch
  • etc (add more here).

I believ we should make informed choices on whether a library is a good fit or not, and whether or not there’s any library that meets our needs for a specific purpose (for example, some are against depending on Three.js).

Basically every project in the open source Linux community depends on some library or other; it’s the open soure spirit. I believe we can take advantage of this.

In my opinion, using a third party library will save time but I am not sure it will allow for the performance control we want and need. As @trusktr pointed out, there needs to be a way to make an informed opinion on the use of a third party library before it is adopted as a dependency.

Options #2: We take advantage of the third party libraries if they have an MIT license and give Acknowlegement, but make it part of the base code and maintain from there forward with our own performance enhancements and modifications to fit the library.

EDIT: After reading @gadicc’s post and my own research, I did not consider there definitely should be an adoption of utility libraries rather than try to re-invent the wheel. I am just stating the obvious. :stuck_out_tongue:

1 Like

Yeah. Let’s be more a part of the ecosystem. Avoid reinventing the wheel and contribute back to useful packages.

And my thoughts on some of those that were mentioned:

  • jQuery - we probably shouldn’t use it internally, it’s pretty slow for DOM stuff. I’m also not sure where we’d use it… most of the DOMRenderer stuff will hold it’s own reference to the node and change properties directly. What did you have in mind for it?

  • lodash/underscore - definitely, there are a lot of essential functions here we shouldn’t try do ourselves (except in some component stuff). Lodash is known for being smaller and much more performant than underscore.

  • Three.js - I think we spoke about this elsewhere, that we’re all keen to use it for 3D stuff but it should be part of an optional plugin?

I edited your post and added HammerJS, which I also mentioned (for discussion) in Eventing System.

2 Likes
  • jQuery - yep, we don’t need it. You’re right, we don’t need to query for elements since we’ll create references for each one from the get go, and accessing those elements will be part of our public API.
  • lodash - Yep, agree.
  • Three.js - Yeah, not all of it need be used. Probably the WebGL stuff will be handy. The question is, if we use Object3D (maybe we don’t need to), how might that work with threads?

Perhaps the questions isn’t what 3rd party libraries we need,
but rather what do we need to accomplish that could be more suitably handled by external libraries.

One of the big things there that comes to mind is a physics library.

1 Like

@AdrianRossouw Yep, good way to put it. That’s why I haven’t used any 3rd party libs in my prototype yet. I figure when I get to the WebGL parts or Physics then I’ll evaluate at that point.

@AdrianRossouw mentioned eventing libraries at Eventing System.

I asked a friend of mine who built a webgl library on top of three.js how he felt about the dependency.
these were his reasons:

His view is that the whole clean modularization thing is a bit of a red herring because 90% (or more) of NPM depends on specific node.js versions and libs.

the whole reason “clean modules” work is because they all have the same root dependency

  1. depending on three.js gives him instant compatibility. you can mix other three.js code with code that uses his library with zero work
  2. three.js is an instant-on webgl thing that will keep getting updates and he doesn’t have to maintain, and has a large community
  3. being able to deliver a single .js bundle that works is infinitely more useful to real people than having to set up a build chain
1 Like

Another interesting eventing stream-like library, https://github.com/paldepind/flyd, I’m starting to like.

You should check out highland.js if you’re liking that : http://highlandjs.org/

1 Like

As far as FRP-type libraries go, Most is the fastest I was able to find.

1 Like

Highland looks good, and is made by the same guy who made the amazing async library which I love, so I’m sure Highland is very well thought out considering his experience making async.

I’m really liking the idea of using FRP techniques with our engine, but I believe that these ideas should be implemented (as far as an end user is concerned) on top of the rendering pipeline but not coupled to it, possibly even in a separate repo to the engine. Not to say that the engine itself can’t be architected with these techniques, but that the public API for our engine shouldn’t force FRP style programming, and that the API should be easily manipulatable with FRP techniques if the end user so desires (be it with our own implementation or one of their choice).

1 Like

Physics, animation and matrix math:

1 Like

Here’s the first beginnings of a DOMMatrix polyfill for the DOMMatrix API that is coming to browsers:

I’m really liking the concept of the async-csp channel library, for use with the upcoming and amazing ES2016 async/await syntax. The examples in the README aren’t entirely helpful at painting a initial picture of the significance of the pattern, so read here first on how this pattern can be used for event handling in user interfaces (note that the article uses generator/yield syntax instead of async/await, but the channel pattern is identical in both forms). If you don’t quite understand the difference in syntaxes, see also this similar article also on “taming” things with the async/await syntax in order to compare.

Here’s the example from the generator/yield article, converted to async/await and using the async-csp library:

import Channel from 'async-csp'

function listenTo(el, type) {
  let ch = new Channel()
  el.addEventListener(type, event => ch.put(event))
  return ch
}

~async function() {
  let el = document.querySelector('#ui1')
  let ch = listenTo(el, 'mousemove')
  while(true) {
    let event = await ch.take() // blocks until a mousemove happens and puts an event into the channel.
    el.innerHTML = ((event.layerX || event.clientX) + ', ' +
                    (event.layerY || event.clientY))
  }
}()

And the second example converted:

import Channel from 'async-csp'

function listenTo(el, type) {
  let ch = new Channel()
  el.addEventListener(type, event => ch.put(event))
  return ch
}

~async function() {
  let el = document.querySelector('#ui2');
  let mousech = listenTo(el, 'mousemove');
  let clickch = listenTo(el, 'click');
  let allEvents = Channel.merge(mousech, clickch)
  let mousePos = [0, 0];
  let clickPos = [0, 0];

  while(true) {
    let event = await allEvents.take();
    if(event.type === 'mousemove') {
      mousePos = [event.layerX || event.clientX, event.layerY || event.clientY];
    }
    else {
      clickPos = [event.layerX || event.clientX, event.layerY || event.clientY];
    }
    el.innerHTML = (mousePos[0] + ', ' + mousePos[1] + ' — ' +
                    clickPos[0] + ', ' + clickPos[1]);
  }
}()

Those two examples are really interesting. Any thoughts for or against the patterns in these examples?