Framework or Library

A framed view of the French National Library
A framed view of the French National Library

When speaking about dependencies, both terms can be used, sometimes in a (dangerous) interchangeable way. Is React a framework or a library? What about Bootstrap, or Lodash? Both are “packages” after all, right?

Sure they are, but they will definitely not have the same impact on your app.

Libraries

A library (“bibliothèque” in french, but most french people say “librairie” which actually means “bookstore” but matches the pronunciation of “library”) is a set of functions for general (like underscore.js) or specialized purposes (like moment.js).

You call library functions whenever you need them, like you pick tools in a toolbox. They do not require any changes in your software design.

Using a library is performing a imperative call to it

Proprietary calls

As any dependency however, they require you to call their proprietary API, thus “locking” your code with them (or even possibly a version of them), so that a call should rather look like this:

In reality your code depends on library’s API

Such locking will increase with the number of calls you’re issuing: the more you call the library, the more your code is being dependent to the library (or library version):

The more you call the library, the more your code is “polluted” with proprietary calls

Single point of dependency

To limit such a dependency however, you can hide it behind a wrapper:

Using an adapter keeps your calls library-independent

Such a wrapper can actually serve more than one purpose. Aside reducing the locking to a single item in your code base, it allows you to expose your own api to callers: only the calls that make sense, and with your own semantics.

However, step by step, your code is still dependent to the library’s.

Business API

Hopefully, as the late David J. Wheeler used to say:

All problems in computer science can be solved by another level of indirection.

Indeed, you can avoid such dependency by adding an interface:

Referring API interface instead of implementation allows to keep app code independent
  • callers will depend on that API declaration ;
  • the adapter will have to implement it.

But your app code can now compile without the library. You are now able to replace/upgrade the library without changing caller’s code. All you may have to do is to replace the adapter’s implementation.

Frameworks

Frameworks (“quadriciels” in official french, but everybody says “framework”) are different, as they provide a different type of service: they offer to manage things for you, instead of letting you devise what to do.

Handing over control

To do so, they implement the backbone (the “frame”) of an application, and let you fill the blanks. But those blanks are left in defined places and have defined shapes.

That means that:

  • the app starts with the framework: you have to hand over the steering wheel.
  • since the framework drives the app, you’re not the one making calls anymore: instead, you will be called back by the framework when appropriate.

This is the principle of Inversion of Control (IoC) or, more trivially, the “Hollywood principle”.

“Don’t call us, we’ll call you”, a.k.a. the Hollywood principle

Contracts

Of course nothing prevents you to manually call some code of your own, a third-party library or even some framework API,, but at your own risks. This may or may not work as you expect. Frameworks have rules that you are supposed to follow and, should you break them, the framework could not be accounted responsible for any failure.

Typically a framework will allow you to write components that will fit in their containers through the implementation of a contract:

Every component is required to comply with the framework’s contract.

The container will then be able to handle your code as a framework-compatible software piece whose life cycle can be managed, and will call you back at times that are relevant to perform some kind of operation or another.

As you can see, this is a much more structural choice that libraries for your application design: all your components become specific to that framework. The won’t be portable (i.e. not understood by another framework) nor interoperable (i.e. an Angular component will hardly interact with a React component).

One may argue, however, that the adapter pattern could be used to limit framework dependency, just like we did to limit the dependency on libraries:

Insulation of framework components make hardly a difference

This may look as useful… if the dependency direction was the same. But it is not: libraries adapters used to take a shape required by the app, whereas here component adapters can only take the shape of what the framework expects. As a result, the supposedly “free” app component can only mimic the initial contract (lifecycle, semantic, granularity).

Inside frameworks, components adapters would be unnecessary layering then.

Framework libraries

Libraries can also comply with frameworks. Instead of providing an API, they provide components implementations for a given framework.

As frameworks bacome popular, a number of framework libraries became available. Most of them are about widgets, though: for instance the Material Design components have been ported from Android to Web Components, Angular, React, Vue and even iOS frameworks.

Standard frameworks

Anybody can imagine the tremendous cost of porting the same library (and its subsequent versions) on each of those frameworks.

IBM has devised a solution about this: instead of porting they Carbon Design System on each of the past, current and future hyped frameworks, they invested in a port on the standard Web Component framework, which can be used in any context.

So, not only this allows to use their components from frameworks:

The web component is just part of the framework component’s view

But the same components can also be used from a plain app:

Web components can be inserted as tags even in simple web apps

Conclusion

Frameworks and libraries are very different third-party options:

  • frameworks provide you application blueprints with built-in services but enforces predefined contracts to call your code. As such, they imply a strong dependency.
  • libraries won’t help you design your application, but can be called only when you need them. You can devise a design that limits dependency to them.

They are not mutually exclusive, but it is recommended that libraries called from frameworks are framework-compatible.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Jérôme Beau

Jérôme Beau

Software engineer for three decades, I would like to share my memory. https://javarome.com