Backend Development 11 min read

Technical Architecture of Worktile: SPA Design, Service Stack, and Real-time Messaging

Worktile’s architecture combines a single‑page AngularJS front‑end with a Node.js/Express backend, leveraging MongoDB, Redis, and ejabberd for real‑time messaging, illustrating how SPA design, modular services, and long‑connection techniques enable a stable, high‑performance team collaboration platform.

Architect
Architect
Architect
Technical Architecture of Worktile: SPA Design, Service Stack, and Real-time Messaging

Since its launch over two years ago, Worktile has attracted more than 100,000 teams, and its technical design had to address four key challenges: cross‑platform web access, native‑like client experience, efficient real‑time messaging, and overall service stability.

SPA Design

The team chose a single‑page application (SPA) approach to minimize page navigation. After evaluating Backbone.js and finding it too complex, they adopted AngularJS for its two‑way data binding, declarative syntax, modular architecture, and built‑in dependency injection.

Two‑way binding allows UI updates automatically when the underlying data changes, as shown in the following snippet:

<div class="entry-task-main" 
    ng-class="{1:'task-completed-style'}[task.completed]">
   <a class="entry-task-check" 
    id="task_check_{{ task.tid }}"
      wt-click="js_complete_task($event, entry, task)">
       <i ng-class="{0: 'icon-check-empty', 1: 'icon-check-sign'}[task.completed]"></i>
   </a>
   <a class="entry-task-title" href="javascript:;">{{task.name}}</a>
</div>

Semantic directives let developers express UI logic declaratively, for example:

<div ng-repeat="task in tasks">
    <wt-task view-type="item" show-project="false" 
           class="slide-trigger"
           hide_action="true"
           ng-click="locator.openTask(task.pid, task.tid)">
    </wt-task>
</div>

Modules are defined in a central AngularJS module, enabling clean separation of features such as projects, tasks, events, and files:

(function () {
   'use strict';
   angular.module('wtApp', [
       'wt.project.ctrl',
       'wt.team.ctrl',
       'wt.task.ctrl',
       'wt.event.ctrl',
       'wt.post.ctrl',
       'wt.file.ctrl',
       'wt.page.ctrl',
       'wt.mail.ctrl'
   ]);
}());

Dependency injection further reduces coupling between modules:

taskListCtrl.$inject = ['$scope', '$stateParams', 
           '$rootScope', '$popbox', 
           '$location', '$timeout', 
           'bus', 'globalDataContext', 
           'locator'];

Service Design

The backend follows a classic MEAN stack (MongoDB, Express, AngularJS, Node.js) complemented by an XMPP‑based messaging service. The overall service diagram is shown below:

Key backend components include:

API services (Web, Mobile, Open) built on Node.js for its asynchronous, event‑driven model and language uniformity across front‑ and back‑end.

Cache and queue services using Redis, leveraging its pub/sub capabilities for low‑latency notifications.

A MongoDB database, chosen for high performance, easy sharding, and natural fit with Node.js’s BSON format.

A file preview service that streams various file types; for Office documents the team integrates Microsoft Office Web App.

Message Push

Real‑time updates are essential for a collaboration tool. Worktile initially used Socket.IO, but as traffic grew the solution struggled with clustering and state storage. The architecture was later refactored to use ejabberd, an Erlang‑based XMPP server, together with Redis for presence storage.

Message types exchanged for task events are defined as follows:

on_task_trash            : "on_task_trash",
on_task_complete         : "on_task_complete",
on_task_move             : "on_task_move",
on_task_update           : "on_task_update",
on_task_comment          : "on_task_comment",
on_task_badges_file      : "on_task_badges_file",
on_task_unarchived       : "on_task_unarchived",
on_task_badges_check     : "on_task_badges_check"

Three push strategies are discussed:

Short polling – simple but low real‑time fidelity.

Long polling – server holds the request until data arrives, increasing load under high concurrency.

WebSocket – full duplex communication, requiring both client and server support.

Because ejabberd’s native WebSocket support was limited, the client uses Strophe.js over BOSH (XMPP over HTTP long‑polling) to maintain a persistent connection, as illustrated below:

Conclusion

The Worktile platform exemplifies a MEAN architecture enhanced with an XMPP‑based real‑time layer, demonstrating how careful selection of SPA frameworks, modular backend services, and efficient push mechanisms can deliver a robust, scalable collaboration product.

real-time messagingRedisNode.jsSPAMongoDBejabberdAngularJS
Architect
Written by

Architect

Professional architect sharing high‑quality architecture insights. Topics include high‑availability, high‑performance, high‑stability architectures, big data, machine learning, Java, system and distributed architecture, AI, and practical large‑scale architecture case studies. Open to ideas‑driven architects who enjoy sharing and learning.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.