You can’t do IMAP in the browser, can you?

OpenPaas unified inbox

At Linagora we develop collaborative messaging software for more than 10 years. It all started with OBM, a full-featured groupware mainly developed in PHP and Java, and continues with OpenPaas, an open collaborative platform written almost exclusively in Javascript. We use Node.js for the backend and Angular.js (version 1) for the frontend.

In OBM we use Roundcube (one of the most famous webmail out there) for web-based email management. Roundcube works pretty well by using a combination of a HTML+Javascript frontend and a PHP backend. The typical scenario is as follows:

  • The frontend sends a “command” to the PHP backend (for instance “open the user’s INBOX folder” or “send ‘Hello John, how are you?’’ to”)
  • The backend translates the command to an IMAP request (for instance “SELECT INBOX”) or a SMTP request and sends it to the actual IMAP backend.
  • The backend receives the IMAP or SMTP response, analyses and parses it and sends back the data to the frontend (for instance a list of email messages)

Back in 2015, when we first discussed the architecture for OpenPaas, we needed to choose between two options:

  • Do like Roundcube and many other webmail software; have a Node.js backend doing the IMAP and SMTP heavy work and expose a lightweight API to the frontend. The frontend then uses the lightweight API to manage the user’s mailboxes, send emails, etc... →Straightforward, but not very technically interesting :)
  • Find another solution that allows us to develop the webmail application entirely in Angular.js and make it run completely in the browser, with no backend at all. →Technically interesting, yet difficult to implement for a very simple reason: you can’t open TCP sockets from the browser so you can’t do IMAP and you can’t do SMTP. All you can do is send HTTP requests.

Option 2 is interesting for a number of reasons, let aside the opportunity for us to be the first open-source Angular.js webmail with no backend :)

  • It eliminates the load on the application backend, by allowing the browser to connect to the email server directly.
  • It moves the application logic to the user’s browser (on a mobile phone, tablet or a desktop computer) and allows us to gain natural scalability by utilizing the growing power of devices.
  • It simplifies the code required to “make it work” by not having to convert from frontend calls to IMAP commands back and forth.
  • It’s pretty cool !

You got it, we chose option 2. An important technical note: in OpenPaas we develop both the frontend and the mail server (on top of Apache James) so we can implement almost anything in the mail server :)

It was now time for us to decide how we would implement the solution. And we discovered JMAP, a draft specification of a protocol that was particularly well-suited for what we intended to do:

  • The protocol is stateless.
  • It works over HTTP(s) which is good for us (you remember we’re inside a browser, right?) and uses JSON as the exchange format, which is rock-solid and native in the browser.
  • It uses the same set of APIs for the equivalent of IMAP and SMTP, simplifying even more the implementation by eliminating the need to understand the specifics of multiple protocols. It even support Calendars and Contacts synchronization, though we don’t use that.
  • It supports batching of operations, which means less round-trips to the email server, which means less network and battery usage (which means happy customers, by the way !)

So we moved on and used that, implementing both the backend and the frontend. And in an effort to gather a community around our product, we developed the JMAP-related code in an external Javascript library released under the MIT licence.

Stay tuned for the next episode where I’ll give you an overview of how easy it is to develop JMAP-compatible code with ES2015 !

Interested in joining us doing awesome code? Contact us on Github, on Twitter or apply to a job offer on our website.