How we built our mail notification service

Or, how developer experience (DX) is not a gimmick

One of our main goals we established when we started building the new ecosystem was to bring clarity, abstraction and simplicity, both in terms of the end-user experience, but also on how we, the developers, build our stuff.

One of the procedures that suffered from segmentation and mediocre design was the way we pushed mail notifications to users. This involved feeding events and payloads to either some rusty SGL — our proprietary scripting language) — scripts or to other legacy channels. As a result, the experience was inconsistent and super painful to modify.

To that end, we set to build the all-new BPMail platform.


  • Templates should be easy to build, change and deploy, even for a designer.
  • We should be able to continuously push changes.
  • A set of centralized components will have to drive the new facility to provide abstraction and consistency
  • Concerns should be separate.


  • React
  • Webpack
  • Jenkins
  • Yarn
  • Node
  • Jest
  • Babel
  • Docker
  • Rancher
  • Git
  • ..and quite some more.

Result — Work-flow

Here’s what we ended up with: A node and react based platform where we can efficiently reach all the goals set above; Designers can design and preview mail templates in their browsers (without even having to reload) and then a pipeline would generate those templates and push them to the servers. 1. Edit react components, preview in real-time on browser

We love React. React is powering and most of our intra tools. We also live and breathe on ES6. Webpack is our bundler of choice that does the magic behind the scenes

2. Happy with the results? Push!

We do everything on git — though it took us year to get there. Once we are happy with the preview, a git push is enough.

3. Jenkins takes over

Code is stored on Github. When a new branch is pushed, our Jenkins instance automatically:

  • builds and updates the staging server using that branch.
  • runs the test suite, for which we use Jest.
  • Builds sample “emails” and screenshots from our predefined demo-data.
  • Informs us on slack whether the build and tests were successful.

Assuming everything is — literary — green, next step would be the pull request. After review and merge, Jenkins repeats the above, and also deploys the compiled js files onto our live nodes using rsync.

The servers themselves are docker containers which have the js files mounted from local disk.

Then using nodemon, the node server is restarted when the files are updated. The containers are managed using Rancher, so scaling up or down is just a matter of clicking the + button, or asking our slack bot (nicely) :)

Bird’s-eye view

In order for us to have a bird’s-eye view of all our current templates, we introduced an additional step that generates screenshots of all our templates upon build (see the header image of this post). This way, we can easily spot mismatches and issues and provide changes and fixes.

How is it working out you asked?

Like a charm! For example, just yesterday, , our Illustrator, without any assistance or guidance from a developer, changed the content for a template, added a “happy easter” graphic globally (in the Footer component) and pushed it to production. It kind of sounds like magic and, by all means, it also feels like it is. We are happy with the result.

This is the resetPassword.jsx file used for ..well, guess :)

Watch this space, we shall have more to share soon!

Happy Easter!

Join us, !

BestPrice Dev

How we build stuff at

George Papadakis

Written by

CEO at, Co-founder of Phaistos Networks.

BestPrice Dev

How we build stuff at