Introducing FabFit: The Tech Stack
1200 commits, two years, three rewrites, and every emotion it’s possible to experience — FabFit is ready to say Hello World.
Recently, I joined forces with my Mum to launch our first real product — FabFit — with the aim to make health and fitness accessible to all; no stigmas, no models in tiny clothes, just real people taking real classes and getting healthier, together.
FabFit, from a technological point has been quite a challenge and a steep learning curve from building advanced React components, a GraphQL backend, security best practices, custom user authentication, payment processing, filming and editing over 120 videos, and building a CMS to power it all. Not only all of that, but only building FabFit at night and on the weekends whilst working in a studio full-time has proven tricky and has taken way longer than expected.
Over the next few posts I want to cover the ups, the downs, the technology used and the lessons learned whilst building my first publicly shipped product.
This is the first of those posts: The Tech Stack. Let’s begin the whirlwind tour.
One thing is for sure, I would have shipped this thing a year earlier if I didn’t have this obsession of rewriting the codebase. Next time I’m going to aim to get something out of the door in a couple of weeks, not years.
Originally I was planning on using the WordPress API to power the application — I even attended Human Made’s A Week of REST to learn about the API and React first hand. An initial backend prototype was scaffolded and then it dawned on me, I’d have to keep writing PHP for the lifetime of the application, so that idea was quickly thrown away.
I then rebuilt the entire backend in Node, generating a REST API and that went really well. It was a good experience and a chance to deepen my understanding of Node.
But then, what seemed like out of nowhere; I started hearing about this GraphQL thing and it sounded too good to be true. Mid-2017 I opted to build a GraphQL API to power FabFit and I felt like Zeus himself had bestowed some mystical powers upon me.
I started prototyping the backend using GraphCool’s Backend-as-a-service, however, when the Prisma Beta launched I quickly jumped on that and haven’t looked back. For those looking to get into GraphQL — you can’t go wrong with Prisma (also, Apollo just launched Apollo Server 2 and it’s pretty sweet).
But it isn’t all about some shiny API. Mix in transactional emails, performant handling of images and video, payment processing, secure user authentication, tracking all users progress through classes, tutorials and programmes and out comes the below infrastructure. It’s slightly bigger than my original idea of a single WordPress instance.
Next is extremely easy to work with, it’s a beautiful mix of robustness and flexibility. It provides the server-side rendering so you don’t have to worry about, it also has a router built in and few extra niceties. Next has the added benefit of having a massive community around it, for me it was a no brainer.
To deal with the GraphQL API I plugged in Apollo. Why Apollo? Because Relay melted my brain and Apollo’s docs are great. Local state is also handed via
apollo-link-state, you won’t find any obtuse redux stores or mobX decorators anywhere in the application.
For styling I opted to use the built in
styled-jsx, however, if I was to rebuild the application I would do it with Styled Components.
FabFit is powered by a GraphQL API through Prisma. Prisma is our database layer which then couples with Gaia — our primary Node server handling all business logic. I was going to split everything into microservices but that was one buzzword too many for now. The experience of building something with Prisma is sublime; it’s fast, intuitive and flexible.
For transactional and marketing emails we’re using AWS Simple Email Service (I’ll be releasing a post shortly on how this is done). I tried a number of services such as SendGrid and two others I can’t remember. However, SES has an easy to use API that makes templating, customizing and distributing emails a breeze. For those email geeks out there I used MJML to build all of the emails.
All imagery is hosted on Cloudinary and uploaded via Houston (our custom CMS). Cloudinary works by some black magic that I’ll never understand, it’s incredible. It allows you to request any size or crop of image you require just by URL parameters. It also sends the best file type for that user’s device (JPG, WebP etc). ALSO it has really nice features such as face detection that you get for free, haven’t found a use for that but it blows my mind every time I see it.
And on the 7th day God created Stripe
Stripe powers all payments for FabFit, it is brilliant. Creation and management of users is really straight forward and then associating them with the correct payment plan is strangely simple — I’ve probably done something wrong. They also have a brilliant webhook feature that can hook into any event, such as a failed payment which I then use to trigger SES to send reminder emails or pause people’s accounts.
As you can see from the map above there are a few things going on, the infrastructure revolves around three core services — Zeit’s Now, AWS and Prisma Cloud.
Now is brilliant, it handles our core application server and the frontend application. There’s no need for CI to run the deployments since they are run and autoscaled from a single command:
yarn deploy:<APP> and are then aliased to their domains with
now alias <DEPLOYMENT> <URL> . Easy peasy.
- Ship faster. I’m working on a bunch of new features and improvements such as search, leaderboards, social logins as well as entire new sections and applications. I want to ship these in days, not months.
- Motivation is tricky. Motivation is a tough one, I love what I do and that definitely helps. However, when a project drags on that motivation can start to fade, particularly on the run up to the launch.
- It doesn’t have to perfect. This took me a lot of thinking, countless podcasts and audiobooks and half of Medium to understand. What I’m shipping doesn’t have to be the end product, no where near it in fact. Ship something that’s a little questionable and iterate on that.
Over the next 12 months I want to help FabFit grow; adding new features to the main web application (leaderboards, search), adding a nutritional section with recipes and meal plans, as well as building a suite of iOS, Android and TV applications. You can view our full roadmap at fab.fitness/roadmap, or the for more details you can even check out our internal roadmap.
Coming up in this series
- Building Houston — FabFit’s custom CMS
- SES Setup with Express
- Project Architecture
- Why GraphQL?
- Staying Motivated
- Film Production Setup
- Building Production Applications with Next.js