00:00:11.210
hello thank you for coming today I'm going to share the story of how the team
00:00:17.789
at betterment secretly swapped out the entire front end for several of our apps last year in order to launch our new
00:00:24.480
brand identity my name is Chris LoPresto a lead front-end architecture at
00:00:30.779
betterment and I love helping engineering and design teams find ways to work better together I play some non
00:00:37.410
computer keyboards and you can find me at Chris LoPresto on github or Twitter
00:00:44.510
the last year betterments spent six months creating a new brand identity
00:00:49.680
this meant reimagining the company's mission statement photography style logo
00:00:55.590
color palette the entire user interface of our web and mobile apps online
00:01:00.840
calculators emails everything had to change so from start to launch the
00:01:07.260
entire project took six months it was the last two months stretch when we
00:01:13.110
built everything now this is an aggressive timeline we did it to ourselves the agency said expect at
00:01:19.920
least 12 months for the brand exercise so we said how about half how about half that we could aim for a better image
00:01:26.220
birthday it'll be at the end of May that'll be great they'll be after tax season so no one will freak out if their
00:01:31.290
tax storm suddenly look different it'll be before the summer because nobody reads press releases from the beach
00:01:37.729
where as it happens we delay it a little bit so in March this is what our
00:01:43.320
homepage looked like but by May we wanted the snez it up new colors
00:01:49.799
photography new content throughout all of veteran comm we wanted to apply this
00:01:55.140
brand to our retail app so this is what our summary page looked like in March
00:02:00.770
but May we wanted new navigation that new word mark in the top everything's
00:02:07.079
tighter it is on a grid system now investing involves risk past performance knockdown
00:02:13.830
tea future results but it does look like this user is about to have a really good two months so we got that going for us
00:02:23.580
this is what our portfolio page looked like basically the project requirements were you see that over there ya can't
00:02:30.570
look like that anymore so if this seems wildly impractical buckle up our mission was to redesign
00:02:39.000
everything in eight weeks in secret we want this time to big reveal all of our
00:02:44.640
apps change at once articles appear online and then we'll just bask in the beauty of our brand new brand then we
00:02:53.280
thought well since we already have to touch everything anyway while we're in the neighborhood what
00:02:59.400
have we made everything responsive you
00:03:04.650
know it never waits the crisis so what are you talking about here oh so these
00:03:13.050
designs were never gonna work at these small sizes it was going to take a lot
00:03:18.330
of work to get from that to this reconstruct all our CSS all our HTML by
00:03:25.230
May so you're probably thinking it's gonna be fine we'll just whip out our
00:03:31.709
trusty feature flag framework design system and get to work so at this point it is helpful if you already have one of
00:03:38.489
each which we do if you don't no worries hopefully this story piques your
00:03:44.550
interest now big projects are risky in part because they change a lot of code
00:03:51.410
one of the best ways to cope with this risk is by slicing your work up into tiny pieces and shipping them one at a
00:03:57.750
time now this means shipping incomplete work well that's okay you wait until it's ready you hide it
00:04:03.930
behind a feature flag and once it is ready flip a switch turn it off now a
00:04:10.140
huge advantage of this approach is that you can solve problems one at a time when they pop up you can see what's
00:04:15.750
working what's not change your mind about things and you're not jerking your users around as you figure all this out
00:04:20.780
but a rebrand is so big it touches everything like how do you put everything behind a feature flag
00:04:27.560
so at first we didn't know how but our engineering principles dictated that we had to find a way the only way to have a
00:04:35.129
worry-free launch day was to not ship any code on that day instead we'd have
00:04:40.409
to get to a point we were happy with flip the switch and turn it on the
00:04:45.720
betterments feature flag framework it's called test track it follows visitors and users across
00:04:52.139
devices we have clients for rails and JavaScript and all their mobile apps and we use it all the time to run
00:04:58.020
experiments and dark deploy features if you don't yet use feature toggles in your workflow you should definitely
00:05:04.289
consider it it'll change your life there's a few gems out there that make it really easy to go get going some
00:05:09.569
really great services out there but slicing of work doesn't do much good if
00:05:15.840
each slice ruins the last one which is often the case when CSS is involved so
00:05:25.319
for this project especially we needed to assemble new interfaces on the fly across multiple apps see what worked see
00:05:32.370
what didn't in the best way oh really the only way to do this efficiently and
00:05:37.710
creatively is that the component oriented design system which would give us reusable components now better inch
00:05:45.360
design system is called style closet lets us share patterns and components of
00:05:50.669
voc betterments look and feel across all of our apps now if you don't have a design system don't worry we had to
00:05:57.599
rewrite ours entirely as part of this project but the important thing to remember is that both test track and
00:06:04.229
style closet were already integrated in all of our apps so otherwise no way that
00:06:11.159
this eight-week project timeline would have been remotely possible investing in
00:06:17.370
our systems over the years it put us in a good position such that what once would have been deemed wildly
00:06:22.800
impractical actually became the basis of our project plan but we didn't know what
00:06:29.879
that meant at the beginning of the project we were just wondering how in the world are we going to do this like
00:06:35.789
forget Gantt charts and press releases we just need a halfway believable way to get this out the door
00:06:41.400
how can we get from here to there at all to which the engineer say I don't know
00:06:48.530
but also spike just do something it doesn't matter if your prototype is dumb
00:06:53.880
long as it's concretely dumb which is why I like to ask myself what's the
00:07:00.060
dumbest thing that could possibly work well here we go
00:07:06.440
we already ship a design system into each app so I thought what if we create
00:07:12.060
a rebranded version of the design system then each app already has a sass manifest what if we made a second one
00:07:19.380
they used the rebranded system behind a feature flag and then finally we know
00:07:25.890
that the new responsive designs need different markup so what if we had some view logic that understands the feature
00:07:31.680
flag and knows how to keep our world separate the stuff that's in production and all the new rebrand stuff it seems
00:07:38.910
reasonable enough so we got to work I spent about one minute writing the
00:07:45.720
beautiful rebrand CSS that you see here I wanted something garish so I figured you know white on blue ought to do and I
00:07:53.730
wrote some JavaScript to toggle these styles on in our design system doc site so with the old Styles the typography
00:07:59.400
demo looked like this but with the new vastly improved Styles it looked like
00:08:05.550
this and so it was at this point I'm you totally nailed it right so at this point
00:08:10.620
I started going up to designers one by one telling him I had started the rebrand project so they'd get really
00:08:16.230
excited then asked to see it and then I would show them this and it looks on
00:08:22.020
their faces varied but we had what we needed we had a way to do new style
00:08:27.510
stuff without messing up our old style stuff and we shipped this to production
00:08:32.580
we actually cut a minor version release of style closet and I met the next step
00:08:37.950
was to try to get this dumb stuff into an app behind the feature flag so the
00:08:45.120
upgraded retail to the latest version of style closet made a new rebrand sass manifest that pulled in the rebranded
00:08:52.410
system and this is what we wanted to put behind our feature flag so in our application layout we added
00:08:59.880
logic to use the new stylesheet if this test track feature flag rebrand enabled
00:09:05.970
was on now in public no one's gonna see this nonsense this feature flag is initially off for all of the users but
00:09:13.529
engineers working on the project or anyone else keeping tabs can use our test track Chrome extension to flip
00:09:20.399
rebrand enabled to true and get the new styles and we shipped this to production
00:09:27.839
on day 1 of the project on launch day all we had to do was log in to our test
00:09:33.120
track admin site and flip this rebrand enabled flag to true for everybody to go
00:09:39.329
live with the new brand now our designers being a serious bunch already
00:09:44.430
made me make my colors mildly less ridiculous but things are holding
00:09:49.829
together so far so for our last trailblazing trick we're gonna juggle
00:09:55.769
old and new markup at the same time I ported the CSS for a few of our cleaner
00:10:02.010
more modern components the header and progress bar and footer that you see here they said about making the demo
00:10:08.940
page work for both the old and new worlds that's when things started to get
00:10:14.730
a little weird right away we have CSS selectors that reference color the colors had changed so we're already
00:10:19.980
needed view logic for a pretty silly reason and there are much bigger markup changes coming I'm starting with this
00:10:25.860
SVG logo and the grid system but getting hacky and hand wavy things are holding
00:10:31.829
together pretty well so far so we decided to push ahead and see if this
00:10:38.339
would work in a real-world situation and an hour later we had an answer it did
00:10:45.000
not even on the simple pages I mean like most rails apps we used layouts to share
00:10:52.620
page structure and partials to share chunks of markup so even a hack this far
00:10:58.140
we needed a lot of logic in a lot of places and so far this was just a reskin
00:11:03.270
the actual redesigns we're gonna rearrange all of this content so I found myself gazing at this
00:11:08.850
ginormous SVG no longer so sure we'd be able to share one set of Marco let's
00:11:17.430
recap we're onto the ship a rebranded design system and we did it lots of work
00:11:25.380
to do but we're off to the races we wanted to use this new design system in our apps behind a feature flag then we
00:11:33.300
did it oh you already do that but as for
00:11:39.660
the view logic necessary to set up the new brand nope way too complicated not
00:11:45.630
gonna work but the good news is we're transitioning out of that terrifying
00:11:52.139
feeling at the start of a project when all we know is there's a bunch of things we don't know followed by a bunch of
00:11:59.850
more things we don't know we don't know let's pile of unknowns is best faced
00:12:04.889
head-on we strike out blazed a trail
00:12:10.069
we'll make sure one way or another we can get from wherever we are to wherever we need to be so we have our Styles
00:12:19.380
worked out but the tangled view logic showed us that what we really need is a separate view layer for this feature
00:12:25.949
flag because all of our problems will go away if we can just add rebranded versions of views without touching the
00:12:33.569
existing ones and have a bit of logic that just determines which one to show now this is a specific requirement for
00:12:41.040
its rails has a pretty great answer built right in action pack of variants
00:12:48.649
so whether you realize it or not like we're all familiar with the rails template resolver when a controller is
00:12:54.990
rendering a request it's the resolver that knows where to find the right view on the file system
00:13:00.089
so that's controller path slash show dot HTML the RB what I didn't know was that
00:13:07.680
after that HTML format the resolver checks for an optional variant that you can define so let's say that you have a
00:13:16.470
website that serves colorful high-res pictures of robots
00:13:22.180
but you're looking at your logs one day and suddenly realize that you have a lot of traffic from experimental Kindle
00:13:28.759
browsers that can't see color so you decide to optimize the images for their
00:13:34.399
black and white existence oh man here we go so the controller can do a browser
00:13:41.749
check and say hey there's a Kindle making this request I'm gonna set
00:13:47.119
request dot variant equals Kindle and that'll make the resolver first look for
00:13:52.189
a Kindle template if it doesn't find it it will fall back to the plain HTML er B
00:13:57.949
it's been serving the rest of us all along this is built right into rails so
00:14:03.259
luckily when I said out loud what we really need is a separate view layer for
00:14:08.779
this feature flag the coworker mine matter-of-factly replied well Whitney's a variant all we had to do is
00:14:18.379
move this rebrand enable check from our application controller our application layout into our application controller
00:14:23.749
it's a few lines of code and we were in business we realized we wouldn't have to
00:14:28.999
make changes to the existing views for the entire project then even better we could just delete them after he launched
00:14:34.370
their replacements we were excited it was additive and therefore completely safe to just make new rebranded versions
00:14:41.899
of everything we couldn't break anything even if we tried well challenge accepted
00:14:49.329
obviously we could obviously we did but our bugs ended up being real bugs
00:14:56.179
pertaining to real features not project config gotchas so our focus shifted to
00:15:04.220
all the stuff that needed changing we audited our design system all of our
00:15:10.850
apps came up with a long list of pages and components that needed to either be reworked or rebuilt entirely as we
00:15:19.160
thought about how long it would I'll take something had to give it's a style closet began life as a wait
00:15:26.929
to share pattern to cross our apps but it was tough going the apps weren't built with this system
00:15:32.629
in mind our components never just works when you drop them in there's always a fight perhaps all had these
00:15:38.630
complicated CSS code bases that few braved even fewer loved I actually
00:15:45.440
included captain Sully Sullenberger on this slide to assure us it's gonna all be okay well the fact of the matter is
00:15:54.320
as this peer reviewed totally factual study indicates CSS is hard it gets
00:16:01.580
harder as the team grows it gets harder as the code base grows an hour old our
00:16:07.700
old system suffered all of the usual pitfalls yes CSS is globally scoped he introduced
00:16:13.610
a new thing something else breaks so we'd compensate by scoping our rules no
00:16:20.060
more strictly and a show of strength that doesn't stop anyone else from making their change more important than
00:16:25.970
your but then perhaps most insidious is that in reality you have to use these
00:16:32.810
so-called reusable components that's your own risk
00:16:37.870
now swapping out our entire view layer represented an opportunity to start fresh with the new CSS architecture and
00:16:45.440
so we decided to rewrite our design system this isn't out of the blue we've
00:16:52.160
been working towards this we had internal prototypes drew inspiration from all manner of open source projects
00:16:59.270
and untold numbers of medium articles we were confident enough to make the leap because we felt we'd be able to move
00:17:05.600
faster with the new system then continue to fight the old one so we put together
00:17:12.800
a wishlist sensible defaults one at zero
00:17:19.339
config for an app to get going with the system default element styles so that
00:17:25.610
semantic markup automatically looked good we wanted cohesive systems for
00:17:31.400
spacing typography grid breakpoints color as well as the ability to apply
00:17:39.110
these system Styles consistently in either sass or with utility classes in our markup finally a suit CSS naming
00:17:48.590
convention it's like BAM so that our components could defend against inward and outward bleed to achieve true reuse
00:18:02.490
so let's dive in we built a lot we're gonna move through overly quickly we
00:18:09.090
created an exponential spacing scale that increments they're all multiples of four used it to create spatial
00:18:15.780
relationships within our components throughout all of our layouts every space you perceive so you could apply a
00:18:22.320
padding using this SC spacing function which was using a unit tested SAS
00:18:27.900
function if you were assembling page markup in an app we provided corresponding utility
00:18:33.390
classes built with those same SAS functions so to apply the same padding you could use a utility class selector
00:18:39.720
without needing to write CSS in the app we had a new color palette so he made a
00:18:45.930
conventional naming scheme so we had functional access in SAS we created
00:18:51.960
color and background color utility classes we had five primary colors for
00:18:57.090
secondary variants of each and then for betterments complex data visualizations we created a gradient system or the
00:19:03.780
hundred color stops for each primary color our previous responsive efforts
00:19:09.390
used an ad hoc set of max width media queries so we took the opportunity to research and standardize on a much
00:19:16.290
simpler set of min with media queries now constraining this breakpoint set allowed us to create responsive versions
00:19:22.560
of each utility class so it's easy to specify a default padding and then loosen it for larger viewports and still
00:19:29.760
not have to write additional CSS in the app we created a linear scale of
00:19:35.220
typography sizes based on the spacing scale we had font size line height combinations optimized for our new font
00:19:42.240
and then we'd adjust line Heights and some header font sizes responsibly in
00:19:48.780
keeping with our goal for semantic markup looking good by default we created a vertical rhythm system applied
00:19:55.110
as bottom margins to type of graphic elements again based on the spacing
00:20:00.270
scale adjusted responsibly we built the 12 column grid based on flexbox we had
00:20:07.170
fixed width gutters based on the spacing scale adjusted responsively
00:20:13.810
inspired by the Dropbox paper team we designed a new icon set in sketch on conventional art boards we wrote a
00:20:21.460
script that uses sketch tool to export SVG files optimize them generate view
00:20:26.680
partials and a corresponding rails helper so designers can now change or add icons by updating sketch and just
00:20:33.940
opening a pull request engineers can pop them on a page using this SC icon helper
00:20:39.400
and then we recently made this interactive icon builder in our design system Doc's site so that engineers can
00:20:45.490
generate the EOB for the icon they're looking for we built all the traditional
00:20:51.190
components design system classics like card and but but the first time though
00:20:58.330
these components were truly reusable we could put them in anywhere and they would work thanks to our suit CSS naming
00:21:03.700
conventions we could drop them in they'd all play nicely with each other but we
00:21:09.310
also built layout components we've built a built-in content slots and these components served a dual purpose it made
00:21:15.730
it easy for our teams to start building responsive pages so they did all the heavy lifting taking stacked content slides and then
00:21:22.000
putting them on the grid at larger viewport sizes but they also served as examples for our teams for how to build
00:21:27.850
these components with our new patterns and we built visualization tools so that
00:21:34.180
you could see the underlying content slots and grid these are actually all browser screenshots of better mint.com
00:21:41.200
visualized with our style closet chrome extension as we built each new piece we
00:21:46.990
use the visualization tool to check our work so suffice it to say an
00:21:52.690
action-packed productive few weeks with unprecedented levels of collaboration between our engineering and design teams
00:22:00.750
for the first time we had designs expressed by a system built with the system and then as teams began to use
00:22:08.320
the system we immediately noticed a step change in the pace of our UI development
00:22:15.390
pages that used to take a day would spring to life in about an hour engineers ended their demo saying I
00:22:21.370
didn't write any CSS and its responsive now I don't want to paint too rosy of a
00:22:27.700
picture there was a learning curve there was a lot of work but at this point we knew he had made all the right strategic
00:22:33.880
choices so the only remaining question was can we hit our deadline when can we
00:22:41.140
launch the new brand to the world and return to our regularly scheduled programming now a fixed date and a fixed
00:22:49.060
scope are not a winning combination we are stressed because we didn't seem to have a way to punt on anything like a
00:22:56.170
brand isn't something you can turn partway on we needed all of our pages to be in on the action we had two levers we
00:23:02.560
could pull the date or the scope we didn't want to shift the date and we didn't know how to shift the scope so
00:23:08.890
you're stuck so maybe just to lift our spirits let me look at everything we'd
00:23:14.590
already done we had used view variants to great effect we now had this secret rebrand mode that internal employees
00:23:20.770
were testing behind the feature flag and then while reliving the insight that led to this we had this moment of clarity or
00:23:28.050
deja vu or I don't know it may have been at media we just did the exact same
00:23:33.460
thing again and made a lighter-weight reskin mode so with just a few tweaks to
00:23:41.080
our variant logic we wired up a switch the teams could flip on to reskin a page
00:23:46.290
so the single line of code you'd get a new variant which meant new colors new
00:23:51.430
fonts and some breathing room because it wasn't gonna be the end of the world if a page or section wasn't quite done by
00:23:58.300
the launch deadline we could get on brand enough in the meantime without having to completely solve every last
00:24:03.670
technical problem and it yielded surprisingly good results we even chose to leave some of the deprecated systems
00:24:11.010
reskin permanently into their ultimate demise and deletion from our code base but most importantly we had decoupled
00:24:18.640
done from launched constraint really is
00:24:25.300
a wonderful thing so we were debriefing after the launch and kind of pondering how we would have arrived at these
00:24:30.580
results with their normal iterative processes and we're not sure that we would have we definitely not as
00:24:36.990
creatively and efficiently we shipped more code full of better
00:24:42.610
ideas more quickly than we thought possible and we eliminated far more debt
00:24:47.620
than we created some of us well we were
00:24:53.020
so relaxed when we're so okay not only did we hit our birthday launch date but we were so relaxed on that day if some
00:25:00.220
of us may or may not have been sound asleep when we flipped to that feature flag on constraints improved our plan
00:25:06.880
and improved our results quantifiably so
00:25:12.940
there's many many reasons to be careful when intensifying effort around project deadlines by definition you're
00:25:20.290
subverting the notion of sustainable development pace and it's a fantastic way to turn working software into buggy
00:25:26.050
software so we analyze pull request steps during and after the project now
00:25:32.020
because we're doubling down on the design system the style closet repository saw the most dramatic spike
00:25:37.600
there's 247 pull requests now for perspective this represented 49 percent
00:25:42.820
of style closet pull requests ever but that first half had been spread over two
00:25:48.340
and a half years not 54 days we shipped 44 releases of style closet which means
00:25:55.690
we were releasing every workday then we launched and we're immediately back to
00:26:01.090
normal so at the very least even accounting for recoil and recuperation there reflects a lack of panicky
00:26:07.510
show-stopping bugs with veteran comm you kind of see a calm before the storm we
00:26:13.960
knew all of the content was on its way out the door then you see this huge spike because we built an entire new
00:26:19.930
WordPress theme with our new design system then we turned it on on launch day and again immediately back to normal
00:26:27.930
now a retail app is part of a repository that contains other apps so there's not as clear of a signal here there's a
00:26:35.260
delayed spike partially because we were waiting for the design system partially because there was a bit of a rush to aim
00:26:40.600
for that deadline but then we're immediately below normal so we told ourselves it's probably easier to work
00:26:46.270
in the new world although it was now summer but we were thrilled this is what we had hoped to see
00:26:56.460
all right now let's take a look at all this CSS that we wrote the CSS rules are
00:27:02.890
assigned a numeric specificity highest score wins in the case of a tie last one wins
00:27:08.230
so Harry Roberts of CSS wizardry here with this sort of experimental notion of
00:27:13.450
a specificity draft on the x axis you plot rules based on their order in the
00:27:19.120
Cascade on the y axis you plot their specificity and he mused loosely
00:27:24.130
speaking this line should be smooth and trend upward is if you write a dodgy rule some poorer unfortunate rule that
00:27:30.700
comes after it will have to fight back then that'll show up as a jagged graph indicating developer pain so on the Left
00:27:38.380
we have style closet one some of our better CSS not great not bad on the
00:27:43.990
right we have style closet too it's much better smoother and it's a much lower specificity but it's really fun to see
00:27:52.000
and explain the graph features you kind of see our CSS reset it's flat that
00:27:57.190
first bump is actually a visualization tool flat then we see this tangle of some old form styles that we didn't have
00:28:03.909
time to rewrite and then at the end you see a bunch of our utility classes these are important by design so that our apps
00:28:10.299
can freely use them in their markup but this same analysis is so much cooler in
00:28:16.059
retail so on the left is the old CSS that was no fun to work with on the
00:28:23.500
right wait a second that's almost entirely style closet the in-app CEO
00:28:29.260
says it basically is all the way over on the right the system to app ratio is fantastic it means dramatically less
00:28:36.220
work in the app to build the features with the new system so that's quality
00:28:41.250
let's look at quantity way way way down retails CSS code base went from about
00:28:48.400
10,000 lines down to about 2,000 lines that's on par that we saw a betterment calm the old WordPress theme about
00:28:54.520
12,000 lines of CSS the new one about 2,000 lines of code now remember we're
00:28:59.799
not just matching functionality the new code base supports a dramatically improved user experience
00:29:05.920
and it adds all these components that made it possible to build all of our application interfaces from scratch as
00:29:13.510
quickly as we did well let's look at the payload size in a nutshell more system
00:29:20.410
way less at the app level the design system payload went up about 57% gzipped
00:29:27.040
from 23 to 36 K but if you look at retail shipping across the wire it
00:29:33.430
dropped by 54% 86 kg zipped now this is
00:29:39.100
far less CSS from a far more capable system and we actually have experimental
00:29:44.860
style closet 3 builds that are weighing in around 24 case or back down to the original payload size so with all of
00:29:53.500
that behind us what are we doing with our newfound leisure time
00:29:59.490
well standardizing the view patterns across all our apps freed up a lot of time and creative energy for a bunch of
00:30:05.860
new stuff we integrated web pack pipelines into all of our apps and we've
00:30:11.110
since built a rails component framework inspired by JavaScript frameworks it establishes a clean foundation for a
00:30:17.470
hybrid front-end architecture in which rails stimulus and react see to play a part and we're building form
00:30:24.400
interactions animation framework stated visualizations and lots of features all
00:30:29.710
based on the system we launched last year which has been improving by the day
00:30:37.320
so I was listening to a James Corden interview and he relayed something that his dad used to say that the difference
00:30:44.170
between doing something and not doing something is doing something if we
00:30:50.830
accomplished impractical things at a seemingly impossible timeframe all
00:30:55.990
because we made a decision to just do something to commit to shipping and to
00:31:02.170
commit to finding clever compromises in order to do so the stories of shared
00:31:08.500
involved dozens of people or eight action-packed stressful weeks problems and changes
00:31:14.670
mistakes and inventions distractions and debates we didn't lose their cool we actually
00:31:20.710
had a lot of fun cuz nothing really beats tackling tricky problems with good people thank you