Every day a couple of new javascript modules are created and published around the world and we need to think long term. Let's say today I need to use an ORM module to go smooth and fast. But tomorrow I may face a deprecated module or may find a better one to switch or even may need to create my own.

For example, the team have decided to use Sequelizejs on top of the Sqlite to provide the models:

const User = sequelize.define('user', {
  username: Sequelize.STRING
    username: 'melbourne'

Then, a new type of database like Realm was introduced and they planned to switch:

class User {}
User.schema = {
  name: 'User',
  properties: {
    username: {type: 'string'}

let realm = new Realm({schema: [User]});
realm.write(() => {
  realm.create('User', {
    username: 'melbourne'

So, this can lead to refactoring the entire application and the team needs an interface to present in front and ignore code rewriting. As a result, switching will be easy and changing the bindings will not affect the entire code.

class User  {
  define(name, dataTypes) {
    ThirdParty.define(name, dataTypes);
  create(data) {

Regarding the example, what would be the good design pattern in javascript? How to bind an interface on top of third-party modules to develop the future-proofed and scalable apps?


1 Answer 1


I don't think it is possible in general to provide a future-proof abstraction layer. Different libraries have different approaches to the same problem which means they may provide different abstractions.

Furthermore, the point of a library is to save you work. If you have to replicate the whole data model one-level above the ORM just to provide an abstraction layer, you introducing complexity with no benefit.

I think the best approach is to keep your code well-factored in general and follow principles of separation of concerns and single responsibility, but don't introduce layers to prepare for a library replacement which may not happen anyway. See the YAGNI principle.

  • It's such a good advice. Thanks. Actually, my thought originates from other OOP languages where binding an interface as a contract to implementations makes the dependency injection with ease. So binding would tell the container that it should inject the module X when a class needs an implementation of that interface. So it would be very easy to change the binding to the new implementation. Jul 13, 2017 at 8:42
  • 2
    @hallaji: Yes changing the implementation is really easy if a shared interface is defined, but the hard part is defining a common interface which which could be adapted to all libraries.
    – JacquesB
    Jul 13, 2017 at 10:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.