EventSnaps is a platform that allows event organizers to seamlessly collect photos from guests. They can then choose to display these photos on an easily customizable website, with either public access or password protection.

Apr 2018

Style Guide

Style Guide.png

One of the first parts of the project I worked on was the development of a style guide. The purpose of this was to ensure consistency throughout the visual design of the product. This was especially important when I started to design and build components that used these typographic, color, and layer styles.

User Experience Flows

The next part of the project was to map out exactly what the users would be interacting with, and how. I created dozens of maps like these to detail what screens need to be built, how they would link together, and what features each would support. These translated directly into the high fidelity Sketch designs I worked on.

Visual Design


Next I used the experience maps to build components by functionality and then combined those components to design the screens. I designed versions of each screen for the various possible interactions a user could take with it and the resulting effect that would have.



The stack for EventSnaps is composed of a Node.js backend, using Feathers JS, and a React.js frontend. I choose to use MongoDB for the database due to the ease of storing variable data models. There were 4 “servers” in the project: one was responsible for serving the react app, one for serving the api, one for serving the public gallery pages, and one for dealing with user media assets. I also built 3 enviornments: development, staging, and production, each with different supporting services (i.e. Databases, Assets Storage, Mail Delivery, etc…). The platform was hosted on Heroku because of the ease of setup and abstraction of infrastructure.

API & Models

In total, the api server had over 30 endpoints and models to manage. Feathers.js makes managing an app of this scale fairly simple, by having you group related functionality into decoupled services.

One of the core features of the services was to allow users to submit photos in as many ways as possible without forcing them to download an app. This meant that I has to build content ingestion systems for SMS (using Twilio), Email (using Sendgrid), direct upload and from social media services. This was abstracted so that the content ingestion system was agnostic as to where the photos came from, they were handled in the same way.

I also developed a system that would automatically hide or prevent changes to fields marked as internal by external requests. This includes things like user passwords, stripe payment ids, and so on. The reason this was important is that a key attribute of Feathers.js is the compose-ability of services. This presented a problem because Feathers can already hide properties from external requests, but if for example, the Event Service queries the Payment Service and populates that data and then returns the result, a payment id might be exposed. This is because the Payment Service only hides the payment id from external requests and the Event Service is considered internal. Thus each model includes an _type property that determines its type, which is used to lookup which fields should be hidden. And one of the last steps before a response is returned, the entire response body is traversed recursively to look for these private fields and remove them.

The API server also included things like asynchronous job processors, file streaming to Google Cloud Storage, and a custom user authentication and management system.

React Frontend

The frontend react application, like the API server, was fairly complex. There were around 40 components in the entire app. I built a mix of data connected and functional components, but tried to push actual api connection up the hierarchy of components .

The frontend makes use of both realtime API requests with as well as normal REST requests using React Refetch. It includes drag and drop functionality to move elements around and for uploading media. It uses JWT tokens for authentication and automatically renews expiring tokens to allow the user to stay continuously logged in.


After weeks of work I decided not to ship the project for several reasons, chief among them was that I didn’t want to actually build a business around it. This project was mainly a way for me to test the skills I’ve developed as an engineer and designer. If you’re interested in seeing some more of the code or designs or want to try it out, shoot me an email!