Reusing Code in the frontend and backend

A major selling point for many frameworks these days are the ability to re-use code on the frontend and backend.

NodeJS is quite vocal about this, but they are not the first.

Pyjamas (Python to JS compiler):

Your application's design can benefit from encapsulating high level concepts into classes and modules (instead of trying to fit as much HTML as you can stand into one page); you can reuse - and import - classes and modules.

GWT (Java to JS compiler):

GWT is not an attempt to abstract away the browser from you. Neither is GWT an attempt to prevent you from writing JavaScript when you want to. GWT is simply a way to give us developers some extra leverage in the form of productivity tools and the ability to create higher-level abstractions when it's useful. If you're a JavaScript guru, we hope you'll find GWT is a great way for you to package up your best work and make it easy to reuse.

Scala JS (Scala to JS compiler):

At the Scala Day last week, Sébastien Doeraene presented Scala.js, a Scala to JavaScript compiler. The compiler supports the full Scala language allowing its users to build web applications front to back in Scala and potentially reuse code between the server and the client.

Dart (Dart to JS compiler):

If you want to reuse code between command line and browser applications you should move them into the lib directory of another package my_shared_code where you put only code that doesn't depend on dart:io (for example some entity classes) and import this code from both app packages (browser and command line).

Opal (Ruby to JS compiler), GHCJS (Haskel to JS compiler), SharpKit (C# to JS compiler), Ceylon JS (Ceylon to JS compiler), FunScript (F# to JS compiler) ... they all try to do the same thing, make it possible to re-use your backend and frontend code between each other.

My question, how often do you actually re-use code between your frontend and backend and if so, how much code do you actually re-use? From my personal experience with GWT, there was very little code re-use between the frontend and backend, usually just my validation class which I don't really need in the frontend in any case and sometimes data transfer objects which became obsolete in any case since you can easily go to and from JSON these days.

What is your opinion, Is the whole selling point of code re-use between the backend and frontend overrated?

Adam Bene's photo

In the age of single-page apps (like Hashnode itself) and microservices, backend and frontend are usually totally decoupled.

And decoupled components should have well-defined interfaces - usually REST APIs.

When I have to share some logic between frontend and backend, I usually put it in a microservice so it can be used without any technology restrictions. It can be used from a native mobile app or a single-page app. It has a very low cost to replace any of these microservices.

Sandeep Panda's photo

I like Adam's (@adambene) answer. IMO, companies that are trying to build universal (isomorphic) SPAs will reuse a lot of code on backend and frontend. For example, Hashnode is a universal app. So, it's important for us to write components that can be rendered on both client and server. This is where you will need to reuse a lot of code between frontend and backend.

But when I used to build simple SPAs with Angular, I didn't reuse a lot of code on frontend. The only places where I reused code were form validations and other simple stuff. I don't think developers usually reuse a lot of code between client and server, unless they are building isomorphic apps.

Show +1 replies
Jan Vladimir Mostert's photo

Idea Incubator, Full Stack Platform Architect

I'm trying to gauge if throwing away code re-usability between browser and server is small enough to ignore those benefits and rather use two different languages optimised for the task at hand - this is obviously for non-isomorphic apps.

Sandeep Panda's photo

Co-Founder, Hashnode

@JanVladimirMostert Yes. I believe code reuse is minimal if you are not building isomorphic apps.

Shreyansh Pandey's photo

Applications these days rely on distributed, redundant and scalable microservices. Gone are the days when you could write an app in PHP with the Frontend and the Backend strictly coupled (PHP, seriously?)

I'll give you a simple model everyone uses these days: a frontend, usually written in AngularJS, Ember or React; a backend, say Node.js (because why not); a messaging stack, Redis or RabbitMQ. Personally, I prefer RabbitMQ and ZeroMQ for MQs. And a data tier: combination of volatile storage options, persistent storage options and what not.

If you're in a big team, sharing the code becomes redundant. I mean, seriously. If you see it in this way: frontend code is generally written for cross-browser compatibility; for server-side, stripping all of that code, re writing it for cluster management is a big pain.

However, there are times when you HAVE to use the code. Say, a database adapter or whatever. For that, I use the Universal Module Definition. Something like this:

( ( root, factory ) => {

    if ( typeof define === 'function' && define.amd ) {

        // 'define' is used in Async. Module Definitions
        define( [ '--Dependencies--' ], factory );

    } else if (typeof exports === 'object') {

        // Node/CommonJS export object
        module.exports = factory( require( '--Dependencies--' ) );

    } else {

        // Otherwise, attach it to the root object we provide
        root.attachedExports = factory( root.dependency );

    }

}( this, FACTORY_FUNCTION ) );

And then upload it to either a private NPM repo, or wherever I like. Works flawlessly across everything.

That was code sharing. If I have to share some services, I create a deployment pipeline, attached to the core process (the primary app requiring it) and then add some children (any other processes which want it). This eliminates a lot of security risk there is when sharing services and works very well.

Since these services are easy to deploy, it helps in scaling it as well.

Show +1 replies
Shreyansh Pandey's photo

node, coffee and everything in between

While designing the application, I make sure that I don't have to do that. However, there are times when you can't escape that. Say a websocket-based app. Writing code for the backend and the frontend is just a waste of time. I can't give you the exact numeric value, but for some projects it's 0% for some it's 5-ish. But that's it.

Jan Vladimir Mostert's photo

Idea Incubator, Full Stack Platform Architect

To me that sounds small enough to discard the benefits of code re-use between frontend and backend. Thanks for the comments!

Denny Trebbin's photo

I do it like @adambene. Putting the code into microservices.

That is, because of the corporate environment, I have to stay backend-agnostic. Google and other web crawlers can't parse our SPA's. Therefore, we don't need to care for SEO or having content inside of <noscript>. The first-page-hit looks a bit slow. But since we have our company CDN established, even that seems acceptable regarding speed. Additionally, we store web assets in HTML app cache. On corporate side we have 3000 office PC's across the globe, due to some routing issues, people can't judge if our side is slow due to Coding/Libraries/Frameworks or due to network issues.

On React.js Node.js apps, I am also not reusing much of the code. We cache web assets via service workers -> ponyfoo.com/articles/progressive-networking.. But we use a little different approach.

  1. On page load -> opac overlay with loading spinner rendered from static index.html
  2. Document ready -> Initialize the SPA
  3. Check if something according to URL is in service worker cache
    • If not -> React render() HTML, store render() result in service worker
    • If yes -> React fetch cached HTML and render it, React render() semi opac overlay with loading spinner, fetch current data
    • On data received -> destroy overlay, React render() HTML, store render() result in service worker

It's still not SEO friendly and it's also not progressive-enhancement, but getting stuff done.

Show +1 replies
Denny Trebbin's photo

node.js member. hacking web & mobile. love pixel perfect design. hate quick & dirty. conjuring in germany. kid of the 80s.

Exactly. I am not a big fan of sharing code between front end and back end. Putting business logic into front end for validation purposes and doing the same validation on back end again seems a bit like overkill and feels wrong to me. I can not really find much examples for when it's good to share the same code between front end and back end. It's only for SEO I can see benefits right now.

Tony Brown's photo

American Space Ninja

SSR will improve your performance and your SEO

Lars's photo

I use angular in the forntend so I don´t share any code with my NodeJS Express backend. I also use Microservices and because all have there own Database. For some Databases I wanted some extra Methods that wrapp around the actual NodeJS wrapper, I wrote a libary which I use in my microservices, so that they all use the same "wrapper of a wrapper". Thats the only code I "share".

When I need to communicate from the Frontend with a service (only api-service with routes to other services) I use a REST API. For communication between services I also use REST API´s but currently I add async routes like AMQP and MQTT which will be priamry and prefered, only in special cases or when RabbitMQ is down the REST API is used.

Ian Worthington's photo

Hi there, I just found this article by searching for this exact functionality. In my case I want to share my entire permission/authorization module onto the front end.

I have several elements on some pages which are shown or not shown depending on some complex if statements - which are written into my service layer (ASP.NET). At the moment I am calling these back end functions from JS - so they are being reused which is great, but each call costs 200-500 ms. They do all load in parallel which is nice, but I can see this becoming a huge problem if I decided to make table view of many many rows of data all with their own "management" buttons.

So at the moment this is making me thing that I want the exact same code which makes decisions about if a user is allowed to do a particular action on a particular entity - on the front end too. It would allow me to pass the users session, and the relevant object/entity into a function, and return a simple true or false. Exactly as I do now, but without having to travel over the network.

This may make me move from ASP to Node...

Jan Vladimir Mostert's photo

Idea Incubator, Full Stack Platform Architect

You can do that with Kotlin now, Kotlin in the backend and KotlinJS in the frontend which you can combine with React or Angular or whichever JS framework you prefer.

Write logic once, use twice