Rank #1: Intro to Rush.js with Pete Gonzalez
In this episode, Pete Gonzalez joins the show to talk about everything Rush.js: What is it? What is it for? How do you use it? Find out here on The Frontside Podcast!
Pete Gonzalez | @octogonz
During the day, Pete works at HBO in Seattle on their streaming media apps. Prior to that, he was at Microsoft for 9 years, and before that, he worked at various consulting companies. A long time ago he was a cofounder of Ratloop, a small company that makes video games.
04:47 - Problems with Managing Large Codebases
- Rush Stack: provides reusable tech for running large scale monorepos for the web
07:22 - How does Rush provide a solution for build orchestration?
13:34 - Rush Stack Opinion: How to Lint, Bundle, etc.
24:27 - Getting Technical About Versions
32:47 - Thoughts on Monorepos
36:30 - Getting Started (Cont’d) + Efficient TypeScript Compellation
43:28 - Does Rush have a size limit? Is it for bigger or smaller projects? Both?
44:34 - Using pieces of Rush in non-Rush projects?
Please join us in these conversations! If you or someone you know would be a perfect guest, please get in touch with us at firstname.lastname@example.org. Our goal is to get people thinking on the platform level which includes tooling, internalization, state management, routing, upgrade, and the data layer.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
Jun 25 2020
Rank #2: Big Ideas & The Future at The Frontside
In this episode, Charles and Taras discuss "big ideas" and all the things they hope to accomplish at The Frontside over the next decade.
Please join us in these conversations! If you or someone you know would be a perfect guest, please get in touch with us at email@example.com. Our goal is to get people thinking on the platform level which includes tooling, internalization, state management, routing, upgrade, and the data layer.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, a place where we talk about user interfaces and everything that you need to know to build them right. Today, we're going to talk about big ideas and the future of Frontside.
TARAS: Yeah, starting with is Frontside is good idea?
CHARLES: No, we're going to just talk about how do you know that an idea is good? We've touched on it a couple of times before. Like how do you, how do you go about validating a big idea, how do you discover a big idea? What do you do?
TARAS: And then, even when you have big ideas like big tests, what does that mean for the world? How do you make a big idea an idea that a lot of people like and agree with and actually use on day to day.
CHARLES: Yeah. It turns out that it's not easy. There's a lot of work involved with that. A lot of it crystallized around the conversations we're having about what exactly is big test and recognizing that big test isn't really a code base. It's not a toolkit. Even though it does has aspects of those things, it really is an idea. It's an approach. It's a way of going about your business, right?
TARAS: Yeah. Especially when you put big test functionality in place, when you start doing big testing and then you put together things like using Mocha and Karma, big tests in that kind of test suite is really just like interactors and the idea of big testing. There's nothing else. All the interactors do is just give you an easy way to create composable like [inaudible] objects, so you don't have to write -- you have the components but you don't have to write selectors for each element in the component, especially if gets composed. But that's like a very small functionality that does a very specific thing. But big test itself, it takes a lot of work to actually -- we had this firsthand experience on the project we're working on right now. We are essentially introducing like Ember's acceptance testing but for React in a react project and having to explain to people what is it about this that actually makes it a really good idea and having people in the React world see that this is actually a really good idea. It's kind of incredible. When you actually try to sell something to somebody and convince somebody that this is a good idea is when you realize like how inadequate your understanding of the idea really is. You really have to start to break it down and understand what is it about this that is a really big idea.
CHARLES: Yeah, I completely agree 100% because to be clear, we've actually been doing this now for two years almost. So, this is not the first React project where we've put these ideas in place. But I think in prior examples, we just kind of moved in and it's like we're going to do this because this is what we do. And we have firsthand knowledge of this working because we've operated in this community where this is just taken on faith that this is the way you go about your business. You have a very robust acceptance test suite. And because of that, you can experience incredible things. When you and I were talking before the show, we were kind of commenting on inside the Ember community, you can do impossible things because of the testing framework. You can upgrade from Ember 1 to Ember 3 which is a completely and totally separate framework, basically. You're completely and totally changing the underlying architecture of your application. You can do it in a deterministic way and that's actually incredible.
TARAS: And what's interesting too is that the React core team kind of hinted a book at this also in their blog post about fiber or moving to fiber because one of the things that they talked about there is that knowing how the system is supposed to behave on the outside allowed them to change the internals of the free app framework, specifically about test suite for the React framework, but it allowed them to change the internals of the framework because they were testing kind of on the outside. The system kind of is a black box and that allowed them to change the internals and the test suite essentially stayed the same. So this idea of acceptance testing your thing is really fundamental to how Ember community operates. But other communities have this as a big idea as well. It's just applied in different areas.
CHARLES: Right. And so applied to your actual application, this is something that's accepted in one place, but it's not an accepted practice in other places. But you can make your argument one of two ways and say, "I have experienced this and it's awesome. And you can do architectural upgrades if you follow the patterns laid out by this idea." And that works if you have a very, very high, high trust relationship, but you don't always have that, nor should you. Not everybody is going to be trusting you out of the box. So, you're going to have to lay out the arguments and really be able to illustrate conceptually practically how this is a good idea just so that people will actually give it a try.
TARAS: And it takes a lot. One of the reasons why it was easier for us to introduce big testing to the current project we're working on is because we were able to write, like we've done the implementation for this in a previous project. So when we were convincing people this is a good idea, we're like, "Look, your test suite can be really good. It's going to be really fast. And look, we've done it before." So the actual process of convincing people that a big idea is a really good idea is actually kind of a complicated process that requires a lot of work and partially requires experimentation. You have to actually put an implementation in place and show that you're going to have to build up on your successes to be able to get to a point where you can convince people that this is actually a really good idea. People who have not heard about this idea, and especially people who might have counter, like they have people of authority in their community that have counter views. For example, quite often when it comes to big tests, when you bring up big tests, people will reference a blog post by a Google engineer that talks about how functional testing or acceptance testing is terrible. And for a lot of people, a Google engineer means a lot and the person makes really good points. But that's not the complete idea. The complete idea is not just about having an acceptance test suite. It's a certain kind of acceptance test suite. It's an acceptance test suite that mocks out at boundaries so you don't make API requests to the server, you make an API request to a [inaudible] server using something like Mirage or whatever that might be. So, the big idea, it has like new ones that makes it functional, but getting people who are completely unaware, who don't necessarily look up to you as an authority to believe you like, "Yes, that actually sounds like a really good idea." It is not a trivial task.
CHARLES: No, it's not. Because the first time you try and explain it, you're arguing based on your own assumptions. So, you're coming to it safe in the knowledge that this is a really, really good idea based on your firsthand knowledge. But that means you're assuming a lot of things. You're assuming a lot of context that you have that someone else doesn't and they're going to be asking questions. Why this way, why this way, why this way? And so, you have to generate a framework for thinking about the entire problem in order to explain the value of the idea. And that's something that you don't get when it's just something that's accepted as a practice.
TARAS: I think simulation is actually a really good example of that. If you haven't had experience with Mirage, if you don't know what having a configurable server in your tests does for you, you will probably not realize that similar ideas apply to, for example, Bluetooth that when you're writing tests for your Bluetooth devices, or you're writing tests for an application that interacts with Bluetooth devices, you actually want to have a simulation there for Bluetooth so that you can configure it in a kind of similar way to the way you would configure a Mirage for a specific test. You want to be able to say, "This Bluetooth device is going to exist," or, "I have these kinds of Bluetooth devices around me, they have the following attributes. They might disconnect after a little while." There's all kinds of scenarios that you want to be able to set up so that you can see how your application is going to respond. But if you haven't seen a simulation with something like Mirage, you're going to be going like, "I don't know what the hell why would this be helpful."
CHARLES: It seems like lot of work. One of the things that we've been working on, as I said, is trying to come up with a framework for thinking about why this is a good idea because we can't just assume it. It's not common knowledge. For example, one of the things that we've been developing over the last year and more recently in the last few months is trying to understand what makes a test valuable. At its essence, what are the measures that you can hold up to a test and say this test has X value. Obviously, something like that is very, very difficult to quantify. But if you can show that and you say, "This test has these quantities and this test has these quantities," then we can actually measure them. Then it's going to allow people to accept it a lot more readily and try it a lot more readily. So, the ideas that we're playing with right now is that you kind of have to evaluate a test on one on speed, tests that are fast, have an intrinsic value, or rather test that are slow. The upside that you gained from the test is very quickly bled away or offset if the test is slow. So, I can have a very comprehensive test that tests a lot of high value stuff. But if it takes three days to run, it's going to be basically worthless. Another axis on what you can evaluate is in terms of coverage. I'm not talking about coverage of lines of code. I'm talking about use cases and units of assemblage. So, there's the module. Those modules are then stitched together into components. Those components are stitched together into applications. Those applications are downloaded onto browsers. And I would consider it a different unit of assemblage. Your application running on Firefox is a different assemblage than your application running on Chrome, is a different assemblage than your application running. You have this access, which is the coverage of your unit of assemblage. That's another way that you can evaluate your tests. So if I have a test that runs only on Node in a simulated dom, there's a cap, there's an absolute cap on the value of that test and it cannot rise above a certain point. And the other thing, another access that we've identified is isolate ability, an ability to run a test. So if I have a test suite comprised of 1500 tests, but if one fails in the middle, I have to restart the test from the beginning. That's going to decrease the value. Maybe it's related to speed, being able to run the tests without having to install a bunch of different dependencies. So that's another access. And so trying to really understand the variables there, that's something you have to be very systematic about thinking about the tests so that you can actually take your idea and explain it to someone who's not coming at it from first principles. Imagine you have to explain an if statement to somebody who's never programmed with an if statement before.
TARAS: That is going to be very difficult.
CHARLES: It's going to be difficult, right?
TARAS: Yeah. In general, it's very challenging to go from an experience that somebody had, like overriding somebody's experience conveying your own personal experience is very difficult. And getting someone to experience something is very difficult. And so that's what I think a lot of the work that we've been doing over the last little while has been breaking down these problems into a way of understanding them so that we can actually explain why these things are important. Like what we've had to do this recently with a Bluetooth work that we've been doing. We have a partner that's implementing a Bluetooth abstraction for mobile devices and trying to convey to them the value of being able to simulate devices. That's something that we saw with Mirage. We knew that being able to simulate devices in tests in different environments is extremely valuable. We know this firsthand from our experience. But trying to justify to them why we think this is important and why they should rejig all of their thinking about how they're going to architect this middle layer between the native APIs and the application APIs, why they should rejig this layer to make it so that it will allow for simulation, like convincing very technical, very knowledgeable and experienced people that these ideas are important, it requires kind of fundamental understanding of the value that they provide.
And I think this touches on what really I think Frontside is going to be doing going forward is creating conditions for this kind of thought to be cultivated, to be able to create business environment where our clients gain benefit from this kind of very deep insight, insight that transcends the source of those ideas. Because there are certain ideas that are really fundamental and they're beautiful ideas. For example, in React world, a functional component is a really beautiful idea. It's a really simple concept. And kind of going along along with what you're saying about this kind of fundamental ideas, they will drive you to the next point you couldn't even imagine. I think the work that the React core team has done -- they've set out this functional component as a primitive, but it wasn't possible for a long time to really make the functional component a reality until they've gone through the process of actually understanding what connects all the dots so that you could eventually get to a point where like, "Oh, actually this [inaudible] API is a way for us to enable the fundamental concept of having a component." Not only is it simple, but it actually works. You can write a performance application using this fundamental concept. So, the work that we're going to be doing is first of all, making it possible to have conversations at this level. So, people that we're going to be working with Frontside, clients who we work with, companies that work with us, who partner with us, it's going to be all to support creating this environment where we can have this kind of ideas. Then being able to extract these great ideas from the frameworks and actually making them available across frameworks. You don't have to be locked into a specific community to be able to benefit from that.
One of the first steps we're working on now is now that we have an understanding about big tests, we believe this is a good idea, we have ways to justify why it's a good idea. We have clients who have benefited from this good idea. Now we're in position to fill in the gaps that are missing from big tests, from being something that could be used in any framework. We want it to be really easy for people to be able to say, "I really love acceptance testing, but I have to work in a React project or I have to work in a Vue project, I have to work in an Angular projects." It's like, "It's no problem. I have big tests. Big tests is going to give me what I want." The big tests, the idea, but it's going to come with all the little pieces that you need to be able to assemble the functional test suite that is going to give you the benefits that Ember's acceptance test suite provides for Ember projects.
CHARLES: I mean, why should you have to compromise on these things. If it is a good idea and it is a fundamental idea, whether it's how you manage concurrent processes, whether it's how you manage testing, whether it's how you manage routing, why should you have to compromise? Why should you have to say, "You know what? I love..." I don't know, what's a comparable system? "I love air conditioning." Why should I have to go into a car that doesn't have air conditioning? Because every single car has a different air conditioning system, or every single house has a different air conditioning system. I'm showing the fact that I live in Texas here by using this example. But we've developed air conditioning systems that are modular so that they can be snapped on to pretty much any house and you don't have to build a custom thing for the circulation and refrigeration of air every single time or have it just be like it's part of the house. Or we have this wood that ships with ducks. It's like, no, we want to separate out that system.
TARAS: You don't have to commit to living in a specific area to get the benefit of being comfortable. You don't have to give up the comfort for specific areas. The good idea of air conditioning is not restricted to just one area. You can actually experience it wherever you go and have it be available wherever you would go. You have to be able to, like if you're moving to a new house, you can install air conditioner and now you're going to have like cool air. That's the kind of the theme I think of what we're going to be doing. But there's so much work to do because we're kind of, I would say, probably 30 or 40% into having -- if we were to look at like big tests as a big idea is used and is well known in our industry, we're probably maybe 5% on that. If we take into consideration what it takes for us to be able to convey what it takes to convince people is a good idea. I think we're, if you add to it, we'll probably add another 15%. So the next step is actually creating some tooling around it that would make it really easy for people to consume. Because right now, what's really unfortunate is that you have big tests that is available. If we set it up in the React project, doing it with create-react-app right now is kind of difficult. So we're going to make that easier. But then companies still need to make a choice between the ergonomics [inaudible] Cypress or the speed and the comfort and the control that you have with big tests. We have to basically eliminate the need to make that choice by making the tooling that you get in Cypress and making that tooling available for big test projects.
So that is going to kind of bring us up to maybe 60%. And then the remaining part is taking the software that enables the big idea and then making the software work across all different frameworks so that it's really easy to install. On Angular, it's just going to be add a plugin and it gives you big testing. You don't have to rely on their unit testing or you don't have to rely on the end to end testing as using Selenium. You just have big tests and it works just as well as it works and React and just as well as it works in Ember. So you can get the benefits of that. Going through the whole process and then bringing into the world this way, we have a lot of work to do because every part of the architecture of building modern frontend applications requires this level of effort. If you look at routing, routing is extremely inconsistent across frameworks. There are different opinions for every framework. There are different opinions of how to implement it. And that's problematic both on an individual level and a specific project level because it's so hard to know what you should use. And in many cases, it's not complete. What constitutes a routing system on React looks different than what would be in Ember, and it looks different than what it is in Angular. And each one of them has their own trade-offs. So if you find yourself in a situation where you've been using React and now you have to use Angular, you have a steep learning curve. But this also has an interesting effect of like, "Well, we have a world now where micro frontends are a thing." There are really good reasons why companies might want to use multiple frameworks for single platform because different frameworks have different benefits and different teams based on their location might prefer a different framework. There's lots of different reasons why companies choose and we want developers to be able to choose specific framework. But how do you do that when you need to have basically micro frontend architecture, you need to provide an SDK that provides a consistent user experience like -- you need to provide an SDK that provides a consistent developer experience, but then that developer experience because it's developer experience, needs to enable consistent user experience regardless of what framework the team decides to use. So now, routing needs to be more robust. Routing without having a strong concurrency primitives is going to be very limited and it's not going to be as portable across frameworks as one that actually has very robust concurrency primitives.
So now we'll start looking at concurrency. We've got concurrency primitives that are different for each framework. We've got Ember concurrency, we have a Redux-sagas. We have observables. React is introducing suspense and their hooks. And now each one of those things is different. So now, we need a concurrency primitive that is framework agnostic that is externalized, that we can consume to build stuff. Now that's a piece of the routing system. There's other things like state machines. State machines are an important part. If you look at the authentication system, the core of an authentication system is a state machine. How do you express a state machine in a way that is framework agnostic, in a way that works in every framework. That's an area that we need to explore. So, there's a lot of work for us to do to take these big ideas and externalize them from the framework so that they can be consumed by frameworks. And the applications that use this frameworks, that is a lot of work. And that's essentially what Frontside is setting out to do is hold these good ideas and extract the pieces that are actually core to these ideas. And then make them available independently and then see what that will provide. In a world where we have all of these pieces in place and we have kind of the granular little pieces that we need to be able to have a really strong concurrency primitive, we have a great routing system that's using this concurrency primitives. We have a state machine mechanism that can work with any framework, has very comfortable APIs. We have all these pieces. What kind of collaboration will that allow? What is the world that that will create? I think for people who are in the Ember community, we saw firsthand what it means for us to stand the shoulders of giants. We have wonderful, brilliant people creating really awesome tools. Now, if that same level of collaboration was happening in a way that was framework agnostic, but we were all standing on shoulders of giants and we were helping each other create something like this, what kind of world would that create? That's what Frontside is setting out to find out.
CHARLES: Yeah, and it's going to be fantastic. I should say it's going to be really, really fun. It's going to be challenging. Like you said, there is a lot of work to do.
TARAS: A lot of conversations to have. I mean, I think it's difficult to have these conversations because we all have good reasons for thinking certain things and a lot of times it requires understanding each other to find the place. Core teams do this. It's getting everybody to align on where we want to go, provide leadership like doing all of that work and doing it in a way that is actually possible. Because to create an environment with this kind of research that is happening, it requires a lot of money. Charles and I cannot do this. A small group of people probably cannot do this either because we need real use cases. We need real projects to make sure that these ideas are not dream implementations or just like vaporware. We need the pressure of real projects, real clients' relationships to create software that is going to make a huge difference for their developers. So we need those relationships with clients so that we can actually create the conditions for this kind of thing to emerge. That needs to also happen for us to make this kind of a situation possible. So, there is a lot of work to do but it's a really worthwhile cause.
CHARLES: And I think that it's one of the reasons that we start with testing as the most important use case because it's something that you don't want to be just saying, "Hey, you want to come help us fund research to make everything better?" There is real pressure, there's financial pressure and there's a duty to make sure that if a project has a deadline, that deadline is met. You want to come in at cost and on time. That's the goal of every project. And you want to try and strive to do your best to achieve that. And testing is an area where the research almost always pays off. I mean, where it has clearly. You can invest a lot of money and get a lot of reward in return because you're losing so much money by not testing or by focusing your investment in testing on lower value targets.
TARAS: For people that are familiar with acceptance testing, I think that just goes like a no brainer. Acceptance testing just enables you that. So by putting big test as a first kind of objective, but putting acceptance testing as a first kind of milestone, it sets us up to benefit in the way that Ember community has benefited where the acceptance test now became a mechanism that made it possible for the framework to change. And so, we're kind of setting up the same conditions here. When you start working with us or with any of the companies that work with us, the first benefit you get is you get the acceptance testing. Now, developers are more productive because they know that they have a certainty that if something broke, they will know. If they broke something, they will know. But what that also gives us is a way of introducing change in a systematic way. So, if we find that we have a new routing mechanism, we can start to refactor our React router setup to use this new routing mechanism and we can do it safely because we have our acceptance testing in place. So in many ways, it's kind of like the first step. And it's actually a great first step for business and is a great first step for tech technology. That's kind of a really awesome overlap.
CHARLES: In the podcast with Dylan Collins, we talked about this is like step one is make experimentation cheap because experimentation can be wildly expensive and you can throw away a lot of money if you're just experimenting without constraints. And there is nothing like a great application/acceptance test suite that puts those constraints in a completely and totally unambiguous way. So I think that's actually a great summary of our next decade.
TARAS: Yeah, I think so too. I think it's a good to show you the perfect next step. And I think this is going to show us the perfect next future though we can't really imagine it right now. But I do know one thing, this future is going to include a lot of people. Fundamentally, what we're setting out to do is a big idea. And so, big ideas are brought to the world by a lot of people. And I think one of the things that's important is that from day one, we include everyone in the process. For anyone who's interested in these big ideas, we want to make it possible for you to participate in. So that's the reason why Frontside is going to have an RFC. Like on our Frontside website, we're actually going to start writing and publishing RFCs. The first RFC that we're going to have is going to be for big tests, which is to lay out why big test is a big good idea for frontend for our industry. And as we start talking to people, there's actually lots of applications beyond frontend. So, we're going to focus on writing these RFCs and sharing them with the world so that we can include as many people in it as possible so everyone can participate. And ultimately, hopefully, that will have an influence on our industry and actually allow us to leverage these big ideas in a way that is not tied to any particular source of these brilliant ideas.
CHARLES: Yeah, hat tip to the Ember community for the whole RFC thing, which I guess they didn't invent either.
TARAS: Yeah, they borrowed it also, sorry. But I mean, it's been adopted everywhere. And I think it is a really interesting way of making people part of your process and making it our process as our meaning, like everyone who works with us. Whether you work for Frontside, that there's a client of Frontside or you work with the company that is partner with Frontside, whatever that might look like, we want to start to create places where we can be having these conversations and together surfacing these great ideas and making them part of a tool sets.
CHARLES: I think that's a perfect way to wrap up. Like I said, you pretty much described our next decade. Maybe if we get more people, it's going to be significantly less and we'll move onto the next thing even more rapidly. I am fully pumped. I'm ready to see this. There's a lot of work to do and I feel great about getting to it.
TARAS: I'm very excited about all the work that we're going to be doing, so let's get to it.
CHARLES: Yup. All right. We'll see everybody next time.
Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at firstname.lastname@example.org. Thanks. See you next time.
Oct 03 2019
Rank #3: Transparent Development
In this episode, Charles and Taras discuss "transparent development" and why it's not only beneficial to development teams, but to their clients as well.
Please join us in these conversations! If you or someone you know would be a perfect guest, please get in touch with us at email@example.com. Our goal is to get people thinking on the platform level which includes tooling, internalization, state management, routing, upgrade, and the data layer.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, the place where we talk about user interfaces and everything that you need to know to build them right.
It's been a long summer and we're back. I'm actually back living in Austin, Texas again. I think there wasn't too much margin in terms of time to record anything or do much else besides kind of hang on for survival. We've been really, really busy over the last couple of months, especially on the professional side. Frontside has been doing some pretty extraordinary things, some pretty interesting things. So, we've got a lot to chew on, a lot to talk about.
TARAS: There's so much stuff to talk about and it's hard to know where to start.
CHARLES: So, we'll be a little bit rambly, a little bit focused. We'll call it fambly. But I think one of the key points that is crystallized in our minds, I would say over this summer, is something that binds the way that we work together. Every once in a while, you do some work, you do some work, you do some work, and then all of a sudden you realize that a theme, there's something thematic to that work and it bubbles up to the surface and you kind of organically perceive an abstraction over the way that you work. I think we've hit that. I hit one of those points at least because one of the things that's very important for us is -- and if you know us, this is things that we talk about, things that we work on -- we will go into a project and set up the deployment on the very first day. Make sure that there is an entire pipeline, making sure that there is a test suite, making sure that there are preview applications. And this is kind of the mode that we've been working in, I mean, for years and years and years. And where you say like if what it takes is spending the first month of a project setting up your entire delivery and showcasing pipeline then that's the most important work, inverting the order and saying that has to really come before any code can come before it. And I don't know that we've ever had like a kind of unifying theme for all of those practices. I mean, we've talked about it in terms of saving money, in terms of ensuring quality, in terms of making sure that something is good for five or 10 years, like this is the way to do it. And I think those are definitely the outcomes that we're looking for. But I think we've kind of identified what the actual mode is for all of that. Is that fair to say?
TARAS: Yeah, I think one of the things I've always thought about for a long time is the context within which decisions are made because it's not always easy. And it's sometimes really difficult to really give it a name, like getting to a point where you have really clear understanding of what is it that is guiding all of your actions. What is it that's making you do things? Like why do we put a month of work before we even start doing any work? Why do we put this in our contract? Why do we have a conversation with every client and say, "Look, before we start doing anything, we're going to put CI in place." Why are we blocking our business on doing this piece? It's actually kind of crazy that from a business perspective, it's a little bit crazy that you be like, "Oh, so you're willing to lose a client because the client doesn't want you to set up a CI process?" Or in a case of many clients, it's like you're not willing to accept -- the client is going to say, "We want to use Jenkins." And what we've done in the past, in almost every engagement, we're like, "Actually, no. We're not going to use Jenkins because we know that it's going to take so long for you to put Jenkins in place. By the time that we finish the project, you're probably still not going to have it in place. That means that we're not going to be able to rely on our CI process and we're not going to be able to rely on testing until you're finished." We're not going to have any of those things while we're doing development. But why are we doing all this stuff? It was actually not really apparent until very recently because they didn't really had a name to describe what is it about this tooling and all of these things that makes why is it so important to us. I think that's what kind of crystallized. And the way that I know that it's crystallized because now that we're talking to our clients about it, our clients are taking on to picking up the language. We don't have to convince people that this is a value. It just comes out of their mouth. Like it actually comes out of their mouth as a solution to completely unrelated problems, but they recognize how this particular thing is actually a solution in that particular circumstance as well even though it's not something Frontside sold in that particular situation. Do you want to announce what it actually is?
CHARLES: Sure. Drum roll please [makes drum roll sound]. Not to get too hokey, but it's something that we're calling Transparent Development. What it means is having radical transparency throughout the entire development process, from the planning to the design, to the actual coding and to the releases. Everything about your process. The measure by which you can evaluate it is how transparent is this process to not just developers but other stakeholders, designers or people who are very developer adjacent, engineering managers all the way up to C level executives. How transparent is your development? And one of the ways that we sell this, because I think as we talk about how we arrived at this concept, we can see how this practice actually is a mode of thinking that guides you towards each one of these individual practice. It guides you towards continuous integration. It guides you towards testing. It guides you towards the continuous deployment. It guides you towards the continuous release in preview. I think the most important thing is that it's guided us, by capturing this concept, it's guided us to adopt new practices, which we did not have before. That's where the proof is in the pudding is if you can take an idea and it shows you things that you hadn't previously thought before.
I think there's a fantastic example. I actually saw it at Clojure/conj in 2016, there was a talk on juggling. And one of the things that they talked about was up until I think it was the early 80's or maybe it was the early 60's, the state of juggling was you knew a bunch of tricks and you practice the tricks and you get these hard tricks. And that was what juggling was, is you practice these things. It was very satisfying and it had been like that for several millennia. But these guys in the Physics department were juggling enthusiasts and I don't know how the conversation came about, you'd have to watch the talk. It's really a great talk. But what they do is they make a writing system, a nomenclature system for systematizing juggling tricks, so they can describe any juggling trick with this abstract notation. And the surprising outcome, or not so surprising outcome, is that by then, once you have it in the notation, you can manipulate the notation to reveal new tricks that nobody had thought of before. But you're like, "Ah, by capturing the timing and the height and the hand and we can actually understand the fundamental concept, and so now we can recombine it in ways that weren't seen before." That actually opened up, I think an order of magnitude of new tricks that people just had not conceived of before because they did not know that they existed.
And so, I think that's really, as an abstract concept, is a great yardstick by which to measure any idea. Yes, this idea very neatly explains the phenomenon with which I'm already familiar, but does the idea guide me towards things with which I have no concept of their existence? But because the idea predicts their existence, I know it must be there and I know where to look for it. And aha, there it is. It's like shining a light. And so I think that that's kind of the proof in the pudding. So that's a little bit of a tangent, but I think that's why we're so excited about this. And I think it's why we think it's a good idea.
TARAS: Yes. So what's also been interesting for me is how universal it is. Because the question of is this transparent enough? That question could be actually asked in many cases. What's been interesting for me is that asking that question in different contexts that I didn't expect actually yielded better outcome. At the end of the day, I think that a test for any idea is like, is it something that can help you more frequently than not? Like is it actually leading you? Does applying this pattern, does it increase the chances of success? And that's one of the things that we've seen, thinking about just practices that we're putting into place and quite asking are they transparent enough? Is this transparent enough? It's actually been really effective. Do you want to talk about some of the things that we've put in place in regards to transparency? Like what it actually looks like?
CHARLES: Yeah. I think this originally started when we were setting up a CI pipeline for a native application which is not something that we've typically done in the past. Over the last, I would say, 10 years, most of our work has been on the web. And so, when we're asked to essentially take responsibility for how a native application is going to be delivered, one of the first things that we asked kind of out of habit and out of just the way that we operate is how are we going to deliver this? How are we going to test it? How are we going to integrate it? All the things that we've just talked about is something that we have to do naturally. But because this is not very -- like continuous integration and build is very prevalent on the web. I think that testing still has a lot of progress on the web, but it's far more prevalent than it is in other communities, certainly the native community. So when we started spending a month setting up continuous integration an integration test suite, spending time working on simulators so that we could simulate Bluetooth, having an automated process with which we could ship to the App Store, all of these things kind of existed as one-offs in the native development community. There are a lot of native developers who do these things. But because it's not as prevalent and because it was new to us, it caused a lot of self reflection both on why is it that we feel compelled to do this. And also we had to express this, we had to really justify this work to existing native development teams and existing stakeholders who were responsible for the outcomes of these native development teams. So, there was this period of self reflection, like we had to write down and be transparent about why we were doing this.
TARAS: Yeah. We had to describe that in SoWs. We actually had really long write ups about like what it is that we're setting up. And for a while, it was, people I think would read these SoWs and I think they would get the what's of what we're actually going to be putting into place. But it wasn't until we actually put it into place and we've seen a few like really big wins with the setup -- one of the first ones was the setting up preview apps where preview apps in -- the web are pretty straightforward because we've got Netlify that just kind of gives it to you easily.
CHARLES: Netlify and Heroku. It's very common.
TARAS: Yeah, you activate it, it's there. But on the mobile side, it's quite a different story because you can't just spin up a mobile device that is available through the web. It's something kind of very special. And so we did find a service called Appetize that does this. And so we hooked up the CI pipeline to show preview apps in pull requests. So for every pull request, you could see specifically what was introduced in our pull request without having to pull down source code, like compile it. You could just click a link and you see a MVC stream of a mobile device and that application running on a mobile device. So the setup took a little bit of time. But once we actually put it in place and we showed it to our clients, one of the things that we noticed is that it became a topic of conversation. Like, "Oh, preview apps are amazing." "This is so cool." "Preview apps are really great." And I think in some ways, it actually surprised us because we knew that they were great, but I think it was one of the first times that we encountered a situation where we would show something to a client and they just loved it. And it wasn't an app feature. It was a CI feature. It was part of a development process.
CHARLES: Right. So, the question is then why was this so revelatory? Why was it so inspiring to them? And I think that the reason is that even if we have an agile process and we're on two week iterations, one week iterations, whatever, there's still a macroscopic waterfall process going on because essentially, your business people, your design people, maybe some of your engineering people are involved at the very front of the conversation. And there's a lot of talking and everybody's on the same page. And then we start introducing coding cycles. And like I said, even if we're working on two week iterations and we're "agile", the only feedback that you actually have, whether something is working, is if the coder says it's done. "I'm Done with this feature. I'm on to the next feature for the next two weeks." And after that two weeks, it's like, "I'm done with this feature. I'm on to the next feature." From the initial design, you have the expectation about what's going on in the non-technical stakeholders minds. They have this expectation. And then they hope that through the process of this agile iterative development cycles, they will get the outcome that satisfies that hope. But they're not able to actually perceive and put their hands on it. It's only the engineers and maybe some really tech savvy engineering managers who can actually perceive it. And so they're getting information secondhand. "Hey, We've got authentication working and we can see this screen and that screen." And, "Hey, it works on iOS now." "I have some fix ups that I need to do on Android." So, maybe they're consuming all of their information through standups or something like that, which is better than nothing. That is a level of transparency. But the problem is then you get to actually releasing the app or whether it's on the web, whether it's on native, but this is really a problem on native. You get to where you actually release the app and then everybody gets to perceive the way the app as it actually is. So you have this expectation and this hope that was set maybe months prior and it just comes absolutely careening into reality in an instant, the very first moment that you open the app when it's been released. And if it doesn't meet that expectation, that's when you get disappointment. When expectations are out of sync and grossly out of sync with reality, even a little bit out of sync with reality, you get disappointment. As fundamental and explanation of just the phenomenon of disappointment, but it's an explanation of why disappointment happens so often on development projects. Is this kind of the expectations and hopes of what a system can be in the minds of the stakeholders? It's kind of this probability cloud that collapses to a single point in an instant.
TARAS: And that's when things really hit the proverbial fan. Now, you have the opposite. So everything that was not transparent about your development process. So everything that was hidden in the opaqueness of your development process, all of those problems, either on a product side, maybe something didn't quite get implemented the way it's supposed to. Like you actually found out two weeks or three weeks before you're supposed to release that that feature wasn't actually quite implemented right. It went through testing, but it was tested against the Jira stories that were maybe not quite written correctly. So the product people are going like, "What the hell is this? It's actually not what I signed up for. This is not what I was asking for." So, there's that part.
And then on the development side, you've got all of the little problems that you didn't really account for because you haven't been shipping to production from day one. You actually have like application not really quite working right. You didn't account as supposed to integrate with some system that is using Chorus or something you didn't account for. Like you have a third party dependency you didn't really fully understand. But because it wasn't until you actually turned it on that you actually started to talk to the thing properly, and you realize there's some mismatch that is not quite working. But now you've got everything that was not transparent about the development process, everything that was hiding in the opaque corners of your development process is now your problem for the next three weeks because you've got to fix all of these problems before you release. And that's what I think where a lot of organizations kind of find themselves in is this position where they've been operating for six months and like, "Everything is going great!" And then three months or three weeks before, you're like, "Actually, this is not really what we were supposed to do. Why did this happen?" That time is really tough.
CHARLES: Yeah. That's what we call crunch time. And it's actually something that is lot of times we think of it as inevitable, but in fact it is actually an artifact of an opaque process.
CHARLES: That's the time when we have to go, everybody's like, "We're ordering pizza and Dr. Pepper and nobody's leaving for a month."
TARAS: Yeah. I think there are people that do that practice like functional testing as part of development process or acceptance testing, I think they could relate to this in some cases where if you had to set up a test suite on an application that was written without a test suite, first thing you deal with are all the problems that you didn't even know were there. And it's not until you actually start testing, like doing functional testing, not integration or unit testing where you're testing everything in isolation, but when you're perceiving the entire system as one big system and you're testing each one of those things as the user would, it's not until that point you start to notice all the weird problems that you have. Like your views are re-rendering more than you expected. You have things that are being rendered you didn't even notice because it's hard to see, because it happens so quickly. But in test, it happens at a different pace. And so, there's all these problems that you start to observe the moment that you start doing acceptance testing, but you don't see them otherwise. And so, it's the process of making something transparent that actually highlights all these problems. But for the most part, if you don't know that there are transparent options available, you actually never realize that you are having these problems until you are in crunch time.
CHARLES: Right. And what's interesting is viewed through that lens, your test suite is a tool for perception. And to provide that transparency, not necessarily something that ensures quality, but ensuring the quality is a side effect of being able to perceive bugs as they happen or perceive integration issues at the soonest possible juncture. To shine the light, so to speak, rather than to act as a filter. It's a subtle distinction, but I think it's an important one.
TARAS: About functional testing and acceptance testing. I think one of the things that I know personally from experience working with comprehensive acceptance test suites is that there is certainty that you get by expressing the behavior of the application in your tests. And I think what that certainty does is it replaces hope as opposed to having hope baked into your system where you think like you're hoping. I think for many people, they don't even perceive it as hope. They perceive it as reality. They see it as, "My application works this way." But really what's happening is there's a lot of trust that's built into that where you have to say like, "Yeah, I believe the system should work because I wrote it and I'm good. And it should not be broken." But unless you have a mechanism that actually verifies this and actually insures this is the case, you are operating in the area of dreams and hopes and wishes, and not necessarily reality. And I think that's one of the things that's different. A lot of the processes around highlighting or shining light on the opaque areas of the development process. And it's actually not even just development process. It's actually the business process of running a development organization. Shining light in those areas is then what gives you the opportunity to replace hope with real validatable truth about your circumstances.
CHARLES: And making it so that anyone can answer that question and discover that truth and discover that reality for themselves. So, generating the artifacts, putting them out there, and then letting anybody be the primary perceiver of what that artifact means in the context of the business, not just developers. And so, that kind of really explains preview apps quite neatly, doesn't it? Here we've done some work. We are proposing a change. What are the artifacts that explain the ramifications of this change? So we run the test suite. That's one of the artifacts that explains and radiates the information so that people can be their own primary source. And look at it in a developer centric, although you can tell, any old person can tell if the test suite's failing, it's not a change that we should go with. But the preview app is something we take this hypothetical change, we build it, we put it out there and now, everyone can perceive it. And so, it calibrates the perception of reality and it eliminates hope. Which is like if your development process is based on hope, you are signing yourself up for disaster. I like what you said that it implies a huge amount of trust in the development team. And you know what? If you have a cracked development team, that trust is earned and people will continually invest based on that trust. But the fundamentals are still fragile because they still can open up a crack between the expectation and the reality. And the problem is when that happens, the trust is destroyed. And it's during that crunch time, if it does happen that you lose credibility and it's not because you became a worse developer. It's not because your team is like lower performing, it's just that there was this divergence allowed to open. But then the problem is that really lowers the trust and that means that unfortunately that's going to have a negative knock on effect. And reasonably so. Because if you're an engineering manager or a product manager, you're something like this and you're losing trust in your development team and their ability to deliver what you talked about, then you're going to want to micromanage them more. The natural inclination is to try and be very defensive and interventionist and you might actually introduce a set of practices that inhibit the development cycle even further and lower the team's abilities to perform right when they need to do it the most, then you end up destroying more trust.
TARAS: Yeah, it's a spiraling effect I think because it's in the process of trying to make things better. And then you start to introduce practices. Like maybe you're going to have meetings every day reviewing outstanding stories to try to get everybody on the same page, but now you're micromanaging development team. The development team starts to resent that and now you've got this like people hating their job. It starts to get messier and dirtier and more complicated. And the root cause of that is that from day one, there was a lot of just [inaudible] about getting into it and just starting to write some code but what you didn't actually do is you didn't put in place the fundamentals of making sure that you can all observe a reality that is honest. And I think that kind of fundamental principle, it's interesting how when you actually start to kind of take this idea and when you start to think about it in different use cases, it actually tells you a lot about what's going on and you can actually use it to design new solutions.
One of the things that Frontside does, I don't know if those who've kind of worked with us before might know this or might not, but we don't do blended rates anymore. Because we don't actually, one of the challenges with blended rates is that they hide the new ones that gives you the power to choose how to solve a problem.
CHARLES: Yeah. There's a whole blog post that needs to be written on why blended rates are absolute poison for a consultancy. But this is the principle of why.
TARAS: Yeah. I think it's poison for transparent consultancy because if you want to get the benefits of transparency, you have to be transparent about your people. Because alternatively what happens is that you start off relying on your company's reputation and then there is a kind of inherent lie in the way that the price points are set up because everybody knows that there is going to be a few senior people, there's going to be a few intermediate people, a few junior people. But these exact ratios of those or who is doing what, how much people are available, all of those things are kind of hidden inside of the consulting company so that they can manage their resources internally. And so what that does is it simplifies your communication with the client. But actually what it also does is it disempowers you to have certain difficult conversations when you need the most. And you could say, "Look, for this kind of work, we don't need to have more senior people working on this." We can have someone who is junior who is at like $100 an hour, $75 an hour as opposed to being $200 or $250 an hour. We can have that person working on this and we can actually very clearly define how certain work gets solved. It requires more work. But then what it does is it creates a really strong bond of honesty and transparency between you and your clients. And it gives you a way, like now the client starts to think about you as a resource that allows them to fulfill on their obligations in a very actionable way. They can now think about how they can use you as a resource to solve their problems. They don't need a filter that will process that and try to make it work within the organization. You essentially kind of become one unit. And I think that sense of unity is the fundamental piece that keeps consulting companies and clients glued together. It's the sense of like, "We can rely on this team to give us exactly what we want when we need it, and sometimes give us what we need that we don't know we need." But that bond is there. And that bond is strong because there is no lie in that relationship. You're very transparent about who are the people that's working on it. What are they actually going to be doing? How much is this costing us?
CHARLES: It's worth calling out explicitly whether on the flip side of it is, is if you have a blended rate, which is the way that Frontside operated for, gosh, pretty much forever, is that people will naturally calibrate towards your most senior people. If I'm going to be paying $200 an hour across the board, or $150 an hour across the board, or $300 across the board, whatever the price point is, they're going to want to extract the most value for that one price point. And so, it means that they're going to expect the most senior people and become resentful if what I'm paying is $300 for a task. If I've got five senior people, it's a better deal for me. For the same price to get five senior people than two senior people to a medium level people and one junior person. And so, it has two terrible effects. One is that they don't appreciate the senior people to be like, "Hey actually, these are people with extraordinary experience, extraordinary knowledge, extraordinary capability that will kick start your part." So they are under appreciated and then they're extremely resentful of the junior people. It's like, "I'm paying the same rate for this very senior person as I am for this junior person? Get this person off my project." But if you say, "You know what, we're going to charge a fifth of the cost for this junior person and we're going to utilize them," then you're providing real value and they're appreciating it. They're like, "Oh, thank you for saving me so much money. We've got this task that does not require your most senior person. That would be a misallocation of funds. I'd be wasting money on them. But if you can charge me less and give me this junior person and they're going to do just as competent a job, but it's going to cost me a fifth of the money, then that's great. Thank you." So, it flips the conversation from 'get this god-damn junior person off my project' to 'thank you so much for bringing this person on'. It's so critical. But that's what that transparency can provide. It can totally turn a feeling of resentment into gratitude.
TARAS: What's interesting is from business perspective, you make the same amount of money. In some cases, you actually make more money. I think in that way, it's a consulting company. But that's not the important part because the amount of value that's generated from having more granular visibility into what's happening is so much greater. It's kind of like with testing where any of those things where when you start to put, when you start to shine light on these kind of opaque areas and then you start to kind of flush out the gremlins that are hiding there, what you then start to do, what you kind of discover is this opportunity to have relationships with clients that are honest. So you could say, for example, like one of the things that we've done recently is we actually have like 10-tier price point model, which allows us to to be really flexible about the kind of people that we introduce. So, there's a lot of details that go into the actual contracting negotiation. But what it does is it allows us to be very honest about the costs and work together with our clients, like actually really find a solution that's going to work really well for them. And then this is kind of a starting point when we start thinking about transparency in this kind of diverse way, you actually start to realize that there are additional benefits that you might have never been experienced before. One of the things that we found recently is that one of the initiatives that we kind of launched with one of our clients is we wanted to bring together, there's a general problem that exists in large projects, which is that if you have a really big company and you have like, let's say 20 or 30 interconnected services, your data domain, like the older data, kinds of data you work with is spread over a whole bunch of microservices spread over potentially a bunch of different development teams spread over a bunch of different locations. What usually has happened in the past is each one of those problems or the domain, the data domain has been kind of siloed into a specific application. We worked with a bank in the past and that being had for every, they had 80 countries. In each country they had 12 different industries, like insurance and mortgage and different kinds of areas of services they offered. And then for each of the country, for each of the service, they had a different application that provided that functionality. Then the next step is, let's not do that anymore because we now have something like 100, 150 apps, let's bring it all together under a single umbrella and let's create a single shared domain that we can then use. And so, a GraphQL becomes a great solution for that. But the problem is that making that change is crazy complicated because the people on the business side who understand how all the pieces fit together. On the other side, you have the developers who know where the data can come from and how to make all that real. And on the other side is there's like frontend implementers who actually build in the UIs that are consuming all these services.
On a project that we're working on right now is we're building a federated GraphQL gateway layer that is kind of connecting all these things, bringing all these things together. But the problem is that without very specific tooling to enable that kind of coming together of the frontend, the backend, the business people having coming together, creating a single point of conversation and having a single point of reference for all the different data that we have to work with and different data that is available to the gateway, without having something like that, without having that transparency in the actual data model, it is really difficult to make progress because you don't have shared terminology, you don't have shared understanding of the scope of the problem. There's a lot of dots in context that needs to be connected. And for anyone who has worked with enterprise, you know how big these problems get. And so what we've done on a project that we're working on now is we actually aimed to bring transparency to this process. What we actually did is put in place, start to build an application that brings together all of the federated services into a visualization that different parties can be involved in. And so I think one of the kind of common patterns that we see with transparency in general is that we are including people in the process, in the development process that were previously not included. So in the past, they would be involved in the process either very early on or very late in the process, but they wouldn't be involved along the way. And so what this kind of transparency practice actually does is it allows us to kind of democratize and flatten the process of creating foundations for pieces that touch many different parts of the organization. And so this tool that we created allows everyone to be involved in the process of creating the data model that spans the entire organization and then have a single point of reference that everybody can go to and have a process for contributing to it. They don't have to be a developer. There's developers who consume it. There are business people that consume it. There are data modeling people that consume it. Like there's different people parties involved. But the end result is that everyone is on the same page about what it is that they're creating. And we're seeing the same kind of response as we saw with preview apps where people who previously didn't really have an opinion on development practices or how something gets built, all of a sudden they're participating in the conversation and actually making really valuable suggestions that developers couldn't really have exposure to previously because developers often don't have the context necessary to understand why something gets implemented in a particular way.
CHARLES: Something beautiful to behold, really. And like I said, it's wonderful when a simple concept reveals things that had lay hidden before.
TARAS: Yeah. It's a very interesting lens to look at things through. How transparent is this and how can we make it more transparent? I think asking that question and answering that question is what has been kind of giving us a lot of -- it had been very helpful in understanding our challenges in the work that we do on a daily basis and also in understanding how we could actually make it better.
CHARLES: I apply this concept in action on my pull requests. I've really been focusing on trying to make sure that if you look at my pull request, before you actually look at the code, you can pretty much understand what I've done before you even look at the diff. The hallmark of a good pull request is basically if by reading the conversation, you understand what the implementation is going to be. There's not really any surprises there. It's actually hard to achieve that. Same thing with git history. Spending a lot of time trying to think like how can I provide the most transparent git history? That doesn't necessarily mean exactly the log of what happened moment to moment, day to day, but making sure that your history presents a clear story of how the application has evolved. And sometimes that involves a lot of rebasing and merging and branch management.
I think another area that has been new for us, which this has revealed those things that I just described are areas where we're kind of re-evaluating already accepted principles against a new measure, but introducing an RFC process to actually a client project where we're making architectural decisions with our developers, the client's developers, external consultants. You've got a lot of different parties, all of whom need to be on the same page about the architectural decisions that you've made. Why are we doing this this way? Why are we doing modals this way? Why are we using this style system? Why are we using routing in this way? Why are we doing testing like this? These are decisions that are usually made in an ad hoc basis to satisfy an immediate need. It's like, "Hey, we need to do state management. Let's bring in Redux or let's bring in MobX or let's bring in whatever." And you want to hire experts to help you make that best ad hoc decision? Well, not really. I mean, you want to lean on their experience to make the best decision. But having a way of recording and saying this is the rationale for a decision that we are about to make to fulfill a need. And then having a record of that and putting it down in the book so that anybody who can come later. First of all, when the discussion is happening, everybody can understand the process that's going on in the development team's head. And then afterwards and it's particularly important is someone asks a question, "Why is this thing this way?" You can point directly to an RFC. And this is something that we picked up from the Ember community, but this is something that open source projects really by their very nature have to operate in a very highly transparent manner. And so, it's no surprise that that process came from the internet and an open source project. But it's been remarkably effective, I would say, in achieving consensus and making sure that people are satisfied with decisions, especially if they come on afterwards, after they've been made.
TARAS: We actually have this particular benefit that could experience that particular benefit today where one of the other things that this RFC process and transparency with the architecture, how that kind of benefits the development organization is that a lot of times when you are knee deep in doing some implementation, that is not a time you want to be having architectural conversations. In the same way like in a big football team, they huddle up before they go on a field. You can't be talking strategy and architecture and plans while you're on the football field. You have to be ready to play. And this is one of the things that the RFC process does is it allows us to say, "Look, right now we have a process for managing architecture so that with the RFC process you can go review our accepted RFCs. You can make proposals there." And that is a different process than the process that we're involved in on a daily basis, which is writing application, using architecture where we have in place. And so that in itself can be really helpful because well intentioned people can bring up these conversations because they really are trying to solve a problem, but that might not be the best time. And so having that kind of process in place and being transparent about how architecture decisions are made allows everyone to participate and it also allows you to prioritize conversations.
CHARLES: Yeah. And that wasn't a practice that we had adopted previous to this, but it's something that seemed obvious that we should be doing. It's like, how can we make our architecture more transparent? Well, let's do this practice. So, I keep harping on this. But I think it's the hallmark of a good idea if it leads you to new practices and new tools. And we're actually thinking about adopting the RFC process for all of our internal developments, for maintaining our open source libraries.
TARAS: There is something that we've been working on that we're really excited about. So, there's a lot of stuff happening at Frontside. But one of the things that we've been doing is working on something we call the transparent node publishing process, which is something that I think we originally drew inspiration from the way NativeScript has their repo set up. But one thing that's really cool about how they have things set up is that every pull request automatically is available, like everything is available. Very quickly, a pull request is available for you to play with and you can actually put it into your application as a published version in npm and actually see exactly if that pull request is going to work for you. You don't have to jump through hoops. You don't have to clone the repo, build it locally, link it. You don't have to do any of that stuff because if you see a pull request that has something that you want but then is not available in master, there's an instruction on the pull request that tells you, "Here's how you can install this particular version from npm." And so you essentially you're publishing. Every pull request automatically gets published to npm and you can just download and install that specific version for that particular pull request in your project. That in itself I think is one of those things I suspect that is going to be talked about. It actually can alleviate a lot of problems that we have on a development processes because like the availability of the work of people who are participating in the project, there is kind of a built in barrier that we are essentially breaking down with this transparent node publishing process. And so, that's something that we're very close to to having it all on our repos and we're going to try it out and then hopefully share it with everyone on the internet.
CHARLES: I didn't know that the NativeScript did this. I thought that the idea that came from it is like how can we apply these transparency principles to the way we maintain npm packages. The entire release process should be completely transparent, so that when I make a pull request, it's available immediately in a comment. And then furthermore, even when a pull request is merged, there's no separate step of let's get someone to publish it. It's just now it's on master. Now it is available as a production release. You close the latency and you close the gap and people perceive things as they are. There is nothing like, "Oh that emerged. When do I get this?" This is something that I can't stand about using public packages is you have some issue, you find out that someone also has had this issue, they've submitted a pull request for it and then it's impossible to find if there's a version and what version actually supports this? And it's even more complex between projects that actually do backporting of fixes to other versions. So I might be on version two of a project. Version three is the most recent one, but I can't upgrade to version three because I might be dependent on some version two APIs. But I really need this fix. Well, has it been backported? I don't know. Maybe upgrading is what I have to do, but maybe downgrading. Or if I'm on the same major release version, maybe there's been 10 pull requests, but there's been no release to npm. And it can be shockingly difficult to find out if something is even publicly available. And the transparency principle comes in to, "Hey, if I see it on GitHub, if I see it there, then there's something there that I can touch and I can perceive for myself to see if my issue has been resolved or if the things work as I expect."
TARAS: I'm really excited about this. I'm really excited about this kind of clarification, this crystallization of transparency. And I'm also seeing our clients starting to apply it to solving problems within their organization as well is very inspiring.
CHARLES: Yeah, it is. It is really exciting. And honestly, I feel like we've got one of those little triangular sticks that people use to find water. I feel like we have a divination stick. And I'm really excited to see what new tools and practices it actually predicts and leads us to.
TARAS: Me too. I'm really excited to hear if anyone likes this idea. Send us a tweet and let us know what you're seeing for yourself about this because I think it's a really interesting topic and I'm sure there's going to be a lot that people can do with this idea in general.
CHARLES: Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside, or over just plain old email at firstname.lastname@example.org. Thanks and see you next time.
Sep 26 2019
Rank #4: Svelte and Reactivity with Rich Harris
Rich Harris talks about Svelte and Reactivity.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, a place where we talk about user interfaces and everything that you need to know to build them right.
TARAS: It's actually a really nice, Rich and I'm really, really happy to have a chance to actually chat with you about this because Svelte is a really fun piece technology. In many ways, it's interesting to see our technology evolve and our industry evolve through innovation, real innovation. I think Svelte 3 has really been kind of that next thought provoking technology that kind of makes you think about different ways that we can approach problems in our space. So, really excited to chat with you about this stuff.
RICH: Well, thank you. Excited to be here.
TARAS: I think quite a lot of people know, Rich, about your history, like how you got into what you're doing now. But I'm not sure if Charles is aware, so if you could kind of give us a little bit of a lowdown on where you kind of come from in terms of your technical background and such.
CHARLES: It's interesting that this D3 and all that did come out of journalism.
CHARLES: And so, are you still working for the same company?
RICH: No. That's ancient history at this point.
CHARLES: Because I'm wondering, are you actually getting to use these tools that you've been building to actually do the types of visualizations and stuff that we've been talking about?
RICH: Very much so. I moved to The Guardian some years ago. And then from there, moved to Guardian US, which has an office in New York. And it was there that I started working on Svelte. I then moved to the New York Times and I'm still working on Svelte. I've used it a number of times to build things at the New York Times and the people have built things with it too. And so, yeah, it's very much informed by the demands of building high performance interactive applications on a very tight deadline.
CHARLES: Okay, cool. So I've probably used, I mean, I'm an avid reader of both Guardian and the New York Times, so I've probably used a bunch of these visualizations. I had no idea what was driving them. I just assumed it was all D3.
RICH: There is a lot of D3. Mike Bostock, the creator of D3, he was a linchpin at the graphics department for many years. Unfortunately we didn't overlap. He left the Times before I joined the Times, but his presence is still very much felt in the department. And a lot of people who are entering the industry, they're still becoming database practitioners by learning from D3 examples. It's been a hugely influential thing in our industry.
TARAS: How long is a typical project? How long would it take to put together a visualization for an article that we typically see?
RICH: It varies wildly. The graphics desk is about 50 strong and they will turn around things within a day. Like when the Notre Dame burnt down a couple of months ago, my colleagues turned around this interactive scroll driven webGL 3D reconstruction of how the fire spreads through the cathedral in less than 24 hours, which was absolutely mind blowing. But at the same time, there are projects that will take months. I work on the investigations team at the Times. And so, I'm working with people who are investigating stories for the best part of the year or sometimes more. And I'm building graphics for those. And so that, it's two very different timescales, but you need to be able to accommodate all of those different possibilities.
CHARLES: So, what does the software development practice look like? I mean, because it sounds like some of this stuff, are you just throwing it together? I guess what I mean by that is, I guess the projects that we typically work on, three months is kind of a minimum that you would expect. So, you go into it, we need to make sure we've got good collaboration practices around source control and continuous integration and testing and all this stuff. But I mean, you're talking about compressing that entire process into a matter of hours. So what, do you just throw right out the window? What do you say? "We're just doing a live version of this."
RICH: Our collaboration processes consist of sitting near each other. And when the time calls for it, getting in the same room as each other and just hammering stuff out on the laptop together. There's no time for messing around with continuous integration and writing tests. No one writes tests in the news graphics, it's just not a thing.
CHARLES: Right. But then for those projects that stretch into like three months, I imagine there are some. Do you run into like quality concerns or things like that where you do have to take into account some of those practices? I'm just so curious because it sounds like there's actually, the difference between two hours and two months is, that's several orders of magnitude and complexity of what you're developing.
RICH: It is. Although I haven't worked on a news project yet that has involved tests. And I know that's a shocking admission to a lot of people who have a development background, but it's just not part of the culture. And I guess the main difference between the codebase for a two-hour project and a two-month project is that the two-month project will strive to have some reasonable components. And that's, I think, the main thing that I've been able to get out of working on the kinds of projects that I do is instead of just throwing code at the page until it works, we actually have a bit of time to extract out common functionality and make components that can be used in subsequent interactives. So, things like scroll driven storytelling, that's much easier for me now than it was when I first built a scroll driven storytelling component like a couple of years ago.
CHARLES: Yeah. That was actually literally my next question is how do you bridge that, given that you've got kind of this frothy experimentation, but you are being, sounds like, very deliberate about extracting those tools and extracting those common components? And how do you find the time to even do that?
RICH: Well, this is where the component driven mindset comes in really handy, I think. I think that five or 10 years ago when people thought in terms of libraries and scripts, there wasn't like that good unit of reusability that wasn't the sort of all encompassing, like a component is just the right level of atomicity or whatever the word is. It makes sense to have things that are reusable but also very easy to tweak and manipulate and adapt to your current situation. And so, I think that the advent of component oriented development is actually quite big for those of us working in this space. And it hasn't really caught on yet to a huge degree because like I say, a lot of people are still coming with this kind of D3 script based mindset because the news industry, for some interesting and historical reasons, is slightly out of step with mainstream mode development in some ways. We don't use things like Babel a lot, for example.
CHARLES: That makes sense, right? I mean, the online print is not like it's a React application or it's not like the application is all encompassing, so you really need to have a light footprint, I would imagine, because it really is a script. What you're doing is scripting in the truest sense of the word where you essentially have a whole bunch of content and then you just need to kind of --
TARAS: A lot of the tooling that's available, especially on like the really fatter, bigger frameworks, the tools that you get with those frameworks, they benefit over long term. So if you have like a long running project, the weight of the abstractions, you've experienced that benefit over time and it adds up significantly. But if you're working to ship something in a day, you want something that is just like a chisel. It does exactly what you want it to do. You want to apply it in exactly the right place and you want to get it done exactly, like you want the outcome to be precise.
RICH: That's true. And I think a lot of people who have built large React apps, for example, or large Ember apps, they sort of look at Svelte and think, "Well, maybe this isn't going to be applicable to my situation," because it has this bias towards being able to very quickly produce something. And I'm not convinced that that's true. I think that if you make something easier to get started with, then you're just making it easier. If you build something that is simple for beginners to use, then you're also building something simple for experts to use. And so, I don't necessarily see it as a tradeoff, I don't think we're trading long-term maintainability for short term production. But it is certainly a suspicion that I've encountered from people.
TARAS: This is something that we've also encountered recently. It's been kind of a brewing discussion inside a front side about the fact that it seems to be that certain problems are actually better to rewrite than they are to maintain or refactor towards an end goal. And we found this, especially as the tools that we create have gotten more precise and more refined and simplified and lighter, it is actually easier to rewrite those things five times than it is to refactor it one time to a particular place that we want it to be. And it's interesting, like I find this to be very recent, this idea is blossoming in my mind very recently. I didn't observe this in the past.
CHARLES: Do you mean in the sense that like if a tool is focused enough and a tool is simple enough, then refactoring is tantamount to a rewrite if you're talking about 200 or 300 lines of code? Is that what you mean?
TARAS: Yeah. If you're sitting down to make a change or you have something in mind, it is actually easy to say, "Let's just start from scratch and then we're going to get exactly the same place in the same amount of time." But this kind of mantra of not rewriting makes me think about that, makes me question whether that's actually something that is always the right answer.
And I think that at the other end of the spectrum, the recent debate about micro frontend has largely missed this point. People think that the benefit of the micro frontend is that people don't need to talk to each other, which is absolute nonsense. I think the benefit of this way of thinking about building applications is that it optimizes for this fact of life that we all agree is inevitable, which is that at some point, you're going to have to rewrite your code. And we spend so much energy trying to optimize for the stability of a code base over the long term. And in the process, lock ourselves into architectural and technical decisions that don't necessarily make sense three or four years down the line. And I think as an industry, would be a lot better placed if we all started thinking about how to optimize for rewrites.
CHARLES: So for those of us who aren't familiar, what is the debate surrounding micro frontends? This is actually something I've heard a lot about, but I've actually never heard what micro frontends actually are.
RICH: Yeah. I mean, to be clear, I don't really have a dog in this fight because I'm not building products, but the nub of it is that typically if you're building a website that maybe has like an admin page, maybe it has a a settings page, maybe it has product pages, whatever. Traditionally, these would all be parts of a single monolithic application. The micro frontend approach is to say, "Well, this team is going to own the settings page. This team is going to own the product page." And they can use whatever technologies they want to bring that about. And the detractors sort of attack a straw man version of this, "You're going to have different styles in every page. You're going to have to load Vue on one page. You're going to have to load React on the other page. It's going to be a terrible user experience," when actually its proponents aren't suggesting that at all. They're suggesting that people from these different teams coordinate a lot more that are free to deviate from some kind of grand master architectural plan when it's not suitable for a given task. And darn right. I think it means that you have a lot more agility as an engineering organization than you would if you're building this monolithic app where someone can't say, "Oh, we should use this new tool for this thing. We should use microstates when the rest of the organization is using Google docs." It's not possible. And so, you get locked into the decisions of a previous generation.
CHARLES: Right. No, it makes sense. It's funny because my first reaction is like, "Oh my goodness, that's a potential for disaster." The klaxon's going to go off in your head, but then you think, really then the work is how do you actually manage it so it doesn't become a disaster. And if you can figure that out, then yeah, there is a lot of potential.
RICH: Yeah. People always try and solve social problems with technology. You solve social problems with social solutions.
CHARLES: Right. And you have to imagine it too, it depends on the application, right? I think Amazon, the Amazon website is developed that way where they have different teams that are responsible even down to little content boxes that are up on the toolbar. And the site doesn't really, it shows, right? Like it shows like this is kind of like slapped together, but that's not what they need. They don't need it to not look like there's slight variation with the different ways that things behave. They need to be showing for their business to work. They need to be showing the right thing at the right time. And that's the overriding concern. So having it look very beautiful and very coherent isn't necessarily a thing. Same thing in Spotify, used as another example of this. I didn't know if it was called micro frontends, but I know that they've got a similar type thing, but they are clearly the experience and having it look coherent is more important. And so, they make it work somehow. And then like you're saying, it probably involves groups of people talking to other groups of people about the priorities.
So yeah, it doesn't sound to me like just like you're going to adopt micro frontends guarantees one particular set of outcomes. It really is context dependent on what you make of it.
TARAS: I'm curious though, so with Svelte, essentially for your reactivity engine, you have to compile to get that reactive behavior.
TARAS: How does that play with other tools like when you actually integrate it together? I've never worked with Svelte on a large project, so I can't imagine what it looks like at scale. I was wondering if you've seen those kind of use cases and what that ends up, if there's any kind of side effects from that.
RICH: As you say, the reactivity within a component is only in the local state within that component or to state that is patched in as a prop from a parent component. But we also have this concept called a store. And a store is just a project that represents a specific value and you import it from svelte/store. And there are three types of store that you get out of the box. A writable, a readable and a derived. And a writeable is just, var count = writable (0) and then you can update that and you can set it using methods on that store. Inside your marker, you can reference or in fact inside the script block in the component, you can reference the value of that store just by prefacing it with a dollar sign. And the compiler sees that and says, "Okay, we need to subscribe to this store as value and then assign it and apply the reactivity." And that is the primary way of having state that exists outside the component hierarchy. Now, I mentioned the writable, readable, and derived are the built in stores that you get, but you can actually implement your own stores. You just need to implement this very simple contract. And so,, it's entirely possible to use that API to wrap any state management solution you have. So you can wrap redux, you can wrap microstates, you can wrap state, you can wrap whatever it is, whatever your preferred state management solution is, you can adapt it to use with Svelte. And it's very sort of idiomatic and streamlined. Like it takes care of unsubscriptions when the component is unmounted. All of that stuff is just done for you.
CHARLES: Digging a little bit deeper into the question of integration, how difficult would it be to take wholesale components that were implemented in Svelte and kind of integrate them with some other component framework like React?
CHARLES: You said there's a NativeScript project, but it sounds to me like you shouldn't necessarily need NativeScript, right? If you're a compiler, you can actually target Android and you could target iOS directly instead of having NativeScript as an intermediary, right?
RICH: Yes. If, if we had the time to do the work, then yes. I think the big thing there would be getting styles to work because Svelte components have styles. And a regular style tag just to CSS and you can't just throw CSS in a native app.
CHARLES: Right. Sometimes, I feel like it'd be a lot cooler if you could.
RICH: NativeScript really is doing a lot of heavy lifting. Basically what it's doing is it's providing a fake dom. And so, what the NativeScript does is it targets that dom instead of the real dom and then NativeScript turns that into the native instructions.
CHARLES: Okay. And you can do that because you're a compiler.
TARAS: Compilers has been on our radar for some time, but I'm curious like what is your process for figuring out what it should compile to? Like how do you arrive at the final compile output? Manually, have you written that code and then, "I'm going to now change this to be dynamically generated." Or like how do you figure out what the output should be?
CHARLES: It's always curious to me about when is the proper time to move to a compiler, because when you're doing everything at runtime, there's more flexibility there. But at what point do you decide, "You know what? I know that these pathways are so well worn that I'm going to lay down pavement. And I'm going to write a compiler." What was the decision process in your mind about, "Okay, now it's time." Because I think that that's maybe not a thought that occurs to most of us. It's like, "I had to write a compiler for this." Is this something that people should do more often?
I just wanted to quickly address the point you made about flexibility. This is a theoretical downside of being a compiler. We're throwing away the constraints about the code needing to be something that runs in the browser, but we're adding a constraint, which is that the code needs to be statically analyzable. And in theory, that results in a loss of flexibility. In practice, we haven't found that to affect the things that we can build. And I think that a lot of times when people have this conversation, they're focusing on the sort of academic concepts of flexibility. But what matters is what can you build? How easy is it to build a certain thing? And so if empirically you find that you're not restricted in the things that you can build and you can build the same things much faster, then that academic notion of flexibility doesn't, to my mind, have any real value.
CHARLES: Hearing you talk reminded me of kind of a quote that I heard that always stuck with me back from early in my career. I came into programming through Perl. Perl was my first language and Perl is a very weird language. But among other things, you can actually just change the way that Perl parses code. You can write Perl that makes Perl not throw, if that makes any sense. And when asked about this feature, the guy, Larry Wall, who came up with Perl, he's like, "You program Perl, but really what you're doing is you're programming Perl with a set of semantics that you've negotiated with the compiler." And that was kind of a funny way of saying like, "You get to extend the compiler yourself." Here's like the default set of things that you can do with our compiler, but if you want to tweak it or add or modify, you can do that. And so, you can utilize the same functionality that makes it powerful in the first place. You can kind of inject that whole mode of operation into the entire workflow. Does that make sense? That's like a long way of saying, have you thought about, and is it possible to kind of extend the Svelte compiler as part of a customization or as part of the Svelte programming experience?
At the other end, at a slightly more extreme level, we have talked about making the cogeneration part plugable so that for example, the default renderer and the SSR renderer are just two examples of something that plugs into the compiler that says, "Here is the component, here's the abstract syntax tree, here's some metadata about which values are in scope," all of this stuff and then go away and generate some code from this. We haven't done that so far, partly because there hasn't been a great demand for it, but also because it's really complicated. As soon as you turn something into a plugin platform, you just magnify the number of connection points and the number of ways that things could go wrong by an order of magnitude. And so, we've been a little bit wary of doing that, but it is something that we've talked about primarily in the context of being able to do new and interesting things like target webGL directly or target the command line. There are renders for React that let you build command line apps using React components. And like we've talked about, maybe we should be able to do that. Native is another example. The NativeScript integration as you say, it could be replaced with the compiler doing that work directly, but for that to work presently, that would mean that all of that logic would need to sit in core. And it would be nice if that could be just another extension to the compiler. We're talking about a lot of engineering effort and there's higher priority items on our to do list at the moment. So, it's filed under one day.
CHARLES: Right. What are those high priority items?
RICH: The biggest thing I think at the moment is TypeScript integration. Surprisingly, this is probably like the number one feature request I think is that people want to be able to write Typescript inside the Svelte components and they want to be able to get TypeScript when they import the Svelte component into something else. They want to be able to get completion [inaudible] and type checking and all the rest of it. A couple of years ago, that would've been more or less than thinkable but now it's like table stakes is that you have to have first-class TypeScript support.
CHARLES: Yeah, TypeScript is as popular as Babel these days, right?
RICH: Yeah, I think so. I don't need to be sold on the benefits. I've been using TypeScript a lot myself. Svelte is written in TypeScript, but actually being able to write it inside your components is something that would involve as hacking around in the TypeScript compiler API in a way that, I don't know if anyone actually or any of us on the team actually knows how to do. So, we just need to spend some time and do that. But obviously when you've got an open source project, you need to deal with the bugs that arise and stuff first. So, it's difficult to find time to do a big project like that.
CHARLES: So, devil's advocate here is if the compiler was open for extension, couldn't a TypeScript support be just another plugin?
RICH: It could, but then you could end up with a situation where there's multiple competing TypeScript plugins and no one's sure which ones are used and they all have slightly different characteristics. I always think it's better if these things that are common feature requests that a lot of people would benefit from, if they're built into the project themselves. I go really light in the batteries included way of developing and I think this is something that we've sort of drifted away from in the frontend world over the last few years, we've drifted away from batteries included towards do it yourself.
CHARLES: Assemble the entire thing. Step one, open the box and pour the thousand Lego pieces onto the floor.
RICH: Yeah, but it's worse than that because at least, with a Lego set, you get the Lego pieces. It's like if you had the Lego manual showing you how to build something, but you were then responsible for going out and getting the Lego pieces, that's frontend development and I don't like it.
CHARLES: Right. Yeah. I don't like that either. But still, there's a lot of people advocating directly. You really ought to be doing everything completely and totally yourself.
CHARLES: And a lot of software development shops still operate that way.
RICH: Yeah. I find that the people advocating for that position the most loudly, they tend to be the maintainers of the projects in question. The whole small modules philosophy, they exist for the benefit primarily of library authors and framework authors, not for the benefit of developers, much less users. And the fact that the people who are building libraries and frameworks tend to have the loudest megaphones means that that mindset, that philosophy is taken as a best practice for the industry as a whole. And I think it's a mistake to think that way.
TARAS: There is also, I think, a degree of a sliding scale where you start off with like as the more experience you get, because there is more experience you get closer, you get to that kind of wanting granular control and then they kind of slides down towards granular control and then slice back up to, once you've got a lot of experience, you're like, "Okay, I don't want this control anymore." And then you kind of cast that and you get into like, "I'm now responsible for tools that my team uses," and now you're back to wanting that control because you want things to be able to click together. It's kind of like a way that your interest in that might change over time depending on your experience level and your position in the organization. So yeah, there's definitely different motivating factors. Like one of the things that we've been thinking a lot about is designing tools that are composable and granular at individual module level, but combined together into a system for consumption by regular people. So like finding those primitives that will just click together when you know how to click them together. But when you're consuming them, just feel like a holistic whole, but at the same time not being monolithic. That's a lot of things to figure out and it's a lot of things to manage over time, but that's solely the kind of things we've been thinking about a lot.
RICH: I think that's what distinguishes the good projects that are going to have a long lifespan from the projects that are maybe interesting but don't have a long shelf life is whether they're designed in such a way that permits that kind of cohesion and innovation tradeoff, if you think of it as a trade off. Anyone can build the fastest thing or the smallest thing or the whatever it is thing. But building these things in a way that feels like it was designed holistically but is also flexible enough to be used with everything else that you use, that's the real design challenge.
CHARLES: It's hard to know where to draw that line. Maybe one good example of this and, these are actually two projects that I'm not particularly a fan of, but I think they do a good job of operating this way. So, I guess in that sense, it means I can even be more honest about it. I don't particularly care for Redux or like observables, but we ended up using, in one of our last React projects, we had to choose between using Redux-Saga and Redux-Observable. The Redux-Observable worked very well for us. And I think one of the reasons is because they both had to kind of exist. They had to kind of co-exist is their own projects. Like Redux exists as its own entity and Observables exist as their own kind of whole ecosystem. And so, they put a lot of thought in like what is the natural way in which these two primitives compose together? As opposed to the Saga, which I don't want to disparage the project because I think it actually is a really good project. There's a lot of really good ideas there but because it's more like just bolted on to Redux and it doesn't exist outside of the ecosystem of Redux and the ideas can't flourish outside and figure out how it interfaces with other things. Like the true primitive is still unrevealed there. And so, whereas I feel like with Redux you actually have to really, really true primitives. Now, they're not necessarily my favorite primitives, but they are very refined and very like these do exactly what they are meant to do. And so when you find how they connect together, that experience is also really good. And the primitive that arises there I think ends up being better. Is that an example of what you guys are talking about?
RICH: Maybe. [Laughs]
TARAS: No, I think so. I mean, it's distilling to the essence, the core of what you're trying to do and then be able to combine it together. I mean, that's been kind of the thing that we've been working on at the Frontside. But also within this context, it makes me think of how does a compiler fit into that? How does that work with the compiler? It's just like when you add the compiler element, it just makes it like my mind just goes poof!
CHARLES: Yeah, exactly. That's why I keep coming back to like, how do you, and maybe I haven't, you just have to kind of go through the experience, but it feels like maybe there's this cycle of like you build up the framework and then once it's well understood, you throw the framework away in favor of like just wiring it straight in there with the compiler and then you iterate on that process. Is that fair to say?
RICH: Kind of, yeah. At the moment, I'm working on this project, so I referred a moment ago to being able to target webGL directly. At the moment, the approach that I'm taking to building webGL apps is to have webGL components inside Svelte in this project called SvelteGL. And we've used it a couple of times at the Times. It's not really production ready yet, but I think it has some promise. But it's also slightly inefficient, like it needs to have all of the shade of code available for whichever path you're going to take, whatever characteristics your materials have, you need to have all of the shade of code. And if we're smart about it, then the compiler could know ahead of time which bits of shade of code it needed to include. At the moment, it just doesn't have a way of figuring that out. And so that would be an example of paving those cow paths. Like if you do try and do everything within the compiler universe, it does restrict your freedom of movement. It's true. And to qualify my earlier statements about how the small modules philosophy is to the benefit of authors over developers, it has actually enabled this huge flourishing of innovation, particularly in the React world. We've got this plethora of different state management solutions and CSS and JS solutions. And while I, as a developer, probably don't want to deal with that, I just want there to be a single correct answer. It's definitely been to the advantage of the ecosystem as a whole to have all of this experimentation. Then in the wild, there are projects like Svelte they can then take advantage of. We can say, "Oh well, having observed all of this, this is the right way to solve this problem." And so, we can kind of bake in that and take advantage of the research that other people have done. And I think we have made contributions of our own but there is a lot of stuff in Svelte like the fact that data generally flows one way instead of having [inaudible] everywhere. Things like that are the results of having seen everyone make mistakes in the past and learning from them. So, there are tradeoffs all around.
TARAS: One thing on topic of data flow here and there, one thing that I've been kind of struggling to compute is the impact of that as opposed to something where you have like one directional data flow because it seems like conceptually it's really simple. You set a property like in two way balance system, like you just propagate through stuff but we don't really have a way, you don't have any way of assessing what is the true impact of that computation. Like what is the cost of that propagation where I think it's almost easier to see the cost of that computation if you have like one directional data flow because you know that essentially everything between the moment that you invoke transition to computing the next state, that is the cost of your computation where you don't have that way of computing the result in a two way balance system. Something like Ember Run Loop or mobx or zones, Vues, reactive system. All these systems make it really difficult to understand what is the real cost of setting state. And that's something that I personally find difficult because this clarity that you have about the one directional data flow and what it takes to compute the next state, it's almost like because that cost is tangible where you're thinking about like mutation of objects and tracking their change like that cost is almost immeasurable. It just seems like a blob of changes that they have to propagate. I don't know. That's just something that I've been thinking a lot because especially with the work that we'll be doing with microstates because as you're figuring out what the next state is, you know exactly what operations are performed in a process where that might not be the case with the system that tracks changes like where you'd have with zones or with Ember Run Loop, or Vue.
RICH: I would agree with that. The times that I found it to be beneficial to deviate from the top-down ideology is when you have things like form elements and you want to bind to the values of those form elements. You want to use them in some other computation. And when you do all that by having props going in and then events going out and then you intercept the event and then you set the prop, you're basically articulating what the compiler can articulate for you more effectively anyway. And so conceptually, we have two way bindings within Svelte, but mechanically everything is top down, if that makes sense.
CHARLES: Is it because you can analyze the tree of top down and basically understanding when you can cheat. This might be really over-simplistic, but if you're kind of with the event, you're collecting the water and then you have to put it way up on top of the thing and it flows down. But if you can see the entire apparatus, you can say, "Actually, I've got this water and it's going to end up here, so I'm just going to cheat and put it over right there." Is that the type of thing that you're talking about where you're effectively getting a two way binding, but you're skipping the ceremony.
RICH: It's kind of writing the exact same code that you would write if you were doing it using events. But if you're writing it yourself, then maybe you would do something in a slightly inefficient way perhaps. For example, with some kinds of bindings, you have to be careful to avoid an infinite loop. If you have an event that triggers a state change, the state change could trigger the event again and you get this infinite loop. A compiler can guard against that. It can say this is a binding that could have that problem, so we're going to just keep track of whether the state changes as a result of the binding. And so, the compiler can sort of solve all of these really hairy problems that you had faced as a developer while also giving you the benefit in terms of being able to write much less code and write code that expresses the relationship between these two things in a more semantic and declarative way without the danger.
TARAS: This is one of the reasons why I was so excited to talk to you about this stuff, Rich, because this stuff is really interesting. I mentioned that we might, so we have a little bit more time. So I just want to mention, because I think that you might find this interesting, the [inaudible], the stuff that we were talking about that I mentioned to you before. So, I want to let Charles talk about it briefly because it's interesting, because it essentially comes down to managing asynchrony as it ties to life cycle of objects. Life cycle of objects and components are something we deal with on a regular basis. So, it's been an interesting exercise and experimenting with that. Charles, do you want to give kind of a low down?
RICH: Yes, I did.
RICH: I'm not going to pretend to have fully understood everything you just said but it does sound interesting. It does have something not that dissimilar to ember's run loop because if you have two state changes right next to each other, X+=1, Y+=1, you want to have a single update resulting from those. So instead of instruments in the code such that your components are updated immediately after X+=1, it waits until the end of the event loop and then it will flush all of the pending changes simultaneously. So, what you're describing sounds quite wonderful and I hope to understand that better. You have also reminded me that Alex Matchneer implemented this idea in Svelte, it's called svelte-concurrency. And when he sent it to me, I was out in the woods somewhere and I couldn't take a look at it and it went on my mental to do list and you just brought it to the top of that to do list. So yeah, we have some common ground here, I think.
CHARLES: All right.
TARAS: This is a really, really fascinating conversation. Thank you, Rich, so much for joining us.
CHARLES: Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @thefrontside or over just plain old email at email@example.com. Thanks and see you next time.
Sep 04 2019
Rank #5: Security with Philippe De Ryck
Philippe De Ryck joins the show to talk all things security: the importance and why you should be taking active steps, how to do it in your codebase effectively, and what can happen during a breach.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, a place where we talk about user interfaces and everything that you need to know to build them right.
My name is Charles Lowell, a developer here at The Frontside. Joining me, also hosting today is Taras Mankovsky. Hello, Taras.
TARAS: Hello, hello.
CHARLES: And as always, we're going to be talking about web platforms, UI platforms, and the practices that go into them. And here to talk with us today about a pillar of the platform that I certainly don't know that much about, and so, I'm actually really happy to have this guest on to talk about it is Philippe De Ryck who owns his own company called Pragmatic Web Security. I understand you do trainings and are just generally involved in the small space. So, welcome, Philippe.
PHILIPPE: Hi. Nice to meet you.
CHARLES: Wow! I almost even don't even know where to start with this subject because I'm kind of like the hippie developer mindset where it's like, "LaÖlaÖlaÖlaÖlaÖ we're in this open land and nothing's ever bad going to happen and we're just going to put code out there," and nobody would ever take advantage of any holes or anything like that. And I think that a lot of developers share that mentality and that's how we end up with major, major security breaches. And so, like I said, this is something that I'm actually very eager to learn but I almost even don't know where to start. I need training, man.
PHILIPPE: Well, that's good to hear. No, you're totally right about that. If you're not into security, it seems like this fast space for a lot is happening and you don't really know how or why and what really matters to you and should I even be worried about this. And let me start by addressing the very first thing. Yes, you should be worried because maybe you're not building something that somebody cares about but you always have something that somebody wants, even the simplest of attacks always targets a valuable resource. Just to give you a very simple idea today, cryptocurrency is all the hype and you have a taker that's just aiming to misuse your users' computers to mine crypto coins because it essentially saves them a bunch on electricity cost. So, there's always something to grab. Usually, it's data or services or worse. But even in the most minimal cases, you have hardware, you have devices, you have network capacity that somebody might want to abuse. So yes, security, I would say, always matters.
CHARLES: What's the best way to get started? You said understanding that everything we do, we're holding onto resources that might be valuable, that someone might want to seize but I'm just getting started with my application. I don't know anything about security. Where do I get started on just understanding the space? And then before I even look at tools that I wantÖ
PHILIPPE: You want the honest answer for that?
PHILIPPE: The honest answer is probably hire someone who has security knowledge. I don't mean this in a bad way. I've come a very long way in my career doing what I do now. And if I look at that, if you are aiming as a developer with no knowledge about security to build a secure application, it's going to be very hard. There's a lot of things you need to know, intrinsic knowledge. These are not things you can simply read a small book in a week, you know all of these security things that you'll know what to do. So, if you have no previous experience at all, I suggest to find some help.
CHARLES: Right. It's like saying, "Hey, you've never written a data layer before but you want to go out and you want to write a massively distributed system where you have all these notes talking to each other. You're not going to read the O'Reilly book 'How to Build Distributed Systems' in a week and go out and do the same thing." It's the same thing with security. You need to understand the entire context. And there's no substitute for experience.
PHILIPPE: Sorry, I actually like that comparison because in a sense, you're right, it's like these other very complex topics you don't expect to learn that in a week or a month and right a functioning data layer. But the difference is if you fail at writing that data layer, your application is probably not going to work. While if you fail at securing the application or seeing potential vulnerabilities, it's still going to work just a bit more than you anticipated. It's going to result leaking all your data to an attacker or opening all doors so that they can gain access to your server, stuff like that. So, I would say that the consequences of not getting it right are, at least in the beginning, very invisible. It's only after things happened that it's like, "Oh, crap!" And you should pay attention to that.
CHARLES: Yeah. And then you have these back doors and these leaks that are set in stone and may be very hard to change.
PHILIPPE: Yeah, absolutely. And honestly, the worst part of the breach is for a company, it might be reputation damage. But what you really should be worried about is all that personal information that's being leaked to, most cases, publicly leaked to anyone but in other cases, it's sold on [inaudible] markets and actually abused by people looking for someone else's identity or credit card information or stuff like that. And the companies usually get away with some bad press, maybe a small dip in their stock price but eventually, they'll bounce back. But it's the users that suffer from these breaches for a very, very long time.
TARAS: What do you see the kind of hot zones around concerns that companies have around security? Because I imagine it's hard to be concerned about everything, so they're probably thinking about specific things like this thing worries us. Like what kind of things do you see companies and teams need to worry about?
PHILIPPE: That's an interesting question. You have all different kinds of companies and all different levels of security awareness and what they're worrying about. I would say if you have the companies that are not very good at or don't have very much security knowledge, they're probably not to worry about things because otherwise, they would have started investing in improving their practices. If you look at the companies that are at least very aware of the landscape, I'm not saying that anybody here is perfect, but some of the companies are actually doing quite a good job. One of the most interesting challenges today is dealing with dependencies. So, all of your packages, you depend on npm, Maven, Python packages, Ruby gems, and so on. All of them form a huge attack factor in most applications today. That's definitely a problem that a lot of companies struggle with and it's very hard to find good solutions.
TARAS: GitHub recently, I saw their vulnerability alert service that I've been getting a lot of notifications from on some of the open source libraries that we use. They have a lot of dependencies. And a lot of projects have the same dependencies. So, the moment that one notification goes on, it like lights up on all of the GitHub repos that I have. So, I have been going through and like updating dependencies and all those libraries.
PHILIPPE: Yeah, that's a very good example. Absolutely. A lot of the projects we build today usually start out by installing a bunch of dependencies. Even before you've written the first line of code, you already have a massive code base that you are relying upon. And a single vulnerability in a code base might be enough, it's not always the case, but it might be enough to compromise your application. And that leaves you, as a developer, in a very hard place because you haven't written any lines of code yet. You have built a vulnerable application and that starting point can be very terrifying. So, there's a lot of reports on this. And actually, if you want some numbers, 78% of the vulnerabilities discovered in existing applications like the ones you mentioned. If GitHub alerts you like, "Hey, there's a problem in one of your dependencies," it's often even an indirect dependency, meaning that you include a framework, if you include React or Express or whatever you're building, that one of your dependencies of one of those projects actually has a vulnerability. If you look at the trees of these packages, they get quite big that it's not dozens but it's thousands of packages that we're talking about.
CHARLES: Yeah that's the other thing is how do you know how to interpret these security vulnerabilities because some of them, we get a lot of security vulnerabilities for node packages but we only use them for our development tools to build frontend. So, if we're building a React application and there's some security vulnerability in some node packages that we're using in our build tool, then that doesn't actually get deployed to the frontend. So, maybe it's not a concern but if we were actually using it to build a server, then it would be absolutely critical. And so, how do you evaluate because the same security vulnerability is not a vulnerability in one context, but might be in another or maybe I'm thinking about it wrong. You see what I mean?
PHILIPPE: Yeah, sure. I totally get what you mean. Actually, I have observed the same things. I also get these security alerts on my projects, and sometimes it's devDependency, so it seems like we don't need to care about that. You're right in the sense that you have to assess the criticality of such a report. So, they will have a rating, a severity rating saying like, "This is a minor issue," or, "This is a major issue," that should be a first indication. And then a second thing to look at is, of course, how are these things used in practice. It's not because it's a devDependency that it's not exploitable because it all depends on what is the vulnerability. If there's an intentional malicious backdoor in the library and you're building that on your build server, it might give an attacker access to your build server. So, that might not be something you actually want to do. So in that case, it does matter. Of course, if it's only stuff you run locally, you can say like, "OK, this is less important." But usually, updating or fixing these vulnerabilities also requires less effort because there's no building and deploying to production servers either. So, it's a matter of staying up-to-date with these.
And one of the things that people struggle with is handling this in a lot of different applications. You mentioned you had a lot of GitHub repos and the vulnerability starts popping up in all of them and you have to fix and update all of them. You can imagine that major companies struggle with that, as well, especially if you have quite a few different technologies. Managing all of that is insanely hard.
CHARLES: Right, because you just usually look at it and you're like, "Oh, I've got to download this." And maybe, "I haven't used it this repo for a while. I've got to clone it up, I've got to update the dependency. I've got to make sure I run all my tests locally, then run all the tests in CI and make sure I didn't break anything by upgrading. I might have fixed closed security hole but broken my functionality." And so, make sure that that is all intact and then push it out to production. Even on the small, it's like I'm looking, "OK, maybe this is going to take me 30 to 45 minutes." But if you have four or five of those things, you're looking at half your day or maybe even the whole day being gone and that's if you have the processes in place to do those automated verification. If you have a very high confidence in your deployment pipeline which I don't think a lot of places have. So, it sounds like these are complementary, like you really need in order to keep a secure application, you have to keep it up-to-date because I think what I'm hearing is you should just evaluate all the threats. You should fix it if you can. The first part of my question is, am I kidding myself when I say, "Oh, I can ignore this one because it's just local or it's just a devDependency."
PHILIPPE: The answer to that question is briefly, I would say they are less critical.
CHARLES: That's cool.
PHILIPPE: In general, the rule is update if you can. And actually some of the tools out there that monitor vulnerabilities, they will automatically create a pull request in your repo saying to upgrade to this version and then you can automatically run your tests if you have them, and you can very quickly see whether some conflicts are generated by updating that dependency - yes or no. And in most cases, if it's a minor version bump, it's going to work as expected and you can easily push out the new version without that vulnerability. So, I would say fix if you can. If it goes quickly, then definitely fix them. But I would focus on non-devDependencies first instead of devDependencies.
PHILIPPE: Second thing I wanted to add is you paint a very grim picture saying you have to spend a lot of time updating these issues and I can totally understand that happening the very first time you look into this. There's going to be some stuff in there, I can guarantee that. But if you do this regularly, the effort becomes less and less because once you have up-to-date libraries, the problem is bad but it's not like we have 50 new vulnerabilities every day, fortunately.
PHILIPPE: So, once you have done that, it's going to be a bit less intensive than you might anticipate at first glance. Of course, if you're using these projects, if you're reusing the same library, then you'll have to update them everywhere. That's the downside, of course.
CHARLES: It's probably a little bit dangerous to be assessing the criticality of the security threats yourself if you're not an expert, and kind of in the same way, it's dangerous to be assessing an architecture if you don't have an expertise in our architecture, I guess is the thing, because you might not understand the threat.
PHILIPPE: Yeah, that's, again, absolutely true. It again depends very much on how it's deployed and what it's used for. That's going to be one important aspect. Another thing that might be very useful is, how deep is the dependency that creates the vulnerability or has the vulnerability? Because for example, if you have your tree of dependencies, if you dependency is like five or six levels deep, the chances of malicious data are reaching that specific vulnerability, and that specific library is going to be fairly small. Because usually, libraries have a lot of features and you only use part of them in your application. So, the other one is address of the features is just sitting there and if it's never used and it's also not exploitable. So, that might play a role as well.
I saw a presentation about a month or two months ago from how Uber manages these things and they struggled with a lot of those things as well. And they eventually decided that they really care about vulnerabilities going three levels deep. And something that goes deeper is considered to be less relevant or less urgent to update because chances of exploitability are going to be very small.
CHARLES: That's actually really interesting.
By the way, these things also have a legitimate purpose. So, they are also used to keep track of a particular user to prevent things like session hijacking or detect problem logins or stuff like that, so they can also have a legitimate use case next to tracking. But they very clearly show how security will always be a cat and mouse game. Tracking used to be easy. You just set a cookie in a browser and the cookie was there next time and you knew who the user was. And then, users became a bit more savvy. You had browser extensions trying to block listings because let's be honest, they're kind of shady. So, users probably don't want that. And then the attacker started moving towards other things and getting more advanced. And you see that in other areas of security, as well. So, I consider that a good thing because as we make things harder for attackers, they will have to get more creative and it will become more difficult to exploit or to take advantage of applications. That's the good side. The bad side or the dark side of that equation is that unfortunately, the vulnerabilities are not going away. It's not because we now have these somewhat more advanced attacks using advanced features or even CView-based vulnerabilities that the old things like SQL injection and [inaudible] have disappeared in applications. That's also not true and that means that it makes it just a bit more harder for everyone on the defensive side to build more secure applications. You're going to have to know about the old stuff and you have to learn about the new stuff.
CHARLES: Again, we come back to that idea. It's all a bit overwhelming. Aside from the solution of like, "Hey, let's hire Phillippe. Let's hire some other security expert." We were actually in your training, and obviously, I don't want to divulge all the secrets or whatever. If we were to attend your training, what do you see is the most important thing for people to know?
PHILIPPE: There's no secrets there. [Chuckles] What I teach is web security. I kind of like to think I teach that in a very structured and methodical way. But in the end, there's no secrets and I don't mind talking about this here on the podcast because I honestly believe that everyone should know as much as they can about security.
What do I teach? I can talk about specifics but I can also talk about generic things. One of the general takeaways is that one of the best things in my opinion that a developer can do is realize when they don't know something and actually admit that they don't know something, instead of just doing something. Maybe having like a brief thought like, "Hmm, is this secure? Well, it's probably good. I'm going to deploy it anyway. We'll see what happens." That is not the right way of doing things. If you do something and you recognize like, "Hey, this might be security sensitive. We're dealing with customer information here. We're dealing with healthcare information. We might want to look at what plays a role here," and then you can go ask someone who does. You probably have a colleague with a bit more security knowledge, so you can ask him like, "Hey Jim, or whatever your name is, do you think that this is OK or should we do something special here?" Very much like you are doing, asking me questions right here. That's one important takeaway that I hope everyone leaves with after a training class because not knowing something and realizing that you don't know it allows you to find someone who actually does. That still leaves us with that point which you wanted to sidestep.
PHILIPPE: A second thing is to realize that security is not a target. It's not something you're going to hit. It's not a holy goal that after working really hard for two years, you're going to hit this security milestone and you're done. It's always going to be a cat and mouse game. It's always going to be a moving target but that's OK. That's how things are. And that's the same with all other things in the world essentially. It's an evolving topic and you'll need to be ready to evolve with that as well.
TARAS: One of the challenges that I see into quite often in teams is that at the individual level, people really try to do their best, maybe the best of their abilities. But it's often, when it comes to being part of a group, it's often like they do best within the kind of cultural environment that exists. I'm curious if you've seen good or kind of environments or cultures for engineering teams that are conducive to good security. Are there kind of systems or processes the companies put in place that you've seen to be very effective in preventing problems? Have you encountered anything like this?
And then, of course, security champions themselves are not going to be security experts. They're mainly developers just with a security focus. So, they should be able to escalate problems up to people with more knowledge, like a security team which can be a small security team within their organization that people can easily reach out to, to ask like, "Hey, we're doing something here and I know that this is security relevant and I'm not entirely sure what's happening here. So, can we get a review of this part of your application?" Or, "Can you guys sit on the meeting to see what's going on and what's happening there?" And I think that structure also makes sense. It's still going to be hard to build secure applications because there's still a lot of things to address, but at least, your teams get some awareness. And then of course, you can help your security champions to become better and they will get better over time. You can augment them with the security architects. You can train your security champions separately with more in-depth knowledge and so on. And that veteran or that setup seems to work quite well in many large organizations today.
CHARLES: Yeah. I like that. It gets me to thinking, so having the having the security champions, having people who have this as part of, not their specialization, but at least part of their focus, being in the room, being part of the conversation because we try and do that and provide that service when it comes to UI but we also have a bunch of processes that kind of automate the awareness of quality. So, the classic one is your CI pipeline, your deployment pipeline. So, you're automating your advancement to production. You're automating your QA. It's still no substitute for having someone who's thinking about how to have that quality outcome but you still have some way of verifying that the outcome is quality. Are there tools out there that you can do to kind of keep your project on the security Rails. I'm thinking something that we we've done recently is having preview apps, so that we get a tight feedback loop of being able to deploy a preview version of your application that's on a branch but it's talking to a real backend. There's a lot of more software and services that are supporting this and it's kind of become an integral part of our workflow. So, testing automated deployment preview apps, there's this kind of suite of tools to make sure that the feedback loops are tight and that the quality is verified even though you have people, you also have people guiding that quality. It's just making sure that the standards are met. Is there a similar set of tools and processes in the security space so that we've got these champions out there, they're being part of the conversations. They're making suggestions but they can't be everywhere at once. And is there a way to make sure that the kind of the ways that they're guiding the application, just verifying that the application is going in that direction? Or an alarm bell has sounded. We mentioned one which is the automated pull request with the, "Hey, you got this dependency and there was a pull request." Are there more things like that, I guess, is what I'm saying.
PHILIPPE: Yes, there are. But I would dare to say not enough. So yes, you have some security tools you can integrate in your pipeline that do some automated scanning and they tried to find certain issues and alert you of those issues. So, these things do exist but they have their limitations. A tool can scan an application. Some of the findings are going to be easy and fairly trivial, but it's good to have the check in place nonetheless. But some of the more advanced issues are very likely to be undetectable by those automated tools because they require a large amount of skill and expertise to actually craft and exploit to abuse that particular feature in an application. So, we do have some limitations but I like discretion because I do believe that we need to leverage these mechanisms to ensure that we can improve the security quality of our applications. A very simple thing you can do is you can run an automated dependency check when you build the application and you can use that to decide to halt deployment when it's a severe vulnerability or go ahead anyway when you consider this to be acceptable because if you automate all of those things, things can go wrong as well. We can talk about that in a second.
So yeah, these things can be done. But what I strongly encourage people to do to ensure that they can kind of improve the code quality is to flag certain known bad code patterns. So if you're building an Angular or a React application, if you're using functions that output go directly into the template, that's going to be very dangerous. So, we know these functions in Angular, they're called bypassSecurityTrustHtml, bypass security should be kind of a trigger and this kind of security irrelevant. And in React, that property is called Dangerously Set innerHTML, also indicating like a 'developer watch out what you're doing'. So, what you could do is you could set up code scanning tools that actually flag these things whenever they appear in application because sometimes people make mistakes. You hire an intern and they don't really know the impact of using that property and they use it anyway which would cause cross-site scripting vulnerability. If you're code scanning to flag these things ensures that it doesn't get pushed to production unless it's a benign case which is actually approved to be in there, then you can definitely stop some of these attacks coming on for sure or some of these vulnerabilities happening.
TARAS: I think the hardest thing to understand is when someone doesn't understand what they're doing that what they will create is so cryptic that I think any tool that tries to figure out what it is that person is doing I think will have a really hard time. The person making the thing doesn't understand what they're doing, then the system is not going to understand what they're doing which makes me think that one of the things that we think about a lot at Frontside is this idea of trying to understand the system from the outside as kind of looking at a system as a black box and wonder what kind of tools are available specifically for inspecting the application from the outside, like as if somehow understanding what the application is doing based on what's actually going on inside of the runtime and then notifying someone that there could be something off in the application, but through exercising the [inaudible] things like, for example, memory leaks is not something you can catch unless you have a test suite that has like a thousand tests and then you will see over time that your application is actually leaking memory. But if you run individual tests, you'll never see that. I wonder if there's anything like that for security where at runtime, there's actually a way to understand that there might be some kind of a pattern that's incorrect in the application.
PHILIPPE: If only, if only. It depends on who you ask. There is such a concept that's called Dynamic Application Security Testing. Essentially, what you do there is you run the application, you feed it all kinds of inputs, and you monitor when something bad happens. And that means that you have detected vulnerability. So, these things do exist. But unfortunately, their efficiency is not always that good. It very much depends on what kind of security problems you're trying to detect. And they can, for example, detect some instances of things like cross-site scripting or SQL injection or things like that. But there will always be limitations. I've seen tools like that being run as an application where you actually know there's a vulnerability because it has been exploited. There is a manual written exploits and the tool still doesn't find any vulnerabilities which is not surprising, because these things are really hard to make an abstraction of to be able to find that in an automated way with a tool. If you would have such a tool that would be, I think, that [inaudible] would be a lot better. I think there's a lot of funders working on that. But at the moment, those tools are not going to be our savior to build more secure applications.
CHARLES: Yes. I mean, it's kind of like linting, right? Or you can make tests. We've been through this kind of all the features or the aspects that we want our application to have, whether it be accessibility. There's certainly a very comprehensive suite of lint level checks that you can run to make sure that your application is accessible. You can run a suite of three thousand things and if it triggers any of these things, then yes, your application won't be accessible but it's not a substitute for thinking through the accessibility architecture. The same thing goes with code linting. You're not going to solve bugs with a linter that makes sure that it's formatted and that you're declaring your variables right and that you're not shadowing things. But you can definitely eliminate a whole classes of things that might be put in there just for maybe even you know what you're doing and you're just forgetful.
PHILIPPE: Yes, these rules exist, as well. They're not extensive but there are linting rules for Angular used for security, for example. But the problem in linting is that they are very useful to find potential instances of security relevant features or security relevant functionality. But the linting rule alone cannot decide whether something is OK or not. Just to give you a very simple example, if you use the bypassSecurityTrustHtml function, if you give that function a static snippet of HTML, that's going to be fine unless you write your own attack essentially. But if you feed that function user inputs, you're going to be in a lot of trouble. And making that distinction with a linter is going to be difficult unless you have a static string in the arguments. But if once you start having that from variables to dynamically decide to have a different code path, then that's going to be very, very difficult to decide automatically. So, yes, you can use that to find the places in the application where you should be looking for, in this example, a cross-site scripting in Angular but the linting alone is not going to give you an answer whether this is OK or not. That still requires knowledge of how Angular handles this things, what happens, and how you can do things safely.
TARAS: Sounds like we keep going back to nothing beats having knowledgeable developers.
PHILIPPE: Yes. Unfortunately, that is true. However, with that said, I want to highlight that frameworks like Angular, well mainly Angular, make things a lot better for developers because yes, you still need knowledgeable developers but the ways to introduce a cross-site scripting vulnerability in an Angular application are actually very, very limited. It's not going to be one, but there's going to be maybe three or four things you need to be aware of, and then you should be set. While if you would have done the same for PHP, it's going to be 50,000 things you need to be aware of that are potentially dangerous. So, yes, frameworks and libraries and all of these abstractions make it a lot better and I really like that. That's why I always refer to abstract things away in a library so that you actually have the ability to look for this dangerous code patterns using linting rules in your code base and that you can, at least, inspect the go to see whether it's OK or not, even though you might not be able to make an automatic decision. You, at least, know where to look and what to approve or how to change in the code base.
TARAS: I think that's one of the things that oftentimes is not taken into account that the frameworks are different. And I think of big differences in how much -- like right now, the most popular framework, I think, React. But it's such a thin layer, it's such a small part of the framework that you can hardly call it a framework. But it is something that companies rely on. But then when you consider how much of that code that you need to write, to make React into a complete framework for your company, the amount of code that your team has to write versus the amount of code that your team has to write when you use something like Angular or Ember, there's definitely a lot less parts of the framework that you need to write or a lot less parts of the framework you need to choose from what's available in the ecosystem. Like in Angler and Ember, and I'm not sure what the story is with the view, but the pieces, they come from kind of a trusted source and they've been kind of battle tested against a lot of applications. But I don't think that enters into consideration when companies are choosing between Angular or whatever that might be because they're thinking like what is going to be easiest for us. What is going be [inaudible] for developers? They're not thinking about how much of the framework are we going to need to put together to make this work.
CHARLES: I can say it sounds, Taras, like almost what you're saying is by using the frameworks that have been battle tested, you actually get to avail yourself of code that actually has security champions kind of baked into it, right? Is that what you were saying? You keep coming back to 'you need developers who are knowledgeable about security', and if you're using kind of a larger framework that covers more use cases, you're going to get that. Do you think that that is generally true, Philippe?
PHILIPPE: Yeah. I think it is and that's why I mentioned that I liked Angular before because Angular actually does offer a full framework. And because they do that, they made a lot of choices for developers and some of these choices have a very, very big and positive impact on security. On the other hand, if you make those decisions, you become an opinionated framework and some people don't like that. They actually want the freedom to follow their own paths and then a less full featured framework like React might be an easier way to go.
CHARLES: But I think what happens is folks don't enter into that decision with their eyes open to the fact that they then now need to be their own security champion because they just don't even see it. We said the most dangerous thing is the things that you don't know.
PHILIPPE: Yeah, absolutely. And I totally agree. That's something that's at least a couple of years and probably still today, many companies moving into this space struggle like, "Which framework do we choose and why do we choose one or the other and which one will still be there in three years because we don't want to switch to another thing in three years," which is risky to our developers. I like that you said that Angular has this security champion knowledge built in because in Angular 2 and every version behind it, but the new version of Angular essentially, they spent a lot of time on security and they learned from their mistakes in the first version because there were some and they took that and they built a more robust framework with security built in by design or by out-of-the-box. Angular offers, for example, very strong protection against cross-site scripting. It's just there, it's always on and unless you actively sidestep it, it's going to protect you. And that's one of the things I really like about Angular and how they did that.
CHARLES: Yeah, that's one of the things that I really like too because I remember there was a blog post back, this is probably, I don't know, almost 10 years ago now, maybe seven or eight years, where someone was comparing why they were more interested in using, their servers were implemented in Ruby and why it was better to use Rails than just Sinatra which is just a very, very, very lightweight HTTP framework. And one of the things that he was pointing to was this new vulnerability was discovered and if you were using Rails, the middle way where the middle square stack is managed by the framework, you just upgrade a minor version of Rails. And now, by default, there's this middleware that prevents this entire class of attack.
PHILIPPE: Was that a cross-site request forgery?
CHARLES: I think it might have been.
PHILIPPE: I think Rails was one of the first to offer built in automatically on support for that. So yeah, that was a very good early example of how that can work really well.
CHARLES: And the advantage from the developers' standpoint, because the contrast that, if you'd been writing your application in Sinatra which is this is very, very low level based right on top of rack and you're managing the middleware stack yourself and there are no opinions, then not only do you have to like fix this security vulnerability, you have to understand it. You have to get to do a lot of research to really come up with what's going on, how is this going to affect my application and then I can deploy a fix. And that's like a huge amount of time, whereas you have the freedom to not even understand the attack. I mean, it's always better to understand but you can defer that understanding invariably knowing that you're kind of invulnerable to it. And I think for people who enjoy kind of pretending, not pretending, but that the security world doesn't exist and say, "Hey, I want to focus and specialize on these other areas and attain deep knowledge there." It's very reassuring to know that if a defense for a novel attack comes out, I can avail myself of it just by bumping a version number.
PHILIPPE: Yeah, absolutely. If you have everything in place to actually upgrade to that version that fixes those, that's a preferable solution. Towards the future, I believe it's going to be crucial to ensure that we can actually keep things up-to-date because everything that's being built today is going to require continuous updates for the lifetime of the application. I definitely hope that the frameworks get better and more secure and start following these patterns of naming the potentially insecure functions with something that indicates that they are insecure. I think that's definitely a good way forward.
CHARLES: Yeah. Can I ask one more question? Because this is something that is always something that I wonder about whenever you talk about any aspect of a system. And part of it is folks will not appreciate good architecture until they've experienced some sort of pain associated with not having that architecture in place. Their project fails because they couldn't implement a set of features without it taking months and years and they just ran out of runway, ran out of deadline. Those types of people who've been on those projects appreciate having a nimble system internally, good tooling. Folks who have experienced good tooling understand how much time they could save, and so, have a very low tolerance for bad tooling. A tool takes too long or is misbehaved or is not well put together, they just can't stand because they know how much time they're losing with security. Is there a way to get people to care about it without having some sort of breach, without having gotten smacked in the face? When you do your trainings, is it generally, "Hey, someone has experienced a breach here, and so they want to bring you in." Or is there some way to get people raise awareness of the problems they don't have to experience that pain but can just experience only the benefit?
PHILIPPE: That's, again, a very good question and that's also a very good illustration of why security is so hard. Because if you get everything right, nothing happens.
PHILIPPE: Or it might be if nothing happens, that nobody cares enough to actually try something against your application. So, there's no positive confirmation if you've done a good job. You can keep putting things off but eventually, there's going to be vulnerability and it's a matter of how you respond to it. We recently had a cross-site scripting in Google's homepage, one of the most visited pages on the web. And somebody figured out that there were some weird browser thing that could be abused and that resulted in a vulnerability on, let's say, such a simple page. So, even there, things can go wrong. So, what would be a good way to draw with some awareness about this is I would recommend following some simple new resources or some Twitter feeds. I have some security relevant articles there but plenty of other people in the industry have as well. And when you read such an article about security incidents, just think about whether this could happen to you or not. And that should probably scare the shit out of you. Simple examples like the Equifax breach, one of the biggest, most impactful breaches of the past few years happened because of an Apache library that was not updated. I think the Apache library, they had a known vulnerability in there. We knew about it. We had a patch, yet it took too long to install that patch and the attackers abused that vulnerability. This is something that probably can happen to each and every one of us because the attacks started, I think, 72 hours after the vulnerability and the patch had been published. So, ask yourself, "Would I have updated my servers in three days after I got that vulnerability report on GitHub?" Yes or no. And if the answer is no, then the same thing can happen to you.
TARAS: Lots to think about.
CHARLES: Yeah, there's lots to think about because the next thing that occurs to me is how do you even know if you've been targeted. Because a good attacker is not even going to let you know.
CHARLES: It's just better to siphon off your blood, like you said, than to kill the -- you want to be a vampire bat and come to the same cow every night and just take a little bit of blood rather than the lion that kills the cow and then the cow's gone.
PHILIPPE: I would say constant monitoring is going to be crucial and you need that data for all kinds of different purposes. You need to monitor everything that happens, first of all, for a post-mortem analysis. If something happens, you want to be able to see how bad it was. This user apparently got a full admin access and if you have decent monitoring, you will be able to retrace his steps to see what they did or did not get. So, that is one very good use case. A second use case is you can use that data to detect attacks. Usually when the attacks are noisy, it's an automated scanning tool but it might be an attacker trying to do things. Again, that may be something very useful for you to act on to see if there is a problem to prevent that user from connecting, or so on. And then, another very good use case of these things is actually inspecting the logs manually as an ops engineer or whatever, who is responsible for doing that, because that might again yield new insights. I've been talking to someone who said that they discovered an abuse of one of their APIs just by looking at the logs manually and detecting a strange pattern and looking and digging deeper into it. And the automated monitoring tools that they had installed that trigger on certain events like a mass amount of requests to the authentication and stuff like that, they did not catch this particular abuse. So, I would say monitoring there is absolutely crucial, for sure.
TARAS: So, the takeaway is higher attentive knowledgeable developers who will learn about security.
PHILIPPE: I would say the takeaway is security knowledge is essential for every developer. So, I encourage every developer to at least have a little bit of interest in security. I'm not saying that everyone should be a security expert. We should at least know about that the most common vulnerabilities in web applications, what they mean, what they might result in, and what to be on the lookout for. So yes, I think that's one of the crucial things to start with. And then within an organization, you should have someone to fall back on in case that there are security relevant things that you actually can talk to someone who does see a bigger picture or maybe the full security picture to decide whether these things are a problem or not.
I think we're closing or nearing the end here, but one of the things we haven't talked about is how to actually get started in security. What if you are interested in security after hearing this podcast and you want to get started? I want to give you just a few pointers so that you actually know where to look.
One of the first things to look at is OWASP. And OWASP is the Open Web Application Security Project. It's essentially a nonprofit that has the mission to improve the security posture or knowledge of developers, and they have a lot of resources on various different topics. They have a lot of tools available and things like that. What you want to start with as a developer is the OWASP Top 10, which is a list of the 10 most common vulnerabilities that exist in applications, just to open your eyes like these things exist in applications today and are definitely a problem. And then, there's a complementary Top 10 called the Proactive Controls and that's about how you, as a developer, can actually prevent these things. So, what should we know about implementing security, which guidelines should we follow. And these two documents are a very good place to start. And then there is a huge community that's actually mostly very eager to help people figure out the right way of doing things and solving these problems we have in our ecosystems.
TARAS: Awesome. That's great. Thank you very much.
CHARLES: Yeah. I'll take that in. That is really, really helpful. Well, thank you very much, Philippe, for coming on and talking about security. I actually feel a lot better rather than usually I'm thinking about securities kind of stresses me out. [Laughs]
PHILIPPE: You can bury the problem but it's going to return in the future anyway, so you might as well get onboard and start learning. It's not that scary if you actually -- it's a lot of fun. So, you should learn about security.
CHARLES: Well, I am looking forward to diving in. If anyone wants to get in touch with you, how would they do that on Twitter or Email?
PHILIPPE: Yeah, sure. I'm on Twitter. I'm always happy to chat about security. You can reach me by Email as well. I'm very easy to reach. And I'll be happy to help out people with questions. Sure.
CHARLES: All right. Thank you so much, Philippe.
Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old Email at firstname.lastname@example.org. Thanks and see you next time.
Jun 13 2019
Rank #6: An Analysis of NativeScript Mobile Platform
In this internal Frontside Podcast episode, Charles, Taras, and Jeffrey analyze the NativeScript Mobile Platform.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, a place where we talk about user interfaces and everything that you need to know to build them right. My name is Charles, a developer here at Frontside. With me today are Taras and Jeffrey.
TARAS: Hello everyone.
CHARLES: Today, we're going to be talking about NativeScript, in particular, and evaluating technologies and frameworks, kind of at the meta level. So, I'm kind of excited about it because we've been pretty heavily involved with NativeScript for the past three months or so. And so, we've gotten to look at it both from beginners' eyes being kind of totally fresh to the platform, but then actually having to start to pump up against some of the edge cases which is what always ends up happening when you actually use a framework for real. Let's get started.
TARAS: We should clarify that this is specifically for preview purposes because if you're going to be shipping the application to production, you still need to go through all those things before...
TARAS: But the onboarding process, you could just install the preview app and then you can point a QR code and it will open that app, whether it's in Angular or in Vue, that app will open up in the preview app and you have a native app that you could play around with.
JEFFREY: And that's key both for the engineers who are playing around with this and building this and also really key for the non-engineers who are part of the team to be able to really easily spin up and see what the engineers on the team are working on.
CHARLES: That's exactly why we thought, "Hey, we want to be able to use this mechanism for preview apps." In the same way on the server side, you have preview apps associated with a pull request. When we saw this, what we immediately wanted to do was have a bot post a comment onto a pull request with a QR code, so that anybody could just, boom, test out this app on their phone.
TARAS: We ultimately ended up setting that up but not quite that way because the original idea of being able to have something like danger bot post the QR code to the comments, you can kind of point out with your phone and open the preview app, that didn't actually pan out. Charles tried to implement that. What happened there?
CHARLES: What it actually turned out was that the preview functionality was dependent on a central server, a central NativeScript server. So rather than kind of statically bundling the assets and just saying 'these assets are this URL and just pull them in and bootstrap your NativeScript application that way', it required a lot of extra stuff. So, it required you to be running a Webpack Dev Server that was building your assets and then basically registering and doing some port forwarding with that dev server to a central NativeScript service that was provided by the company that underpins NativeScript. And that connection needed to be hot and live the whole time for that to work.
So, while it was really cool that you could get the QR codes up and running, unfortunately that functionality could not be decoupled from the hot update and the central service. Those central services were kind of hard coded into the tools.
TARAS: Yeah. So we eventually ended up implementing the preview apps that we wanted but we ended up using Appetize.io to essentially -- the process there is you build the app, you upload the app to Appetize and then danger bot embeds a link to a URL where you can open that app and it will essentially stream like it's running somewhere in a simulator for iOS, an emulator for Android and it will stream a video of that and you can interact with it, kind of like a VNC setup.
TARAS: And that actually accomplished the goal. It's just we weren't able to do the way that we thought we were hoping to do it straight off with the preview app mechanism.
CHARLES: It accomplished the goal. And Appetize is an incredible service that lets you preview the apps on pretty much any type of Android device, any type of iOS device, right there inside of a pull request. But what it didn't allow us to do was pop up your actual device, your actual phone and scan a QR code off of the pull request and pull down the assets. That would have been amazing. But it doesn't always work out that way. And I don't know if that would work long term anyhow because you can't pull down native libraries over the wire and funk them in. That's a big, big no-no. So, the process does have limitations. But nevertheless, that part was really cool.
That is really, really powerful that there's nothing off limits. There's nothing at an arm's distance. There's really not much you can't do because all of those things are available to you. There's nothing that's off limits. That means that they can build cross-platform components on top of those APIs. Whereas a sort of system like React Native which does have cross-platform components, that's kind of where the base layer is but you can't crack open the hatch and go down the next level and start mucking around, unless you want to actually start meddling with the React Native source code or recompiling Swift in Java code.
TARAS: For me, I think this architecture is probably my favorite part of NativeScript.
JEFFREY: Mine too.
CHARLES: Yeah, me too.
TARAS: I really like this part. I kind of hope that everything else is as clever as that was.
TARAS: That was really cool. The challenging part was that a lot of that kind of awesomeness, like everything around it wasn't quite as polished. And so, one of the big things is that like around tooling, because one of the things about having grown up in a way like in the Ember community, in a sense, we have a certain expectation of what the level of polish from tooling that we would expect. And it's kind of supported in the way like when you look at how React or React Native tooling is, even Angular tooling, it's very polished. You kind of expect to see what you need to see when you're looking at a CLI input and you don't see anything else. That level of polish. I think part of the changes that they're going through, maybe that's part of the reason but that same level of polish isn't available around the tooling.
CHARLES: There are these fantastic qualities about the platform and it is amazing. We were using Angular and a lot of people are using Vue and things like that and that actually is pretty incredible. And there is nice tooling, there is command line stuff, but we started to run into issues where, for example, it was very clear that we were pretty much, as far as I could tell, one of the very, very few people running a NativeScript project on CircleCI or in a CI environment at all. It had capability for testing, both for acceptance testing and for unit testing, but it required changes to the core framework and the core tools in order to get those tests to work in a CI environment.
JEFFREY: Before we kind of get into the testing story there, some of the issues were around determinism of reliably reproducing your whole NativeScript environment and stack every time because that's such a key feature of doing it. And on a CI server, it's like, "Hey, we need this to load in the same exact packages every time." And so, we ran into challenges there.
CHARLES: Right. We weren't caching. This was an artifact of the install. And so, we were caching the install, so essentially the yarn.lock was not changing. But the directory was not getting generated unless the cache key changed.
TARAS: And we spent spent quite a lot of time...
CHARLES: Two or three days out.
CHARLES: What that said is, "Oh, nobody's really running this in CI." Nobody's actually building an app from scratch every time.
TARAS: There are people in NativeScript team that actually does a great job of documenting. They did have example projects that exist but sometimes that example project doesn't fit like a perfect combination of what you're looking for. There was an example project that was showing how to run on CI but it didn't use TypeScript. And so, that's where we lost a lot of time.
JEFFREY: So, let's talk about testing since that's kind of the core, the most important part of why you even want continuous integration capabilities to begin with. What did we run into there? What did it look like?
TARAS: Well, I think it's safe to say that we were really on a bleeding edge of testing capabilities in NativeScript ecosystem with Angular, at least. But I think it was still an interesting project. We were using the latest builds. And I have to say I think this is one of those things that's going to be kind of consistent through this, is like the people in NativeScript team are amazing. They're so easy to work with. They're so accommodating. When we ask for stuff, they're on it. But it was a lot of things we're trying to figure out like how do we run unit tests, what can we do. Ideally, we wanted to run, first and foremost, we started with how do we run functional testing. So we spent quite a lot of time trying to get Appium set up. I spent a good two to three weeks on that and it was not productively spent time.
There were multiple ways to package your app. And so, we ran into problems where, like TypeScript kept coming up as a problem and the way in which we were bundling our assets. So, in order to get TypeScript to work, we kind of had to get Webpack running. But the problem is it felt like three quarters of the tooling wasn't Webpack compatible yet. And so, it meant that other pieces of the build were breaking because of this. And so, we had to be on the bleeding edge of several different aspects of the runtime. And the problem is when you're on the bleeding edge, that can break other stuff.
TARAS: But there's complexity in running on native platforms that I think a lot of this complexity is kind of leaking to development experience because one of the challenges is your tests need to run on the native device in the application. So, you have to build the app. You have to push the app into the actual device. So, there's like all the setup of installing the at the app on the device.
CHARLES: You have to launch the simulator.
TARAS: Yeah, right.
CHARLES: To make sure the device is connected.
TARAS: And you run your tests in there. So, that created kind of this situation where we say let's just kind of set Appium aside and just use unit testing which is a very small fraction of the kind of testing that we actually want to do. It will test very little. But let's just do that because getting functional testing to work was really kind of not going anywhere. So once we start doing unit testing, one of the challenges is that it takes like 30 seconds to start your tests. And then, if you for whatever reason, made a mistake, the moment you cancel the build, it leaves, like it doesn't clean up of itself well. So, it leaves processes running in the background. And so now, you spend another like 10 to 15 minutes Googling around for a cookie, "How do you find these processes and stop them?" So, we eventually settled on having a script that does that, but this is the kind of things you have to end up doing because there's a bunch of things that are wired together, but they're not wired together in a way that is seamless. And so, you end up kind of just debugging a lot of stuff where you just want to run some tests but you end up doing all these other stuff.
TARAS: And you spend a couple of minutes just doing something that you'd expect to happen in like 20 seconds.
CHARLES: Right. There is a feeling that every aspect of the system is coupled to every other aspect of the system in kind of varying ways of interconnectedness. And that's not what you want for a very, very complex system. You want it to be extremely modular.
So, I think we should keep the command line tool. There's probably a separate discussion, I think, about that. But you have to close the book on the Appium and the unit testing. I think the other problem was that you have to run these things on simulators. On macOS, that's not a problem because the simulators ship with X code. And so, you don't actually require an external service. Whereas in CI on Android, it's very unlikely that you're going to have Android emulators on hand because they require a separate virtual machine. Android emulation is actually quite heavy. If you're running through Android Studio or something locally, you essentially need VirtualBox or some equivalent to run your Android simulator because you actually need that simulated hardware. If I understand correctly, that was actually not something that had been really accounted for. It was that you might want to be running simulators not on the same machine as what you were developing on or what the actual that you were building on.
TARAS: Yeah, a lot of the tooling seems to be designed around this idea that you're going to be building and running everything on your machine. And so, you can spin up a virtual machine easily. But in CircleCI, for example, they don't support running a virtual machine inside of a Docker container because for that, you need a feature of a virtualization that is not supported in many CI platforms. You have to run a parallel server if you want to have like Appium running, for example. You need to have a separate server running like an Azure or a Google Cloud somewhere that is able to run virtualized servers that have a host machine that's being guest systems that are running the actual Android emulators of different versions. And so, when I started doing research in this, there are companies that are doing this really well but it's not unusual to be using hardware from Amazon that costs thousands and thousands of dollars per month.
I think for anyone who's getting into mobile development, I would say the hidden gem of Android world is Genymotion. Those that do a lot of Android development, they know about it. But Genymotion has both like a desktop environment and it has SaaS offering that they're in the process of releasing. And so, what it allows you to do is when you run it locally or on your local machine, it allows you to create a virtual machine that is running in VirtualBox and then it allows you to run kind of optimized environment for running Android. And when you do that, it's really fast. It's very smooth. It makes running Android devices locally as easy as it is to run iOS devices on macOS.
CHARLES: I remember starting out and trying to actually just get any Android emulator running on my Mac and I couldn't even do it.
JEFFREY: It was such a huge time saver.
TARAS: And to have this Saas offering is really great because you could basically create your virtual machines on demand and then you install into a virtual machine from your CI server and then you run your tests there. That's kind of the key that I found to be able to run tests and automate it against emulated devices for Android. Genymotion is really great.
CHARLES: Yeah. Again that's the kind of thing that you need when you're in CI. And so, one of the things, I think, one of our discoveries is that there just isn't -- when we started working on this and we haven't seen a culture of running these tools in the cloud and accounting for the fact that you might have not all of the tools running on the same machine.
From, I would say, the beginning, I remember the kind of the diagnostics command didn't work but we were running it on a CI server. So, there's a diagnostics command that you run to see do you have this, do you have that, do you have that. It would work and give meaningful results when I wanted to debug my CI server because when we were initially getting set up, something wasn't building right, there was some dependency missing. And I just wanted a diagnosis but it was trying to install all those tools for me. And I was like, "No, no, no. I don't want you to do anything. I don't want to install them. I'm going to be doing all of that as part of the setup of the CI environment. It's going to be installed, it's going to be cached. I don't want you to just try and like massage my system into a suitable state for NativeScript development. I just want you to diagnose what is wrong. Tell me, am I missing this compiler? Maybe I've got the wrong version of Android SDK. Tell me what's going on." And I couldn't get that to work. That was very frustrating. I think it was because the kind of bulk of the assumptions was that it was going to be individual developers working on their own laptops or their own desktop computers to build, to test, to distribute these applications. I think that's becoming less and less the case. I mean, at this point, that's not a way that we're willing to operate.
TARAS: And we eventually figured out how to do all this stuff, right?
CHARLES: Yeah, we have.
JEFFREY: We have.
TARAS: We have the entire process working but it took a lot longer than one would imagine. It took all the time that we had allocated to it which we thought was very generous amount of time but it took like almost a month to get everything set up. The great part of this is that we do have now everything working. And so, there's a repo where people could take a look if they want to get all stuff working on CI, but it took quite a bit of work in figuring out.
CHARLES: Yeah. Actually, I think worth probably a Screencast to show some of those capabilities because it is really exciting. I mean, when you actually think about the pipeline in its entirety. But we never were able to get functional testing working.
CHARLES: Right. When you have a leaky abstraction like that.
TARAS: Part of the problem is because people use leak abstraction. And so, what's happened in Native -- we actually got on the call with NativeScript core team and they're excellent in really being very helpful, understanding what the problems are, and providing pass on making things better. But what's happened as a result of having this leaky abstraction is that people are relying on the leak. And so now, the leak is the API. And so, we can't change that.
CHARLES: And the answer that you really need there is, "We can't change that without breaking stuff. Here's our migration path for deprecating this and introducing a new API." And that gets more into the process stuff and it seems like the process for making changes to the underlying API, I think, could use a little love in the sense that it's kind of opaque as to where the platform is going. There's not a concept of like an [RSC], there's no roadmap about what to expect. What is this API going to look like in the future? Is this stable? If I were writing a software and someone said, "Hey, there's this leaky abstraction," I think my reaction would be, "We've got to fix this." And we also have to acknowledge that there are users who may depend on this. And so, we have to be very deliberate about it.
TARAS: The challenge with this too is that NativeScript kind of outgrew its hands because I think originally, it wasn't meant to be hosting Angular and hosting Vue. Vue didn't exist. Angular didn't exist when NativeScript started. So I think what's happened is that these views that were available, I wouldn't call them components because they don't act like components, but they're exposed in Angular like components but the API feel like Vue objects. So these Vue objects that you consume, that you render in Angular, for example, or in Vue.js, they are the same APIs that NativeScript had before Angular and Vue.js.
CHARLES: Right. You know what? It feels like there's a MVC framework, like a Circa 2010, 2012 MVC framework that has now become the foundational layer for Vue frameworks that have had significant advances in the way we conceive of model in Vue and how data is generated and passed around and how views are rendered off of the data and how reactivity is changed. But there's still, the underlying platform has not evolved. And in fact, this was originally user-facing APIs and now these APIs have become foundational for other user-facing APIs but haven't had the iteration and evolution to make them robust.
TARAS: And flexible enough. As a result, you have the situation where not only is it really super easy to deoptimize the views simply because the requirements of keeping performance expectations are not obvious. One of the things that I found is that the list which is, lists are like 50% of most applications. Before I go into the problem with list, the nice thing about lists in NativeScript is that because they're interacting directly with native APIs, you have really fast list when they're optimized. They're really easy to work with. But they easily get deoptimized by the fact that the expectation to keep the list fast, you have to use this API in NativeScript called array observable and observable. And this is not to be confused with like...
CHARLES: [Inaudible] observables?
CHARLES: It's not to be confused, but in fact, every conversation involves a lot of confusion. Because we were using observables, right?
TARAS: And we were actually using observables. So, we're using observable [inaudible] and we're using this array observables and object observables. And so, it's necessary for NativeScript to, essentially what it expects for list to be fast, is it expects that it's going to receive an array observable which is an object that wraps an array because it needs to know when an order or length of data rate changes. So what happens when you pass an array observable, a NativeScript array observable into a list? It will listen for change events on that object. But if you want to change the value of each of the items, like if you want to change a property on the object and have your view remain optimized, the array observable has to have an observable object which allows NativeScript ListView to listen for changes, property changes on the object. You pass this array observable which contains observables that ListView listens for changes on to make sure that it knows how to correctly apply this change to the list. If you don't have this magic, like if you haven't figured out this recipe for ListView performance success, you're going to have a really hard time because it's really not clear at what point and how this thing got deoptimized, why has it just gotten slower.
CHARLES: There's a lot of iteration that needs to happen there and it's not clear what the plan, what the priority, or even how you will even begin to go about this. Because I think that the internal working is that it seems basically to be controlled by one company. I don't recall seeing any contribution from anybody except for Progress which is Progress Incorporated is the company that's kind of the controlling interest, the original company that developed it.
CHARLES: And there was a certain level of opacity in terms of process. For example, I filed an issue which was actually a blocker. For us, it was actually causing our Android build not to work. I didn't hear anything about it. And then, all of a sudden like four days later, a fix came through referencing another repository on which this thing depended with. There was not a lot of context service. So it was obviously referencing a bunch of context that probably happened between two people in a face-to-face conversation. But I couldn't really tell what was going on, why it was an issue, because there was no comment. It was just a pull request that was referencing this issue. I never got a notification. I actually had to go and be like, "Hey, I really would like for this issue to be solved. I wonder if I..." I was actually going to post a, "Hey, is there any progress on this?" Or, "Is there any way that I can help? What can I do to get this looked at?" And I saw that there was another pull request that had referenced my issue. And it was merged and I looked down, but then there was no indication of when this would be available for public release, how I might be able to work around it. And so, the strange loop that didn't get connected was, "Hey, you've got a user who files an issue. You actually use this as the impetus to fix the issue and make a release." But then that whole process was completely invisible to me.
TARAS: You know what? It sounds like you wanted for it to work [inaudible] but you got a pulling mechanism.
CHARLES: Yeah, exactly. Well, I wanted someone to say like, "Hey, here's what's going on, and we're looking right into it." Or, "We're going to look into it in like two months," or, "We can't address this now. But here's a workaround for it." Or, "I don't have a workaround." That's just kind of the expectation that you have when you're playing with open source. In many ways, it does not feel like an open source project.
TARAS: Let's just do a quick note about Saas. Jeffrey, what did you find about the styling of NativeScript views?
JEFFREY: All the components that come kind of shipped as part of the NativeScript core set of components all have styles attached to them. They have CSS attached to them. And as part of the standard data script workflow, with your build toy, you have SaaS available which is very nice. But actually on a recent project, we're not using Saas at all. We're simply using post-CSS and we were able to kick out some CSS variables that turned out to be really nice for theming. So as kind of a future friendly experiment, we were trying to have a light theme and a dark theme since that is very recently now a core part of Android and very likely will be part of iOS this year, where there's kind of a light theme and a dark theme for everything. We were trying to do that. The simplest way to do that with standard web tools is with CSS variables. You can have the flexibility, you have the theming with those. It's so nice. You just, "Hey, my primary color is this color in one scenario and it's this color in another." And we just didn't really have the flexibility to do that with SaaS by itself. And so, that's kind of a limitation of the tooling right now that I hope in the future, we'll have some more sophisticated CSS tools. And really, NativeScript's move toward Webpack and having that as a primary part of the workflow really opens up that possibility that I hope somebody runs with in the near future.
TARAS: Yes, let's bring it all back together.
CHARLES: Can we pause for a moment? Because I actually do think it's important that we at least touch on the command line. I can give a little bit of a kind rant in here but I think that's actually something really important that we have to talk specifically about that.
But Taras, you also mentioned often if you stop the process midway, it will leave a thousand things open and they're just spewing output to your console. The console output, unfortunately, means there's a big noise to signal ratio because it puts out all of the content for Webpack. Every little thing that it's doing with any of the devices, it's logging to the console. So, it doesn't give you a sense of control. So, what you really are looking for in terms of a command line is, "Hey, I've got this incredible sprawl of complexity and I want to feel like I'm on top of it." And unfortunately, by leaving these things open and having so much console output and having the console output not be formatted well, there's all kinds of colors. Every single tool that you're using whether it's Webpack or whether it's Karma or whether it's just console outputs that you are happing inside of your NativeScript application, the brand of those tools comes through. Webpack is a great example. Its console output feels very Webpack. So when you've got Webpack content randomly interleaved with your console content from your Mocha content, from Karma, all of these competing brands, it doesn't feel like a cohesive developer experience. And so, I really, really hope that -- so, to the point being where I felt like I could not live with that command line tool without rewriting it myself. If we want to use this platform long term, we'd have to either have an alternative command line tool or really, really, really help the NativeScript team completely and totally rewrite the command line experience.
TARAS: I would love to work on fixing a lot of these parts about NativeScript if there was a way to actually do it in terms of like, if they wanted to pay us to help them kind of bring some of these things to a state that would match. For example, what's available in Ember or available in React CLI, I would love to do that.
CHARLES: React Native, yeah.
TARAS: Yeah, let's do that work. But who knows what's in store? A lot of awesome platform like the idea around NativeScript architecture is fascinating and it's really, really powerful and really wonderful people doing some, trying to tackle really challenging problems, but it's all glued together in a way that doesn't instill confidence. And it just makes everything feel wobbly, just makes it feel like you never know, is it a problem? Where's the problem from? What is causing this?
CHARLES: Yeah. And if I fix this thing, is it going to break something else?
TARAS: Yeah, we've seen it happen actually with one of the solutions that was introduced to a bug that you were referring to earlier.
CHARLES: Yeah. So that was our three months experience working with NativeScript.
TARAS: We are considering other things now, very seriously looking at Flutter as an alternative for the same client, same scenario. Flutter is looking pretty exciting. There's a lot of things that are really good there. So in three months, we'll do another report and talk about Flutter and what we found. So, that's it.
CHARLES: And I will say I'm actually not like super excited about dart but I'm in dart spot.
JEFFREY: That's a whole other conversation for yet another episode.
CHARLES: I think that, to continue the conversation maybe next week, next time we have kind of an internal podcast, is I would like to really talk about platform evaluation because really you need three months, at least, to get a good idea of this. Is this going to work for the next five years? And most of the time, we give it a week or give it a two week. Or someone comes on who's really excited about this one particular technology and you go off on that tangent. I think there's an interesting meta discussion about how do you select technologies. And we don't have time for that now, obviously. But it's definitely something that I want to have in the future.
TARAS: Sounds good. I think that will be a good conversation for sure.
CHARLES: I guess that is kind of the executive summary on NativeScript from our perspective. With us being three months in, I think, like you said, there's a lot there.
Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at email@example.com. Thanks and see you next time.
May 24 2019
Rank #7: Deployment with Luke Melia, Aaron Chambers, and Mattia Gheda
Luke Melia, Aaron Chambers, and Mattia Gheda john Taras and Charles to discuss all things deployment!
Luke Melia: Luke has been working with Ember since it was under early development as Sproutcore 2.0. Ember.js powers a SaaS company he co-founded, Yapp, and they funded their business for a couple of years doing Ember consulting under the Yapp Labs moniker. They’re full-time on product now, and his engineering team at Yapp (currently 3 people) maintains around 6 Ember apps. Luke helps to maintain a bunch of popular addons, including ember-cli-deploy, ember-modal-dialog, ember-wormhole, ember-tether, and more. He started the Ember NYC meetup in 2012 and continues to co-organize it today.
Aaron Chambers: Aaron Chambers: Aaron is the co-author of EmberCLI Deploy and is currently an Engineer at Phorest Salon Software, helping them move their desktop product to the web platform. He's been using Ember for 5 years and maintains a number of plugins in the EmberCLI Deploy ecosystem. Aaron loves trying to work out how we can ship JS apps faster, more reliably and with more confidence.
Mattia Gheda: Mattia is a Software Engineer, Ember hacker, Ruby lover and Elixir aficionado. Currently he works as Director of Development for Precision Nutrition where Ember, Ruby and Elixir power several applications. He loves meetups, organizes Ember.js Toronto and co-organizes Elixir Toronto.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, a place where we talk about user interfaces and everything that you need to know to build them right. My name is Charles Lowell, a developer here at the Frontside. With me also co-hosting today is Taras Mankovsky. Hey, Taras.
TARAS: Hello, everyone.
CHARLES: Today, we have three special guests that we're going to be talking to. We have Aaron Chambers, Luke Melia, and Mattia Gheda who originally met collaborating on fantastic open source library that we, at the Frontside, have used many, many times that saved us countless hours, saved our clients hundreds of thousands of dollars, if not more. ember-cli-deploy. We're gonna be talking not about that library in particular but around the operations that happen around UI. So, welcome you all.
LUKE: Thanks, it's great to be here.
CHARLES: Like I said, I actually am really excited to have you all on because when we talk about the platform that you develop your UI on, something that often gets short shrift in communities outside of the Ember community is how do I actually deliver that application into users' hands. Because obviously, we don't want it to be working just on our laptop. We want it to be delivered to our users and there are myriad ways that that can happen and it's only gotten more complex since the last time we talked which must have been like three or four years ago. I kind of just have to ask, I think that what you all were talking about then was cutting edge is still cutting edge now but there must have been some pretty incredible developments like in the last three or four years. What have been kind of the new insights that you all have?
And so, what we decided to do was to try to evolve ember-cli-deploy into a platform essentially, an ecosystem that could let people mix and match plug-ins to do in their organization without locking them into an opinion that might simply be a non-starter in their org.
MATTIA: Yeah. I pulled some numbers just yesterday and we have currently 150 different plugins attached to themselves, to different parts of the pipeline. So some of them are about how to build the assets, some of them are about how to compress them, some of them are about shipping. And they allow people to ship it with different ways like we are seeing [inaudible] with just simply Amazon APIs or Azure APIs and some of them even are about just how to visualize data about your deployments or how to give feedback to the user about what was deployed and represent the information.
And then this is kind of a bit more detail, probably specific to us but we also added this idea of plugin packs. So, in order to help people define their deployment story, we created this ideal of plugin packs. Plugin packs are simply group of plugins. So, plugins grouped together. As a user, if you want to implement what we call a deploy strategy, you can simply install a plugin pack and that will give you all the plugins that allow you to deploy in a specific way. And that's kind of like an optimization that we added just to make it easier for people to share deployment strategies, share ways of deploying applications.
CHARLES: Right. It's almost like an application within the framework.
MATTIA: Yeah, exactly. But to stay on the community side, I think that the interesting part about what Luke was saying which was a great success for us is that all we maintain as the core team for this project is the core infrastructure, so the pipeline and a thousand of plugins. Everything else is community-based. And often, even in my day-to-day work, I end up using plugins that I didn't write and that I don't even maintain. But because the underpinning of it were designed especially by Luke and I are flexible enough. It just like has been very, very stable and very, very reliable for many years. So, I will say definitely the idea of like in the spirit of what Ember is, I guess, creating a shared ecosystem where people can add what they want and extend what was provided has been the one single biggest win of this project.
CHARLES: One of the things that I'm curious about is we've talked about how you're allowing for and kind of embracing the fragmentation that happens in people's kind of the topology of their infrastructure. What do you see is the common threads that really bind every single good deployment strategy together?
CHARLES: It's good to think about those things as soon as you possibly can and make sure that you have all three of those bases covered really before you start adding a whole ton of features.
TARAS: Sprint 0, right?
LUKE: In Agile, we call Sprint 0 the phase the thing you do right in the beginning. You've got a skeleton of an app and then you get the deployment infrastructure going, you have the test infrastructure going, so that there is no task within your actual feature development where you have to do those things. And I think that can be a valuable concept to embrace.
I would just add to Mattia's three points that for deployments, to me, some very simple qualities of a good deployments are repeatability. You need to be able to reliably and consistently run your deployment process. Sounds simple but there's plenty of operations that have run up way too long on manual deployments. So, we don't want to see those rollback capabilities if you have a deployment that you realize was a mistake right after it gets into production. I'm sure none of us have ever experienced that.
CHARLES: That never happens to me.
LUKE: You want to have a method to roll that code back. That's something that can be remarkably complex to do. And so, having some guardrails and some support mechanisms to do that like ember-cli-deploy provides can be really useful. But whatever your approach is, I think that's a necessary quality. And then I think we start to step into kind of more advanced capabilities that a good deployment architecture can provide when we start to think about things like personalization, A/B testing, feature flags, these kinds of things. And that requires more sophistication, but you cannot build that on a deployment foundation that's not solid.
AARON: I think for me, one of the things I've been really thinking about a lot lately, it's a bit of a mindset shift, I think, to get to where the things Mattia was talking about separating those different parts of deployment. And so, I really start to realize the traditional mindset around deployments like I build some stuff and I ship it to the server and then the users get it. But if we can actually stop and actually split our understanding of deployment into two separate phases. One is the building and the physical shipping of the files; and the other one's actually making them available to people. You open up this whole world of our features that you wouldn't normally have. So to be able to actually physically put stuff in production but not yet have it active, as in users don't see it yet but you can preview those versions in production against production databases. And then at some point after the fact, decide, "Okay, I'm now going to route all my users to this new thing," And to be able to do that really easily is massively, massively powerful. And so, to me, the thing I've been thinking about lately is it is a small mindset shift away from packaging everything up and pushing and overwriting what's currently there to being something, again like Luke said, immutable deployments where everything we build and ship sits next to all the other versions and we just decide which one we want to use to look at it any time which leads into then, I guess, A/B testing, feature flags and things. So I guess deployment really is not so much about the physical shipping, that's one part of it. To me, deployment now is shipping of stuff, as in physical deployment and then the releasing it or enabling it or activating it to users.
CHARLES: Or routing it. Sounds like what you're describing is an extraordinarily lightweight process.
AARON: It is, yeah.
CHARLES: To actually route traffic to those files.
CHARLES: I mean that's absolutely fascinating, though the capability that you have when you have the ability to have these versions, the same versions or different versions of your application sitting along next to each other and being able to route traffic. But it also seems to me like it introduces a little bit of complexity around version matching because only certain versions are going to be compatible with certain versions of your API. You have different versions of your API talking to the -- so the simplicity of having kind of mutable deployments, so to speak, is that everything is in sync and you don't have to worry about those version mismatches. Is that a problem or this could just be me worrying about nothing? But that's kind of the thing that just immediately jumps out to me is like are there any strategies to manage that complexity?
CHARLES: Keep repeating ourselves if we think that that [inaudible] actually doesn't exist even in the simple case?
MATTIA: Yeah. I think that that's to reiterate what Luke is saying. That's exactly the point. You can pretend it's not there but it is and you have no way to avoid it. Once you ship something to a browser, you have no control over it anymore. And so, you have to assume that somebody is going to be using it.
LUKE: Aaron, I think you too, I don't know if you can share it. But you recently told us some stories about kind of what you encountered in your work about this and of how long people were using versions and stuff.
AARON: Yeah. Something that we hadn't sort of put a lot of thought into. But the last place I worked at, we had quite a long lived app and we're using feature flags and we're using launch [inaudible] something and it gives you a list of flags and when they were last requested. And there were also flags that we removed from the code and it was just a matter of waiting until all the users had the most current version of the app and weren't requesting the flag anymore. But this one flag just kept getting requested for months and we just could not work out why. It really sort of opened my eyes up to this exact problem that these long lived apps set in the browser and if you have someone that just doesn't reload the browser or restart the machine or anything, your app can live a lot longer than maybe you actually realize it is. So we're shipping bug fixes, we're shipping new features, and we're all patting ourselves in the back. We fixed this bug but have we really? If your users haven't reloaded the app and gotten the latest version, then you haven't actually fixed the bug for some number of people. And it's really hard to tell them as you think about this and put things in place, really hard to tell what versions are out in the world, how many people are using this buggy version still.
CHARLES: Yeah, that's an excellent point. I haven't even thought about that. I mean, what is the countermeasure?
AARON: We hadn't made it until we came across [crosstalk].
CHARLES: It's nothing quite like getting smacked in the face of the problem to make you aware of it.
AARON: That's right.
CHARLES: So, what's the strategy to deal with that?
AARON: I guess for me, my learnings from that would be from very early on thinking about how we're going to encourage people to reload, to start with, and maybe even have the ability to force a reload and what that means but then that has gotchas as well. You don't want to just reload something when a user is in the middle of writing a big essay or something like that. But definitely thinking about it from the start is one of the things you've got to think about from the start. But I guess something that I'd like to implement and I've kind of thought through but not really explored yet, but the ability to see what versions are out there in the world and there are things I've been thinking about in terms of this little server that serves different versions. Maybe we can start having that kind of tracking what versions are out there and who's using what and being able to see because it would be great to be out to see a live chart or a dashboard or something that sort of shows what versions are out there, which ones we need to be aware of that are still there and even what users are using and what versions they can maybe even move them on, if we need to. But there's definitely a bunch of things that aren't immediately obvious. And I don't know how many people actually think about this early on, but it's critical to actually think about it early on.
MATTIA: Yeah. I was going to share what we do which is very similar to what Aaron said just maybe for the listeners to have some context. The first thing you can do is basically what Gmail does, which is every time a web app sends a request, an [inaudible], it will send the version of the app with the request and the backend can check. And the backend can check if you are sending a request from the same version that is the most recent deployed version. And if it's not, this sends back a header and the same way that Gmail does, it will display a pop up that is like, "Hey, we have a new version if you want reload." And on top of that [inaudible] is that we have a dead man's switch. So if we accidentally deploy a broken version, a part of this process, the frontend application tracks in the headers. And if a special header is sent, it force reloads, which is not nice for the user but it's better and sometimes is critical to do so.
CHARLES: Right. I remember that was that case where Gmail released something. They were doing something with broken service workers and the app got completely and totally borked. I remember that my Twitter blew up, I don't know, about a year ago I think, and one of the problems I don't think they had was they did not have that capability.
MATTIA: I mean, you learned this the hard way sadly. But I think these two things are definitely crucial. And the third one, [inaudible]. I thought, Luke, you had the ability that Aaron was talking about like tracking versions in the world. And I think that's more useful for stats so that you know how often your users update. And then you can make the design decisions based on that and based on how much you want to support in the past.
CHARLES: Yeah. Crazy thought here but it almost makes me wonder if there's something to learn from the Erlang community because this is kind of a similar problem. They solved 20 years ago where you have these very, very long running processes. Some of them there's some telephone servers in Sweden. They've been running for over a decade without the process ever coming down. And yet they're even upgrading the version of Erlang that the VM is running. And they have the capability to even upgrade a function like a recursive function as it's running. And there's just a lot of -- I don't know what the specific lessons are but I wonder if that's an area for study because if there's any community that has locked in on hot upgrade, I feel like it's that one.
AARON: Makes me feel like we got a whole bunch of work to do.
CHARLES: We welcome them. I'm always happy to give people plenty more work to do. No, but how they manage even being able to do migrations on the memory that's running. I don't know if it's something that's going to be achievable but it sounds kind of like that's the direction that we're heading.
CHARLES: I'm curious because when we're talking about this, I'm imagining the perfect evergreen app but there's also feels like there's maybe even a tension that arises because one of the core principles of good UI is you don't yank the rug out from underneath the user. They need to, at some point and we've all been there when the application does something of its own agency, that feels bad. It feels like, "Nope, this is my workspace. I need to be in control of it." The only way that something should move from one place to the other without me being involved is if it's part of some repeatable process that I kicked off. But obviously, things like upgrading the color of a button or fixing a layout bug, those are things that I'm just going to want to have happen automatically. I'm not going to worry about it. But there is this kind of a gradation of features and at what point do you say, "You know what? Upgrading needs to be something that the user explicitly requires," versus, "This is something that we're just going to push. We're going to make that decision for them."
LUKE: Yeah, it's a great question. One of the things that I'm curious what you all think is when you think about the mental model that our users have of working in a browser app, do you think that there is a mental model of, "Oh, when I refresh, I might get a new version." Do people even think about that? Or are they just like your example about a button color changing as kind of a minor thing. I don't even know if I could endure stack. We've all been I think in situations where you do a minor redesign and all of a sudden, all hell breaks loose and users are in revolt. Take the slack icon. So, I think it's a fascinating question.
CHARLES: I don't know. What's the answer? Do you always ask for an upgrade just observing? I don't have any data other than observing people around me who use web applications who don't understand how they actually work under the covers. I don't think it's the expectation that this code, this application is living and changing underneath their feet. I think the general perception is that the analogy to the desktop application where you've got the bundled binary and that's the one you're running is that's the perception.
AARON: I'd say the difference there is that, and with all these new ways of deploying, we're shipping small things faster in multiple, multiple times a day or even an hour. So it's not the sort of thing you really want time to use. There has been an update, need to upgrade as well. And that's the difference between the desktop mentality. And if that's the mentality they have, it sits quite a bit of a shift, I guess.
MATTIA: It makes me think that one of the tools that the users -- if you take a look at the general public, there's probably one tool that everybody can relate to which is Facebook. So, I think if there is a way to say what do people generally expect. There is a business user which I think we are often most familiar with but the general public, probably what they're most familiar with is what happens in Facebook. And I don't use Facebook almost. I haven't used it for a couple of years but I wonder how much of what people experience in Facebook actually impacts the expectations around how applications should behave.
LUKE: I think that's a really good question. I do think your underlying point of you have to know your own users I think is an important one also. Obviously, some folks are going to be more technical than others or some audiences will be more technical than others. But I would even question, Charles, your suggestion that people think of it kind of as like a binary that it stays the same until you refresh. I think people have an idea that web apps improve over time or sometimes they get bugs but hopefully that they improve and change over time, and that there is a tradeoff there that means sometimes there's something new to learn but at the same time, you get new features. But I don't know that people necessarily associate that with and it happens when I hit reload or it only happens when I open a new browser, like I don't know that it's that clear for people in their head.
CHARLES: Right. I can see that. But the question is if the evolution is too stark, I think people tend to get annoyed. If they're in the middle of a workflow or in the middle of a use case and something changes, then it gives it a feeling of instability and non-determinism which I think can be unsettling.
LUKE: Definitely. We all value, as engineers, we value getting into that flow state so much of like, "Oh man, I'm being productive. I don't have any distractions." And you kind of owe that to your users also to be able to let them get into that state with your app and not be throwing up, "Hey, there's new stuff. Reload." "I'm in the middle of something. Sorry."
CHARLES: Yeah. I definitely do the same thing. Sometimes, I let iOS be bugging me to upgrade for a month until I finally start to feel guilty about security and actually do the upgrade.
CHARLES: Although once they started doing it at night, it actually made it a lot better.
LUKE: That's an interesting idea, too. I think there's a natural tension between the lower integration risk that we have as the engineering teams of shipping very frequently. Aaron mentioned shipping a dozen times a day. We certainly have been there and done that as well. I would say on average, we ship a few times a day. But the reason that we do that is because we know the faster we get code into production, the faster we can trust it. So it passes all your tests, it passes your [inaudible], but you don't really know if you're being honest. You don't really know until there's thousands of people using it in production. And yet, this conversation makes me think about there is a tension between how frequently you do that versus your users' kind of comfort level and expectations.
CHARLES: And maybe there is a thing where you can kind of analyze on a per user basis how often they're active in the application and try to push updates on times that are customized to them.
LUKE: Like when a user has been idle for 30 minutes or something like that.
CHARLES: Yep. Or even like track trends over months and see when they're most likely to be idle and schedule it for them.
LUKE: Good point.
CHARLES: Something like that.
TARAS: I have an idea. We should introduce screen savers into web apps. And so when the user stops using the app, just turn on screen saver and do the upgrade.
LUKE: I can see the VC patch. It's after dark but for the web.
CHARLES: Enter install flying toaster.
AARON: It does that to open up the idea as well of that automated checking that things are okay well after the fact because it's all right to sit there maybe activate something and sit there even for an hour and make sure there's no bug request coming in. But if no one's actually received your app, then of course it's not going to come in. And it's very easy to kind of move onto the next thing and forget about that. I guess it's not something that I've ever put a lot of time in and I haven't worked anywhere that's had really great automated checking to see is everything still okay. And I guess it's an interesting thing to start thinking about as well an important thing.
CHARLES: Like actually bundling in diagnostics in with your application to get really fine grained information about kind of status and availability inside the actual app.
AARON: I'm not exactly sure, really. I guess I maybe wasn't thinking about inside the app but I don't know what it looks like exactly. But there is that element of shipping fast and getting stuff out there. But are we really making sure it all works later on when everyone's actually using it.
CHARLES: Do you only use just [inaudible] or do you assign like a build number or using SemVer? What's a good strategy?
LUKE: In our case, we use git tags. And so, our CI deployment process for our Ember apps basically looks like this is we work on a PR, we'll merge it to master. If it builds, the master gets deployed into our QA environment automatically using ember-cli-deploy from our CI server. And then once we're happy with how things are on QA, we do git tag or actually I use an ember addon called ember release that does that tagging for me and I'll tag it either in patch minor or major, roughly [inaudible] although it doesn't matter that much in the case of apps. When there is a new tag that builds green on CI, that gets deployed automatically into production by ember-cli-deploy. And so, that's kind of a basic flow. That tagging, just to be clear, the SemVer tag is just going to be number.number.number. You can get more sophisticated than that and I think both Aaron and Mattia have a system where even in the PR stage, there's automatic deployments happening. So maybe one of you want to mention that.
AARON: We're slightly different. Every time we push the pull request, that gets deployed to production. We're able to preview up pull requests in production before we even merge into master which we find super useful to send out links to stakeholders and maybe people that have raised bugs just to get them to verify things are fixed. And then at the point that it's all Google merged, the pull request to master which will automatically do another deploy which is the thing we'll ultimately activate, we activate it manually after the fact. We just do a little bit of sanity checking but we could automatically activate that on merge to master as well. But yeah, the being able to preview a pull request in production is super powerful for us.
CHARLES: That is definitely a nice capability. It's hard. It's one of those certain workflows or patterns or tools that you remember life before them and then after them and it's very hard to go back to life before. I would definitely say kind of the whole concept of preview applications is one of those.
AARON: Absolutely. It's a daunting concept if you're not there, previewing something that's essentially a work in progress and production. And there are some things you want to be careful with, obviously. But for the most part, it's a super valuable thing. As you say, it's a world where once you're there, it's very hard to step back and not be there again.
CHARLES: So I had a question about, we talked about I think it was 162 plugins around the ember-cli-deploy community. What for you all has been the most surprising and delightful plugin to arrive that you never imagined?
MATTIA: That is a good one. I'm pulling up the list. What I can tell you, for me, it's not about a specific plugin. The surprising part was the sheer amount of different strategies that people use for the shipping part. At least, I found that the build part is similar for most people, like most people want to do the things that you're supposed to do. So, you want to build your application and then you want a minify it in some way. And there's a bunch of options there from gzip to more recent technologies. But the way people deliver it to servers and the difference in the solutions, that I think for me has been the biggest thing, where people that ship [inaudible] are people that ship directly to Fastly, people that use FTP files, people that use old FTP, people that use our sync, people that do it over SSH. We have people that ship stuff directly to a database because some databases actually have great support for large files. So we even use it as a storage. We have people that do it in MySequel, people that do it in [inaudible].
CHARLES: It's actually storing the build artifacts inside of a database?
MATTIA: Yes, I've seen them in that. It's kind of interesting like the solutions that people ended up using. And so for me, I think that that's been the most fascinating part. Because as we were saying at the beginning, I'm just seeing now, we even have one for ZooKeeper. I don't have an idea what this does but it's probably related to some sort of registration around the seven-day index. That, to me, I think has been the biggest surprise. Everybody ends up working in a different environment. And so, that flexibility that users need has been by far the most surprising one.
AARON: I think that's also been one of the challenging things, one of the enlightening things for me. I think in the Ember ecosystem, addons and even just Ember itself, it's all about convention of configuration and doing a lot of the stuff that you do for you. I think people expect them to see a lot of point to do the same thing. But the key thing here is it just really automates all the things you would do manually and you need to understand exactly what you want your deployment strategy to be before use them to see a lot of [inaudible] could do for you. You need to decide do I want to install my assets on a CDN and do I want to install my index in Redis or in console or in S3 bucket. You need to know all these things and have decided on all these things and then ember-cli-deploy will make that really easy for you. And this is one of the educational things, I think we still haven't even nailed because there are always people that want to know why this doesn't work. But deployments are complex thing and as what you were saying Mattia, there are so many different variables and variations on doing this that there's no sensible configuration ember-cli-deploy could really provide out of the box, I guess. And so, that's why we ended up with a pipeline that gives you the tools to be flexible enough to support your strategy.
LUKE: I think the closest that we come to the convention is that if any app is using ember-cli-deploy, you can run ember deployment targets or ember deploy prod and ember deploy QA and you can expect that that's going to work. What you don't know is how has it happened to be configured in this project.
Charles, your question about kind of the most surprising thing that's come out of the ecosystem. For me, I would say -- Mattia mentioned plugin packs earlier which are groups of plugins that kind work together well. And so, we've seen some plugin packs like you might expect, like an AWS pack for deploying to AWS. But the more interesting ones to me that we've seen a lot of, companies open source their plugin packs. So what you naturally fall into as a company that's adopting ember-cli-deploy that has multiple ember apps is that you are going to develop your own plugin pack for internal use because generally speaking, companies follow the same deployment pattern for each of their apps. There's usually not any reason to vary that. So then the new thing that happen on top of that is people said, "Why don't I make this open source so other people can kind of see how we do it?" And that's been a really delightful part of the process to kind of get a peek into how other organizations are orchestrating their deployments. And if people are curious about kind of looking at that themselves, you can go on NPM and look for keyword ember-cli-deploy-plugin-pack and pull up all of those. And you can kind of poke around and see what different companies have open source there.
CHARLES: I actually love all three of those answers because it really is for me when you have a constellation of people around a particular problem, it's the surprising solutions that emerge that are some of the most exciting that would have lain hidden otherwise. It would have been kind of buried beneath the source of company A or company B or company C but actually having it all out in the open so that you can inspect it and say, "Wow, where has this solution been all my life?" Something that you have never imagined yourself.
LUKE: That's a great question. Aaron or Mattia, one of you guys wanna talk a little bit about the history here?
MATTIA: Yeah, sure. We've been thinking about this as well. In the past, a guy on the ember-cli-deploy team, Pepin, has actually started this effort and it kind of prototyped this very idea of separating the ember-cli-deploy part from Ember CLI itself and make it a bit more generic. And he started a project called Deploy JS which I can give you a link for the show notes later. I don't think that the project is currently maintained but definitely the start of the effort is there. And the funny thing is that it was surprisingly easy. I think that we didn't get there mostly because we just all use Ember at work. As you know, open source is mostly motivated by the needs that an individual or a group of people have. But if any of the listeners were very interested in this, I think they should definitely get in touch and we will be happy to talk to them and see what can be done here.
CHARLES: I think the wider community could definitely benefit from that because most of the blog posts and talks I've seen that concern themselves with deployment of single page applications, it's still much more of the tutorial phase. Like, "This is how I achieve getting this deployment strategy." Not, "This is how I repeatedly encode it as a program," and leverage it that way. And so, definitely getting that message out to a wider audience, I think it's a -- what's the word? It's an underserved market.
LUKE: Yeah. I really like this idea also. I think about this ImmutableWebApps.org, if you look at it. It's sort of a manifesto with conceptual description of what are the qualities that your app has to have to qualify as an immutable web app which I think is kind of a funny idea but one that people can start to get their heads around and compare that description to their own apps and say how do I hit this or fall short. And it reminds me a lot of kind of the idea of Twelve-Factor App which is an idea that I think came out of Heroku originally. And it's an idea of a backend app that is portable to be able to easily move across different hosts and easily be scalable to different instances of [inaudible] if your app obeys all of these things then it's going to do well under those circumstances, that will satisfy those needs. So, I think it's a great way of thinking and probably maybe even a better entree into the conversation with the wider community than a library, this is certainly a library called ember-cli-deploy.
MATTIA: Thank you so much. It was a great time.
AARON: It was a pleasure. Thanks for having us.
LUKE: Thanks so much.
CHARLES: Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at firstname.lastname@example.org. Thanks and see you next time.
May 02 2019
Rank #8: Pull Requests with Joe LeBlanc
Joe joins the panelists to talk about pull request etiquette.
Joe Leblanc: Joe first learned to code on a Zenith computer his dad brought home from work. It had this built in blue LCD monitor and ran on 5 1/4" floppy disks. He used spreadsheets for work and Joe was interested. They spent about an hour going over macros together and he took off from there. Long after the Zenith died, the open-source content management system Joomla! landed in the center of his attention. Joe found himself writing a book about Joomla programming, authoring video tutorials about Joomla for lynda.com, giving Joomla talks, and helping organize Joomla conferences.
Since his time in the Joomla community, he's picked up Node, Rails, React, and other frameworks. He's currently coding at True Link Financial and working on a few hobby-projects as well.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, the place where we talk about user interfaces and everything that you need to know to build them right. My name is Charles Lowell, a developer here at The Frontside. And with me also is Taras. Hello, Taras.
TARAS: Hello, hello.
CHARLES: Today, we're going to be continuing our conversation about platforms, as always, but in particular the pillar of your platform that has to do with how you collaborate on code. It's an important one. And so, we're spending some time on it. And with us to talk about this today is Joe LeBlanc who is a senior software engineer at True Link Financial in our very own beloved Austin, Texas. Hey, Joe.
CHARLES: Thanks for coming on the show. We're going to be talking about collaboration and I was thinking we could kick off the discussion talking about pull requests because that's typically one of the ways that we collaborate on code. That's really where the rubber tends to hit the road. You have particular interest in the dynamics of a pull request. What experience kind of led you to that interest?
JOE: My background has been doing a lot of work as a freelancer. And when you work as a freelancer or do agency work, a lot of times you are really the only software developer that is around or you're working with maybe one or two other people. And I didn't get a lot of opportunity for pull request reviews. Mine was in that space. And then when I moved to a full time job at a place where I was one among maybe half a dozen or a dozen engineers, that's when I really began to get interested in how I could be better at giving pull request reviews and also submitting pull requests that people want to review.
CHARLES: What made you notice the need for this?
JOE: What would happen is someone would submit a pull request and there would suddenly be just dozens and dozens of comments coming in that were just kind of difficult to keep track of and often were maybe talking about things that didn't necessarily need to be reviewed as a part of that pull request or addressed, maybe things that could be caught by a linter.
JOE: And other tools that are a little bit easier to receive feedback from. Like it's easier to have a tool tell you your spacing is off than have me tell that to you.
CHARLES: Right. And really that seems like the spacing is off, that's kind of like if you need to deliver that feedback, that's kind of like not what you want to lead with. If you don't have linting in place like after all other issues are sorted out.
CHARLES: But it sounds like what you're describing is people who have kind of swarmed over a pull request each with their own kind of pet peeve issue.
JOE: Yeah. And then you're just left with this long list of comments to go back and address and you're pushing up more and more commits. And by the end of it, you could have more than 100 comments on this PR. And you thought that you were going to get this done in a day or two, and then suddenly it's the end of the sprint and it's like, "Oh fine, then I get to merge this."
CHARLES: And typically, it's actually, in my opinion, an anti-pattern when you have like 10 mergers that happen on the second last day of the sprint or the last day of the sprint. There's always issues with that, right? Ideally, you are merging code throughout the course of the sprint. It kind of like defeats the purpose almost. I guess you're doing your integration in shorter periods but even so, tons of stuff is bound to break when everybody's pushing and everyone's rushing.
TARAS: So, what would happen in that situation, in your experience, when you have this pull request that a lot of people are commenting on and some of the comments could be addressed by linters. Would you guys go back and actually implement linting? Did that happen? Would you put linting in place so that you'd have consistent formatting on the projects to reduce that kind of feedback? What would be the resolution or a way to improve on a process so you could actually get better feedback?
JOE: Yes, we did install a linter and that's something that you can either run locally or you can also run in your continuous integration environment. And it's really good to run it locally first because then you can just catch it before you even submit the PR. And that was something that definitely helped cut down on these sorts of comments and even debates over style. You just have this one thing that is maintaining that style or rather telling you when you're wrong for you, and then you don't have to have all these comments coming in as you submit your PR.
And another thing that we would do is we would use, even beyond just things like whitespace and trailing newlines and those sorts of issues, sometimes you would have some of these issues that would come in that wouldn't necessarily be a trailing newline or whitespace issue or something like that but it would be purely someone's sense of style. And in those situations, we came up with a bit of a standard where if you wanted to make a comment that was strictly style that wasn't something that you necessarily wanted to block the pull request over, we would use emojis that had specific [inaudible] thing. So in our case, we would use either a beer emoji or the cocktail emoji to kind of say, "Here, take this with a drink."
JOE: This is not something that's super serious. It's a suggestion, "Here, let's discuss this over beers."
TARAS: It's a really nice approach to friendlify the actual pull request because people can get really -- I think another way people would say this is like when you say that it's not 'I believe it whole strongly'. How does that go, Charles?
CHARLES: It's strong opinions, weakly held.
CHARLES: Right. You're kind of making an assertion about the way things ought to be or often missing from that is how important it is to you. You've made this thing like it should be like this. That's a very black and white statement, very firmly cut between right and wrong. But how important it is to you if it goes the other way is often missing from the conversation.
TARAS: So Joe, what would happen once you made this change? Did you see a shift in the kind of feedback you were getting? What did it look like after this?
JOE: After we started implementing the ideas of putting on emojis to signify things that were not super serious, it became a lot easier to just picture all those comments and define the things that really needed to address. And it was a lot faster. I was just able to address these very specific problems and do that first. And then if I had time later, come back and address those style issues.
CHARLES: Right. Was the kind of the good feedback there the whole time but it was just obscured by the noise of these kind of exterior issues or side issues? Or did you find that because people's thoughts were more given over to the heart of the matter, that you actually got more comments directly relating to kind of the meat of the implementation?
JOE: I think it was really more that the good comments really were buried in there. A lot of times when you see critical comments that seem to be petty, that can really trigger your emotions. And so, I feel like a lot of the times the emotional state that we would get into would prevent us from seeing the good comments that people were leaving, and we would get a little too angry about things that really weren't that big of a deal.
CHARLES: Would the tension kind of noticeably rise?
JOE: Yeah. I actually remember several instances at my job where -- this is when I was working in office and in the same room as all my co-workers. And one of my co-workers would know that I was reading his review by the number of sighs that were coming out of me.
JOE: Yes, I definitely had this reaction that people could tell. Implementing things like these emojis definitely helped. They didn't always fix everything, though. One thing that would happen too is even after filtering out kind of the noise comments and getting into the meat of the matter, we would still wind up in situations where I would want to use one design pattern and another engineer would come along and say, "No, you should do something different," and we would have these arguments.
CHARLES: Right. And those are harder to resolve too because those are strong opinions strongly held.
CHARLES: But it's still a step forward, right? You've eliminated the passionate arguments about the strong opinions weakly held. And so you're able to now grapple with 'how do you resolve these arguments' of these stronger opinions that are more strongly held.
JOE: Yeah. Part of the way that we handled this was we came up with a way of being able to have a debate about something on a pull request, yet also keep in mind that we're working under deadlines and that ultimately, it might not be that big of a deal.
TARAS: I don't know if you experienced this but there's this kind of a feeling where you know you have a deadline that you want to reach and this feedback is kind of not really helpful to that end goal. But at the same time, there feels like a trade off for you, like trading off quality by accepting something that people don't agree being fully ready.
TARAS: But then there is, I guess the tests seem to be like you have some tests and the tests are passing. So, thumbs up. [Laughs]
CHARLES: Yeah. Well, here's the thing. This thought just occurred to me when I heard that is when we are reviewing code, probably the most important code to review is actually not the implementation but it's the tests. Because why do people get so care mad about the code being right? It's because they know how expensive it is to get it wrong. And we all have our different opinions of what's right and wrong and what's going to cost us more. But at the end of the day, we're all trying to save us, save ourselves and our team, pain in the future. The tool that we have to do that is the code review. We're trying to make sure the code is "good". But usually what ends up happening, and I know I'm certainly guilty of this, is I'm focusing on the implementation and I look in and say, "Oh yes, there are tests." I don't really look at the test and say, "Is this a good test?" Because a good test is going to lower that cost that we're so afraid of in the future, and that drives us to want to make sure the code is as close to what we conceive of as perfect as it's likely to get and still hit our deadline. It sounds to me like maybe what we really ought to be doing is reviewing the quality of the test because if you have an excellent test, then the shape of the code almost is unimportant or changing the shape of the code, more importantly, is very cheap. So if you do find that the implementation is suboptimal, the cost of rejiggering it into a better configuration is going to be very low.
JOE: I've discovered so many times where you are running a test that was written previously either by somebody else or by yourself, and you realize that the test is testing the wrong thing entirely.
CHARLES: Yeah, coverage is spotty. It covers 10% of your cases.
JOE: It can also might have a stub or a mock in there somewhere that is hiding something that you weren't counting on. Or it could just be you pull up this screen and test then it saves but you're not really testing what it's saving.
CHARLES: Right. Can I actually proffer a suggestion? At least I'm going to try and hold myself to going forward, is that when I review a pull request or some proposed change to a code base, I'm going to review the test first.
JOE: Ooh, that's a great idea.
CHARLES: I'm going to try and start with the test and avert my eyes from the implementation, no matter how curious I am how this person accomplished the solution. I'm going to hide from the solution and focus on the verification. And if I have faith, first and foremost, in the verification, then my faith in the implementation is secondary.
TARAS: You know, Charles, I really like this. I think it'd be really interesting to try this out and see what kind of impact it creates. It makes me think that there is actually something really useful in here in terms of providing feedback because the challenge is that when you're giving feedback to someone on a pull request, ideally that feedback is going to be useful and it's going to give the person something to think about in regards to the work that they did. And I think a good way of pushing to work back onto the person in a way that allows them space to internalize what they need to do is identifying cases that might be missing because a lot of times, we test happy paths. We don't test the things that we didn't think about. And that's where the devil is in details. It's in the things that we don't test. Those are the kind of problems that we're trying to prevent with having good code. But really the best way to kind of flush those things out is to make sure we have the right test coverage for it. So yeah, I think if you add to that just when you're looking at a pull request is to go, is a test coverage missing the following cases and actually surfacing not. I'm actually thinking like a danger task. A danger is a tool for adding information to pull requests so that it's kind of like an automated mechanism to comment on pull requests. And so I'm thinking like having something that does what [JAS] does. [JAS] has this thing where they will check based on the last git commit. It will figure out what are the tests that have been added since the last commit and then it will actually show you. So when you run tests, it only runs the tests that you kind of impacted which is something that could be used to surface tests that were written in this commit. I mean, we also have that information in the actual commit itself but being able to see 'these are the tests that were written or added' and then you could use that and figure out what else is missing from this. This could be like a way to kind of add onto this process, something a little bit more automated so you could actually highlight this information very easily in the commit itself.
CHARLES: It's funny, my mind was wandering off towards GitHub. When do you use danger and when do you use GitHub actions? GitHub actions have been kind of like brewing and fermenting in my mind.
TARAS: One nice thing is that I mean, danger is a little awkward in that it creates one single commit at a topic. It creates a comment first time you commit and then it keeps pushing information into a comment which shows up at the top of your comment thread.
TARAS: But that's not how you read comments. You read like top to bottom. You don't read top to bottom to top. And so, I think the nice thing about the actions is that because it's using checks like GitHub checks that actually is part of a different area, it's part of the validation area as opposed to part of the actual comment conversation. This seems like a more appropriate place to put their information rather than the first comment.
CHARLES: Yeah. So, do we decide on kind of what the ultimate resolution is for when you have these high order conflicts?
JOE: Yeah. So that's one thing that we came up with that I'm really proud of. And so what we do and at least at that job that I was at, what we did in those situations was we said, "OK, if you've gone back and forth on this two or three times and there's still not an agreement as to what should be done or there is no compromise, what you should do is let the author of the pull request go ahead and merge that code," because you want to merge that code, get it out to production, make sure it's serving our users and our clients. And then what you want to do is take that conflict and record it somewhere to specify this interpersonal conflict not a code conflict or a merge conflict or anything like that. So you take this interpersonal conflict, the topic that was being discussed and you put that -- we were just putting it in a Google doc and leaving it there. And then every couple of weeks or maybe every couple of sprints, we would go through that Google doc and just talk about topics that had come up. And then really more often than not, what we would find is that we didn't care about the topic anymore.
CHARLES: [Laughs] It's amazing how time has a way of cooling passion over things that really don't matter.
JOE: Yeah. And for the things that did matter, we usually have like a really good discussion. Sometimes, we even came up with something different entirely based on just having more people in the conversation and thinking about this problem.
TARAS: I like this because there's a bit of process around it. It's kind of like a retrospective on pull request passions.
TARAS: It sounds like a healthy thing to do for a team, especially. And I think just allocating some breathing room to go through these kind of things could be really important cumulatively over time, especially.
CHARLES: Yeah, definitely. It sounds almost like the pull request is then ongoing. You have this collaboration that happens kind of at the front of the change but then is rippling outwards and onwards and hopefully then has an impact on future changes, like if you're disagreeing. So, would you qualify that the types of issues that end up living in this Google document as architectural issues or just, 'hey this is the way we need to talk to each other and this was off and we need to fix this' or is it both?
JOE: It was mainly more architectural decisions that was coming up in this, sometimes like code style issues as well. Not so much the interpersonal issues, like the interpersonal issues would come during retros.
CHARLES: OK, because it sounds to me like it's not. Then you have the added benefit that your architecture does get to improve because clearly if there's some disagreement about this, then there's some sort of tension there. There's someone perceiving that some problem is not being resolved by a particular implementation. And so it's good to just at least surface this issue again and again. What was your experience with kind of revisiting the architectural issues? Was it mostly 'well, this wasn't really an issue' or is it 'wow, I'm really glad we took note of this because now we have these three ways of thinking about things' and it turns out that given three or four months more experience, this is something that we should be doing.
JOE: Yeah, it is definitely a mix of both but I'm kind of leaning more towards the latter. Like we're just glad that we bring things up. Occasionally, there will be one or two topics that will come up that we still would resolve and we would have to agree to disagree on something. Or in some cases, I think we would allow one of the lead engineers to just make the final decision on something. But that was pretty rare.
CHARLES: So, apart from appealing to either time, the passage of time or just kind of taking a brain dump of all the different architectural options or deferring to a more senior engineer and just kind of asking them to step in and make the call, are there any processes that you can put in place say to kind of mechanically come up with a decision? Like any set of values that you can use as a ruler to kind of line up a set of things to kind of attach weight to one particular solution? For example, one of the things that I always think of is when I have internal conflict about a decision, there's kind of a part of me that feels like this might be the right way and maybe another way is the right way. And so, a tool that I will use is what's internally consistent with the rest of the system. So, even if I've had an insight that something really ought to be framed,one solution should be framed in a certain way. If there's another solution that's more internally consistent with the way things are existing, then I'll use that as a discriminator to say, "OK, that's one thing that I can use to measure a solution against, that I'm not emotionally tied to." It feels more objective. And if you have those tools, you can kind of pile them up and see which pile ends up being higher for each solution. Do you see what I mean?
JOE: I definitely lean more towards keeping things consistent with what's already there. Personally, I probably do that to a fault. Sometimes I need to branch out a little more and get comfortable with possibly breaking something. But you always need to weigh whether it's something that is acceptable to break. Like a lot of the systems I've worked with involve money and it's really important that people either have money when they need it or are charged the correct amount when you charge them with things.
CHARLES: They get really mad when you charge them too much. [Laughs]
JOE: Isn't it amazing? [Laughs]
JOE: It could be that you are OK with breaking this other end of it where you might charge them the correct amount but the fulfillment of that product or the service or whatever you're selling, you might have a little more wiggle room in that part of the code base. Where if you break something, somebody calls in and says it's broken, and then you're just able to fix it.
CHARLES: Is there anything else? If folks are struggling with the way their pull requests work or their code reviews work and they're experiencing friction and tension with their teammates, is there anything else they can do?
JOE: What I would suggest is definitely look at the pull request template feature that is in GitHub and make use of that. Because what you can do with that is come up with several sections of the pull request template and say, "These are the questions that we want to ask before we submit a PR." And if you have those questions and those sections right when you go on that template and people read through that as they're making their pull request, they can often catch problems before they get to another reviewer. I can't tell you how many times I have submitted a pull request, started to write the description and [inaudible] these questions and realized, "Oh, this is wrong," or it's broken or it's totally the wrong thing.
CHARLES: Right. It's funny and I feel like you want to be asking those questions not when you're submitting the pull request but before you're even writing the code.
CHARLES: But a lot of times, we don't do that until afterwards and you're like, "Oh man!" Just this process of forcing myself to think about the problem in this way or think about it holistically totally recasts my implementation.
JOE: Yeah, things like, "How can this break after we merge it?"
CHARLES: Yeah, that's actually a great question, that of one you're talking on pull request.
JOE: Oh yes, definitely.
CHARLES: Like imagining the [inaudible] scenarios.
CHARLES: Man, it's almost like you want to read the -- what are the other questions that you have?
JOE: So the ones that we have are, first of all, what is this pull request? How does it fulfill the requirements for the ticket? And then how can this break after we merge it? Are there any post-merge tasks that need to be run? If you need to get on a server and run a task or do something after it has gone to production, that's a place to document that there. And then the final question is, how is this tested?
CHARLES: Right. That's a good one. And like I said, I think that's the one where I'm going to be starting when I'm both thinking about how my changes will be reviewed and how I review changes.
JOE: Maybe I should consider moving that to the top position.
CHARLES: [Laughs] I mean, it is like. I'm just thinking about it and it does seem like we go straight to the implementation because that's what's fascinating to us. And so we might have way too much bias for the importance of the implementation over the importance of the test because I have to say I am so guilty of when I'm reviewing. Just looking for the fact that it has a test and not looking for what the test does.
CHARLES: And only referring back to the test and trying to understand how the test accomplishes its task. If I don't understand the implementation, I'm like, "Oh, let me look at the test and see how this code is used to the test." That might be problematic but I know that's definitely a little personal goal that's coming out of this podcast for me.
CHARLES: All right. Joe, do you have anything else that's coming up? Any talks? Any meet-ups that you're going to? Any announcements? Anything that you want to plug?
JOE: I have a website at JLLeBlanc.com and that's where I am.
CHARLES: All right. Well, fantastic. Thank you so much for coming on.
JOE: All right. Thank you.
CHARLES: Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at Contact@Frontside.io. Thanks and see you next time.
Apr 11 2019
Rank #9: Frontend/Backend Team Collaboration with Sam Joseph
Sam joins the panelists to talk about frontend and backend team collaboration.
Sam Joseph is a CoFounder of AgileVentures, a charity that helps groups of volunteers gather online to develop open source solutions for other charities all around the world. Sam’s been mucking about with computers since the early 80s and followed the traditional education system through to a PhD in Neural Nets. Next he went all industry, researching mobile agents at Toshiba in Japan, going freelance and then swung back to academia to research peer to peer system and collaborative systems. He now spends the majority of his time trying to make AgileVentures a sustainable charity enterprise, with occasional moonlighting as a contract programmer. Check out his blog at nonprofits.agileventures.org.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Welcome to The Frontside Podcast, the place where we talk about user interfaces and everything that you need to know to build it right. My name is Charles Lowell, a developer here at the Frontside. With today also is TARAS: Mankovski.
TARAS:: Hello, hello.
CHARLES: Hey, TARAS:. Today we're going to be continuing our theme when we think about UI platforms and web platforms, continuing the theme of collaboration and with us to talk about this is Sam Joseph. Welcome, Sam.
SAM: Hi, thanks for having me.
CHARLES: We've already talked a great deal about how the way in which your team collaborates and the communication that happens between your team and between the different pieces of software, your system, form one of the pillars of the platform that you can't just take lightly. You need to actually be intentful about that. I was thinking we could kind of start today's discussion, kind of talking about some of those collaborations.
One that we've probably all encountered, which is usually teams will be split into people who are focused on frontend, people who are focused on backend systems, kind of the services that make sure that all of the nodes that are running on our laptops and our desktops and stuff are running smoothly and error-free and obviously, those two groups of people can sometimes arrive with different sets of priorities and how do we resolve those priorities to make sure that that communication flows freely.
TARAS:: What's interesting about these frontend and the backend teams is that our users are not seeing that separation. They only see one thing. They only touch one thing. They actually see as one group but there's tends of be this kind of split between the frontend and the backend. It's kind of interesting that how the user get into this.
SAM: Yeah. Obviously in some teams, there's a very clear cut distinction between people at the backend and working with the components that are serving JSON over the API and there are some people who are very, very focused on the frontend and drilling CSS and a number of bits and pieces or even just staying explicitly on the design or UX design and there's a mythical full stack developer who is up and down the platform. It doesn't run exactly in parallel but there is this key thing which is almost how much sympathy or empathy can you have for another person who is not you, trying to use something that you set up.
If there was a direct parallel, you'd say, "Obviously, all people who will be working on the frontend are more of that sort of person and perhaps, the people on the backend are not so much that sort of person," but actually, I think you can have people who are doing backend stuff and they're designing API is very, very thoughtfully or the kind of people that consumes those APIs and sometimes, you can have people who are very, very focused on the design and the aesthetics when not necessarily so plugged into how will someone else use this, how will it fits into their lifestyle, which might be very different from my own, so that's maybe another axis, if you know what I mean apart from this sort of pure technical [inaudible]. Does that makes any sense?
TARAS:: Yeah. What's interesting is that everyone is trying to do a great job. Everyone is setting out to do something really good. What people's way of expressing good might be different, so if someone could be really focused on the quality of their code like they want to do their version of doing a really, really good job is doing the best code they could write. Sometimes that doesn't necessarily equate to the best user experience. I think everyone that I've met -- engineers who are writing code, almost everyone that I know is trying to do a really good job. If everyone is doing a good job, it doesn't necessarily always equate to the best user experience.
CHARLES: I think we had a reference that everyone wants to make sure that their system is of the highest quality possible but quality in of itself is not an absolute value. It's relative. In other words, a good definition of quality is how well a system is fit to a purpose. If it fits very well to that purpose, then we say it's of high quality but if it fits very poorly to a particular purpose, then we say, "This is a system of low quality," but what constitutes something of high quality is relative to the purpose. The question is, what is the purpose of writing the frontend system? What is the purpose of writing the backend system? So it seems to me you're going to have a lot of dissonance if the purpose is divergent but if they both share the same purpose, then that is kind of standard quality on both sides. Does that make sense?
SAM: That makes sense and what even more makes it tricky is that actually, purposes can evolve over time and so the thing with the frontend that needed to do with the business today is different tomorrow and the day after. The trick then is sort of the frontend and the backend, as people try to do a great their job, there's this question of how far ahead are we looking so you can talk about important things like sort of asking close modification about [inaudible] extension and there's a [inaudible] of different coding heuristics as best practice that say, you should kind of go in this direction.
Sometimes, that will be the hill they want to die on. It's like, "This code needs to be this way because of this thing," and the idea is that it's sort of future-proofing them but I think the messy reality is that sometimes, the thing that you put in place to future-proof, the whole system gets canned. In two weeks, the business changes and what have you, so the extra effort that you are pushing in on one day to protect yourself against changes in the future actually gets lost and perhaps, if only you'd be able to deliver a shortcut pack, this one feature that that will got the next line of funding in, either one advocates cutting corners but... you know what I mean? Like --?
CHARLES: Yeah, absolutely. I just wanted to chime in and vehemently agree with you that the purpose can change radically, especially if you're in an evolved environment. What constitutes the good code or the good quality solution can vary just as radically because it needs to fit that purpose.
TARAS:: When we talk about frontend and the backend, it seems there's this relationship, which is kind of positional like there's the frontend and then there's the backend. One is in sequence from front to back. It's the direction with the frontend. It's closer maybe to the user where the backend is not. But I think in practice, it's probably more like the left and the right hand where when you have to do two things together, you actually need to do two things to coordinate together.
What you describe about and this is I think where taking shortcuts sometimes can actually be a good thing is that if you say, "I'm going to spend the next few weeks on a backend and doing this specific thing," and then you find out that 10 days into the iteration that it doesn't fit, the better approach to synchronize would be to stop the action and realign. But if you persevere, then you might overstep and you actually be out of sync. It makes me think that the art of creating cohesive organizations from development perspective is to create context where the two kind of work in synergy together. I think that's where a good tooling that allows its synergy to exist. I think that's a lot of the work of actually creating systems where the user experience is kind of cohesive and integrated.
CHARLES: Actually, there was something that you just mentioned in there but it's actually a little nugget that I'm curious to explore and that is if you're 10 days in to like a 14-day piece of work and you realize that it isn't right and it doesn't fit with the whole, right action is to throw it away. I feel like software organizations and this might be a little bit off topic but it's something that really is interesting to me, so please indulge me. I feel like we see the product being the kind of the code output, even in Agile environments and there is an aversion to throwing away code that has been written.
There's the, I would say, incentive is to go ahead and persevere because developer time is so expensive. These are days out of people lives, so they've already invested 10 days. Why not just have four more days just so you have it. When in fact, you actually have more if you just throw that work in the trash because it's an obstruction that's not needed. It's a piece of weight. It's actually something that you now are going to own and it's actually going to be cheaper in the long run and it can be more beneficial to your organization to not own it.
Do you all see that happen kind of play out where people become attached to software that they've invested and will make the decision to hold on to it? Say, we'll spend two more days to complete it, even though it's the wrong thing, like identifying which things need to be thrown away? I feel like we don't actually do that very aggressively -- to say, "You know what? We need to not complete this work."
SAM: I think that is a really tricky one because I think whatever people might say, when you spend time working on something, you become emotionally attached to it. I would say strongly that how logical or rational or whatever sort of a person you are, my experience is being that people working on things want to see them used.
I think in a situation with version control where you can keep things on a branch, they can be useful explorations, things don't have to be thrown away in their entirety. Our charity is doing work for the National Health Service in the UK where there's a lot of employees in Europe and I've noticed the user interface that we're supplying them and I was suggesting some sort of minor tweaks and one of the developers has sort of run with the entire, big, advanced search feature that partially solves the problem but brings in a lot of other bits and pieces. He does some good work there. It's a great work but I think he kind of ran further than I was expecting down that line and I think we have now found a much simpler solution that rather than bringing an entire cabinet, it's a little shading off the side of the existing one.
But I think that doesn't have to be a loss and I was reassuring him that the work was valuable and that there is interesting learnings there and potentially, we might use it in the future version of the project and now of course, the way that stuff is moving on, just how it's going to branch, it doesn't mean you can then sort of magically lose some of the work.
In that case of doing this 10 days out of 14 and so on, the real question is can you get any value from switching somebody that fast? If they spent 10 days in and they realized they don't need that thing, it's like can you switch them quickly onto something else where they'll do four days or might they as well, just finish up there and leave that on a branch. That's a pull request that gets closed and it's there to go back to. That's kind of depends team by team about how quickly you can repurpose people missed rigs, if you know what I mean.
CHARLES: I absolutely agree but the key thing is leaving it on a branch and not integrating it into production, like not actually deploying it because I feel like when we see a feature, it's like we've got to get this thing done and it's done and we're just going to get it in versus now that we've learned how to do this, let's put that on a branch and let's rewrite it and let's take a different approach, rather than just being married to the idea that we're going to get it right the first time or that now is the time for this feature because we understand the complexity of what it actually takes. It is a tricky question. I'm wondering if our processes don't include enough implicit experimentation. We talked a little bit about this on a prior podcast that if they don't include some incentive to not deploy features just because you have them.
TARAS:: I think from a business perspective, there's not a lot of model to evaluate a certain thing. We don't have really any effective way of evaluating learning. You can measure code by the numbers of lines of code that somebody wrote and how much of code was shipped but you can't really evaluate how much was learned and how much was persisted.
I think a lot of this work around supporting effective collaboration is in building a cumulative systems of knowledge like why is a good Git history useful is because it has a built in mechanism for understanding history. It gives you a way to return back to time in your project and understand the context of that specific change and I think this is something that really good teams do this really well. They will respect this because when it's necessary, it is valuable to have this. When you don't have it and you are a year into the project and something happened and then, you are using the only thing you have, which is your troubleshooting skills or you are trying to figure something, as supposed to going back and relying on that history, on that knowledge that's built into the system, what I'm trying to get to is there is an element that is inherent to our development process, which is we don't have a way to quantify it. We have no way to really evaluate it. I think this is the problem that makes it difficult to throw away work because you can measure the amount of time they'll spend but you can't measure the amount of learning that was acquired.
CHARLES: Right. Thatís true.
SAM: I think if you have a positive team environment, if you have your team that is stable in there -- your contacts are coming in, the money is there, everybody is there and you've got the team, you don't necessarily be able to measure the learning because the output of the team will be good. They're kind of doing that in the background but I think individual comments are not going to want to pay for learning experience. It's certainly not at the rate of software developer's cost.
Although, the throwing-aways, if you're familiar with the [inaudible] book, which I think is a [inaudible] is the author, you know, build one, to throw away, you will anyway. We have a frontend mob that we run weekly doing frontend stuff and CSS and so on and we've done like it's a mockup for the client and there's this question about in my [inaudible] and so Iím saying to other developers there, "Let's not get too attached to this. We may need to throw it away and it will be a great learning to sort of restart on that." The [inaudible] to look quite nicely and the client might get attached to it. They want to ship it and I'm like, "Well, actually there's a lot of other stuff that needs to happen," and so, it's a minefield. It really, really is.
TARAS:: I think some of the business relationships that we have to this kind of client consulting company relationship, that relationship might not always create the fit to purpose team for specific challenge. You can have a company that has a lot of employees but their team and their team dynamics might not be fit to purpose to the problem they're trying to solve. If you're building a platform over a long time, you want to be creating that space where that learning gets accumulated over time. It doesn't matter what necessarily the relationship is between the companies that are participating in this process. I think what matter is what are you producing as a result.
If you're working together with people from different companies and they're working together and they're building this kind of an environment where you can collaboratively build things together and then people learning from the output and that knowledge is being carried over and people are being able to stack their knowledge continuously over time, if you're creating that environment and you're building a large platform for example, then you are creating a build to purpose kind of technology team to fit what you're looking to accomplish and that'll include consulting companies. I think those team, they're kind of secondary but I think it's just [inaudible] to that. It's like building a quality development organization to fit the purpose of building whatever it is that you're trying to build. If you're building something small, you might have a small team that'll able to build that effectively. If you have something big, you could have a big team that is building that effectively but building that team in a way that is appropriate to what you're trying to accomplish, I think that's the real challenge that company struggles to do.
CHARLES: Yeah. In the context of these real teams, I guess what can you put in place given that you have backend teams, frontend teams and each one of these needs to be specialized. This is kind of the power of the way that people work is that we're allowed to specialize and there's power in specialization. You can have someone who can be super focused on making sure that you have these high throughput backend systems that are resilient and fault tolerant and all these wonderful things, so that they don't necessarily have to have the entire context of the system that they're working on inside their head at a given time and the same thing someone working on CSS or working on a frontend system architecture, which has grown to be a very complex problem domain in its own right.
But these teams can be working in a context with a purpose is whip-lashing around and changing quite drastically and so, how do you then keep that in sync? Because we've identified purpose as being actually something that's quite a dynamic value. How do you keep these teams keyed in and focused and so, that they're kind of locked in on that similar purpose of they're going to be adapting the systems for work that they're responsible for and specialties that they're responsible for to match that?
SAM: It's a good question and I have my own bias view there --
CHARLES: I would love to hear it.
SAM: I can't bear working on things where I don't understand in great detail how that end user has experienced or what is the effect overall that it's trying to be achieved. You know, I've been working in boards between the industry and the charity for like 30 years and I know people are commenting like, "You were the person who wants to understand everything."
I think there were some people who are maybe quite satisfied who get ticket off the general board or what have you and work on that thing and if the API specs have filled in, so that's it. Go home and they weren't losing a sleep over it. But I think if youíre going to be dealing with these changes and sympathetic that the changes is coming down the path, I think you need to have some degree of empathy with the people who are driving the changes. Do you know what I mean?
CHARLES: Oh, absolutely yeah.
SAM: You know, as we've mentioned already, I think people get attached to what they build and I don't think you can do anything about that. They will get attached to what they build.
CHARLES: Yeah, we've all experienced it. It's so true. It's impossible to [inaudible].
SAM: Yeah. We can try and target it but it's sort of part of our nature. I think there are sort of the tools of the design sprint, of the design jam, of these sorts of things where if you can build to some level is obviously that it can't be shipped but can actually tease out the needs of the user, the designs sprint, the Google team, they have an example with kind of like this robot for hotels where it's like the whole thing is they can have robots that can deliver toothpaste to your door if you run out of toothpaste. In this design, obviously, that would be a huge undertaking to make that as a sort of our production system but they used like a remote control of a robot to simulate all of the key touch points when the client of that hotel, will actually interacts with that robot.
I think the same is true when you're building these systems if you can, again going to touch back on we don't fit a code in that way that I think an ever better thing is not be building the code in the first place and to build an almost a non-code system and then, maybe some of the backend are not going to be interested in the results of what people have learned through this kind of user experience trial before they [inaudible] forever but I think it's seeing other people try to use the end system that puts you in place where you can be empathetic.
I argue for the bias point of view that I think people on the backend of Netflix, trying to optimizing the streams in that or the other, they need to spend some time watching Netflix or at least watching the comedy of Netflix in order to empathize of how their work relates to the end experience and then, when those end experience needs changed, it's important for them to make change on the backend. Do you know what I mean?
CHARLES: Right, exactly. They have to watch through that kind of glass window where they can actually help the person. They can't give them any information. The only levers of control they have is through their own work, making the thing changes that they need to make on the backend, so that one of those users is going to have a good user experience.
This idea reminds me of something which I believe is the case at Heroku where they rotate everybody in the company through pager duty, which I think is kind of a brilliant idea where the entire team is responsible for providing technical support to the end users. When a problem arises, you get to understand what it's like to be someone who's trying to use the system. You get to exposed to the satisfaction, whether an issue was resolved or when it's working correctly or your pager is quiet for your entire shift but you can also get exposed to the frustration that you're engendering in the users if something doesn't go quite according to plan.
SAM: Yeah. I'm not [inaudible].
TARAS:: There is movement in this direction because there is actually a term that has been floating around. It's like a product engineer. It's someone who thinks about the product. These kind of people tend to have the highest value in Silicon Valley as someone who thinks about the product as the outcomes supposed to their code as the outcome. Even in the Agile space, there seems to be movement in that direction because I think one of the challenges, like to do that, you have to understand how you fit into the bigger picture. I could see it being really difficult. Imagine if you're working at a bank or something and being pager duty at a bank would be impossible, simply because their organization is either too big or too sensitive.
The way that their company is dealing with that is they have these group of people where you have a product manager working closely with the frontend engineer and the backend engineer so there's this exchange that is happening where people get to understand the consequences of their actions a little bit more. They understand how things fit together. There is definitely a movement happening in that direction that I think just the more, the better because one of the big differences now is the things that we make are very palatable to the users and the quality of the user experience that users are now expecting is much higher than they were in the past. I think the world is changing.
CHARLES: Yeah. We mentioned this when we were talking before the show but going to the University of Michigan as I did, I was in school with a bunch of mechanical engineers. Their goal was to go work for auto companies: Chevrolet and Ford and everything like that but their mindset was very much, I think the product engineering mindset. All of them loved cars and wanted to be part of building the coolest, most comfortable, most responsive cars. For whatever definition of a good car -- there are a lot of them -- they wanted to design good cars but they were into cars and they were into the experience of driving a car, so what's the equivalent then of that product engineer in software?
I think that every conversation that I had with any of the mechanical engineers who were going into the auto industry, I'm sure there are some of them that were out there but it wasn't about carburetors or whatever. They really wanted to just get into the building of cars. In some aspects, I'm sure they all integrated in some way or another but it was a group that was very focused on that outcome.
SAM: In the UK, I'm hearing this term, 'service designer' a lot that's coming up. Are saying that, Charles, you get the feeling that even getting into software, I'm not so excited about using their own? Like the car, I want this amazing car and then I can drive the car and I'll experience the car --?
CHARLES: Right and other people will experience the car that I've helped design.
SAM: Right and in some way, in software, it's almost like the software itself there's this kind of mathematical beauty of its own and it's like always been more important than the other software heads around me like the software that I wrote. I mean, the user? At the conference and all the software guys love it, that's the key objective, isn't it? Yeah.
I work with a lot of learning developers who are rightly focused on wanting to improve their skills and wanting to level up in particular tech stacks that are the ones that will lead to jobs and the future and financial stability and so on but I kind of wish I could inculcate in them this desire that the user experience was the higher goal than which bit of code does this or the other.
Maybe, I'm being unfair to them when I say that. Coding is hard. There's a lot strange concepts to grasp than sort of grappling with those concepts -- how does this work or why does this work or should I use this function or should I use this method or what have you. I don't know. I think [inaudible] bit a wall when I'm sort of saying like, "Let's think about it through the user perspective, what does the user needs here." It feels like they want the safer answer of what's the correct solution here, how should this be refactored because you need a skinny controller or a fat model or whatever happens to be. I don't know if that's --
CHARLES: Right, like what's going to make my life easier, in a sense of if I'm going to be maintaining this code and it's important. It's very important. You want to be happy in your job, you want to be happy in your work and so, you want to have the skinny control or the fat model because it's going to lower the risk of pain in your future, supposedly. I definitely understand but that can't be the only incentive. I think it's what I'm hearing.
The thought just occurred to me, I actually don't know that much about game development. I know the game industry is certainly has got its problems and I don't know much about the development culture inside the game industry. I do wonder what it's like because it does seem to be somewhat analogous to something like the car industry, where if you're a developer in the game industry, you're probably extremely focused on the user experience. You just have to be. It's so incredibly saturated and competitive for just eyeballs and thumb on controllers. Like I said, I don't really know anything about the game industry when it comes to development but I'm wondering if there's an analogy there.
SAM: Yeah. It sounds strong to me and as much of my cousin who works in the game industry and I sort of taught game programming and work through a lot of it. The game industry has got these sort of user testing experience baked in and it kind of like repeat, repeat, repeat, repeat. There's this sort of constant cycle of doing that and in the somewhat wider software industry, in a certain extent, pay lip service to that.
CHARLES: The game industry, they live and die by that. The code lives and dies by how it actually plays with real users.
SAM: Yes and it feels like in the general world, there's a lot more user interfaces that they just sort of struggle on whatever market dynamics people need to use, these existing vested interest, these banks, these supermarkets and what have you. I guess the market is too big, almost. It's not covered enough but do we really want our industry to be so cutthroat? I don't know.
CHARLES: Yeah. We've kind of seen an example of a couple of industries: the car industry, the game industry which is kind of adjacent to where most software development happens but they have this concept of exhaustive user testing, kind of the pager duty if you will, where you get to experience that. So how do we, on our team and when I say our team, I mean anyone who happens to be listening, what's the equivalent of pager duty for the applications that we write? How can we plug ourselves into that cycle of user-ship so we can actually experience it in a real and repeatable way.
SAM: In the work that we're doing with the NHS, they have a similar program. There's a lot of people who are working purely death by desk jobs but they do have a framework for us to go and observe in the hospitals and emergency rooms and so on. I guess the 'how can we achieve that outside of those clients who have those framework in place,' it seems like maybe we need a version of the cycle where a different person gets to be the product owner and tries to represent what the users are experience each week.
I think almost though, it seems like we need more of that thing you mentioned, Charles which is like kind of being behind the one-way silvered mirror as some sort of framework that connects the loop between some of the individual developers are doing and their experience of how the users are seeing things. I think that's going to be difficult to introduce. Just to sort of back up a little bit with them, I see this kind of idea of Agile, which says, "Let's be using the software which is the thing that's kind of changing and evolving unless you already deployed and you are in the maintenance mode from the beginning and you're getting that thing out there so you have your one-week or two-week or three-week cycles where you keep on having touch points," and I think that's better than touching once every two years.
As malleable as modern software potentially is, it's too sticky. It's like you were saying Charles before with that deploying or whatever, these are all gyros and so, you kind of need a really good mechanism for mocking out interfaces and having users experience and there's a couple of [inaudible], vision and there's something else that's sophisticated systems on the UX space where you can put together sort of a simulation of your interface relatively cheaply and you can run these things and then have sort of video capture of the users interacting with the system.
I think the difficult part that we have in the software industry is we are in this thing, where there's not enough people wanting to be software developers, partly with I guess the cars and the games, is there's so many people want to be game designers that the industry can kind of set the terms but we're in this inverse situation here with software developers where software developers are so much in demand, they can kind of say, "Don't put too much pressure on me. I'll kind of like, I'll go off to different company."
You know, we kind of have to like herd the cats, as they say into allowing these high powered software developers to go in the direction as they want to go in and so, it may be difficult to impose something like that, where you're getting software developers to really experience the end user's pain.
I guess what one has to do is somehow, create a narrative to sell the excitement of the end user experience and the beautiful end user experience to software developers such that they're fully out of themselves and say, "Yes, I want to see how the users are using my software." Do you know what I mean?
TARAS:: Yeah. Because a lot of company had this process where there'll be a product manager, there'll be a designer, they'll design through mock ups and they'll just hand it over to developers to build. There could be some backend, some frontend. I think if you're doing that, there is no emotional engagement between the creators of the actual implementation and the people who are going to be using that.
One way to do that is to try to add more of this actual 'however you do it.' You know, introduce more of the personal experience of the users to go along with the actual mock ups so that people understand like, there's actually be a person on the other end that are going to experience this and create some kind of emotional engagement between these two end. How you do that, I think that's a big question but I think if the organization is simply just throwing designs over to development, that's where the part of the problem is and trying to --
CHARLES: Well, actually, that's a fantastic point because ultimately, we've talked about emotional engagement and attachment to the software being a liability but the reason it exists and the reason it's intrinsic to the way we do things is that's how things get built. We get emotional attachment to it. It's the impetus. It's the driving force. It's literally the emotive force causes us to go forth and do a thing. It's why we're going to do it as a good job.
Like you said TARAS:, if you just kind of throwing your tickets over the wall, there is no emotional engagement and so people will look for it wherever they can find it. In the absence of an emotional engagement, they will create their own which is good quality software that's 'clean' code because people need to find that meaning and purpose in their work. Maybe the answer is trying to really help them connect that emotional experience back to that purpose of the user experience, so that there is no vacuum to fill with kind of synthetic purpose, if you will.
SAM: That's a great point. The charity in AgileVentures that I run, when we get things right, that's the thing that happens in that. We go for transparency at open source. We have these regular cycles where the charity client is using the software in a Hangout with us, with the developers who work on these things and the developers whether they're in a Hangout Live, whether they're watching the video a week later, they see the charity end user struggle with the feature that volunteer developers have been working on and they make that attachments. It's more than just 'I want to learn and level up in this thing.' It's like 'I want to make this feature work for this end user' and we're very lucky to have these charities who allow us to do that level of transparency.
The difficulty often comes that I would see in our paid projects where I would love to be recording the key stakeholders using the system but for whatever political reason, you can't always get that. I think that process of actually connecting the developer with the person who using it and doing that reliably, so that they can have that empathy and then get that emotional connection. It's just tricky in the real world.
CHARLES: It's very hard. One thing that we've deployed on past projects, which I think has worked fairly well is kind of putting a moratorium on product owners writing stories or writing tickets and actually having the developers collaborate with the product owners to write the tickets. In other words, instead of kind of catching a ticket that's thrown over the wall, really making sure that they understand what is the context under which this thing is being developed and then almost as in a code review sense, having the product owner saying, "Actually, the reason we're doing it is this," and having a review process where the developer is actually creating the story in support from the product owner.
Because ultimately if they have that context, then coming up with the implementation is going to be much easier. It's really is about facilitating that upfront learning than being able to do the actual work. That's something but a lot of organizations are resistant to that because the product owners really want to say like, "No, I want it to go this way and I want to just hand this to a developer and I want them to do it."
It's kind of wrestling in control and saying, "You've got veto power over this. You're the editor but we really want to make sure that you're on same page with the developer." In cases where we have been able to kind of have product owners make that shift where the developers are owning the story, oh sorry, or the primary authors of the story and more of the code reviewers of the story, if you will, implementation just seems to go so much more smoothly.
The questions, the key points kind of come out of the front of the process and by the time you start actually working on the thing, the manager or the product owners has the confidence that the developer understands what is involved in making it work.
SAM: Getting that done, what one will say something as tricky to do, I think in the ideal world, you have more of the developers involved in the design sprints or the design jams. The logistics of it are you can't really afford to have all those developers in all of those soft meetings where they are coding away. That sounds a great medium there. I think there's various organizations that do sort of their kick offs where their stories are kind of if not code designed, then there's cooperative voting on the complexities of the stories and making sure that they have folks understand the stories that they're working on and there might have some very different organization that are going to have different constraints on how much time that the organization feels, the different people can be allowed to spent on different sorts of activities. It's sort of tricky, isn't it?
CHARLES: It is definitely tricky because any time that you allocate for people, that's the most expensive resource that you have, so you want to be smart about it.
SAM: Which comes back to that issue then again of repurposing people. If you've got that feature that you go over 10 days, can you say to that person, "Can I switch you over onto this other thing for four days?" Maybe logically, that would be a better outcome for the sprint but maybe emotionally, that person is so attached to that. They are not fighting that front.
The biggest trouble for me, I think over the last 30 years is I assumed that the logical stuff was tantamount. These things like the skinny controller and the fat model, we'd agreed on that that was correct and so, that's why I should pushed for, that's why I should fight for because it's the truth or whatever and actually, maybe I'll sling back around in another 30 years, you can choose your battles because the level of emotional pressure on people, then the whole thing just explodes and nothing gets done. You know what I mean?
TARAS:: Sam, I have experienced something very similar and I think about this all the time. It's just how many perfect things are perfectly acceptable to people in using a different lens when I think about technology because the more skilled you are, I think quite often, people become more pedantic about how they approach things but in practice, the more things that you see that are not written but you realize how really imperfect they are and how in many ways, they fit the world very well, people use it. It's being used by many people in its imperfect state, so there is something like this hole between perfect implementation and the role of this perfect implementation in the world that I think that duality is really interesting.
CHARLES: Yeah. There's a fantastic paper written by, I think it was Richard Garfield back in the late-90s or early 2000s called 'Less is More,' where he kind of talks about this exact tension and he calls it the MIT school of software and the Berkeley school of software and I think Garfield came from the MIT school but basically, the whole thing was saying the Berkeley School is actually right and the name of the paper is 'Worst is Better.' It's a really interesting essay but just talking about working things that are in people's hands will beat the best design every single time because those are the systems that get used and improved.
There's a lot more to it than that. He talks about this exact fundamental tension and obviously, no system exists on either one of those perfect poles -- the MIT school or the Berkeley school. I think what he was trying to point out is that exact fundamental tension that we're talking about, the quest for the 'correct solution' and the quest for a solution. I'm actually have to go and re-read it. I remember it being an intriguing paper.
SAM: I guess the thing that makes me think of is sort of related to philosophy value. I read recently about this, attachment to outcomes. I'm going to segue back but we've got this discussion in one of our teams about, this is sort of microservices versus monoliths and in reading this, I doubt microservices, which is actually pretty radical in some of its suggestions that they're talking about it in Greater Than Code Slack where it's sort of saying that actually, if you keep your microservices small enough, then a lot of the things like code quality become actually kind of irrelevant it sort of almost argues that a lot of the things that we like about the Agile and these things are our ceremonies that are only necessary because we trying to feed these monoliths.
I'm not saying it is true. Iím just saying it's a pretty radical position that itís taking and it certainly, captures the minds of some people in our organization. Some things that I've been trying to make some simple changes just to smooth off some of the edges of the platform that we're working with and I had this respect of like, "No, we can't just make those simultaneous. We need to move to microservices." They're great and it will be perfect and they will allow expansion and so on and my immediate reaction is sort of, "I'm glad we don't have to build microservices because [inaudible]. It's all about attachment to outcomes, so am I attached trying to automate part of my week that I think will have some positive goals in the future? No one's got a crystal ball. That's only a guess on my part.
If I've got some folks who are excited about doing this thing with microservices, maybe I should empower them in that and I should started a mobile microservices and we kind of playing with these set of framework and so on. It's interesting stuff as I'm working my way through the book. At the same time, while we've been doing that, I've actually delegated it to someone else to sort out this sort of thing and I've actually kind of addressed the problem what we would need the microservices for through a different mechanism but still, the microservices thing rolls on and I kind of think, "Well, is that all a complete waste?" But then actually maybe, in two years down the line, it will turn out and that will be a beautiful thing that will enable things.
The further that I go on, the more I say, "I just don't know," and actually, if I can detach myself from caring too much about the outcomes one way or the other, I think it's both long and enjoy myself but it's a tricky thing when you got to pay the rent and pay the bills and so on. I don't see any resolutions to that. I love people being able to use things and get stuff done. I'm so excited about that and I guess, I will keep pushing all of the developers that I'm with towards trying to have a better empathy or understanding of their end users because I think software is more fun when you're connected to the end people who are using that.
CHARLES: Absolutely. Microservices reminds me kind of the experience that we've had with the microstates library. Because we've kind of identified this one very small slice of a problem, a 'refactor,' it's basically a ground up rewrite. If you've got a library that is a couple of hundred lines of code but it presents a uniform API, then you can rewrite it internally. You can refactor it by doing a ground up rewrite and the cardinal rule or the cardinal sin is you're never supposed to do a rewrite.
SAM: Yes and that's the microservices that they're saying. It's like you should rewrite everything all the time, basically.
CHARLES: Exactly. You should always be rewriting it.
SAM: Yeah. Should be able to throw it away because it's a microservice and it can be rewritten in a week and if you're throwing one away, it's only a week worth of work and you can keep on moving away. It is an amazing idea.
CHARLES: I have to read that book. Anyhow, we're going to have you on again to explore --
SAM: Well, let's do another one on microservices. It was a great fun. Definitely, it's time to wrap up but I really appreciate you having me on the show and being able to discuss all these topics.
CHARLES: Fantastic and I can't wait to talk about microservices. This might be the impetus that I need to finally actually go learn about microservices in depth.
SAM: I'll recommend Richard Rodger's book, 'The Tao of Microservices.'
CHARLES: All right. Fantastic. Anything we should mention, any upcoming engagements or podcast that you're going to be on?
SAM: Iím always on the lookout for charities, developers, people who want to help, you can find us at AgileVentures.org. We're busy trying to help great causes. We're trying to help people learn about software development and getting involved in Agile and kind of like experience the real software in action, software development where you ideally interact with the end charity users and see how they're benefitting from the product. We love any support and help. You can get involved in that, if you want to give a little bit to open source and open development. We go for transparency. We have more mob programming sessions and scrum and meetings online/in-house every day, so just come and check out AgileVentures.org and maybe, see you [inaudible].
CHARLES: Yeah and if they wanted to say, reach out to you over email or Twitter, how would they get in touch?
CHARLES: All right. Well, fantastic. Thank you, Sam. Also, if you need any help with your frontend platform, you know where to get in touch with us. We're at @TheFrontside on Twitter or Info@Frontside.io. Thank you, TARAS:. Thank you, Sam and we will see everybody next time.
Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at Contact@Frontside.io. Thanks and see you next time.
Mar 29 2019
Rank #10: Team Collaboration with Jacob Stoebel
Jacob joins the panelists to talk about team collaboration based on his RubyConf 2017 talk, Code Reviews: Honesty, Kindness, Inspiration: Pick Three.
This show was produced by Mandy Moore, aka @therubyrep of DevReps, LLC.
CHARLES: Hello and welcome to The Frontside Podcast, the place where we talk about user interfaces and everything that you need to know to build it right. My name is Charles Lowell, a developer at the Frontside. With me today from Frontside also, is Taras Mankovski.
TARAS: Hello, hello.
CHARLES: Hello, Taras and today, we're going to be talking like we do every time about a piece of the platform that you used to develop user interfaces frontside at your company or organization or wherever it is that you build software. Today we're going to be talking about a piece of the platform that's very, very critical that often gets short shrift or is excluded entirely from what people think of when they think about their tech stack and that's how we as teams collaborate to build and maintain and produce the quality software that we can.
With us today is Jacob Stoebel. Welcome, Jacob.
CHARLES: Now, what is it that you do, in your day-to-day?
JACOB: I'm a full-stack developer for a little company called ePublishing and I mostly work in Rails and React.
CHARLES: Rails and React and so, when we were searching for people to talk about how we collaborate these teams, Mandy suggested you because of a talk that you've given at a RubyConf, specifically about code reviews, which I think are actually a huge piece of the collaboration process because it's a major forum where team members get to interact with each other and it's the gateway for making sure code quality is maintained but more than that, I think it's a learning -- a place where we learn. I learned so much both as a reviewer and as someone who is submitting my work and so, it's actually a very important part of the software development process. You have a lot of great examples of how to not do code reviews.
JACOB: Yeah, I think I may have been a little bit too indulgent in that talk. I had a lot of fun. I did some research from other people, mainly from anecdotes. I had research from talking to people about really, all the anti-patterns that come out of code reviews. It seems like every few weeks, I'll see a tweet that says something along the lines about how code reviews are broken.
I don't really know about that and I have to say, I think I'm kind of lucky at my job that I think they're done in a way that really leaves me feeling pretty positive and that's certainly a good thing but I think what it comes down to -- I'm going to sort of talk about where these ideas come from in a minute -- is that we often have code reviews that for one -- and you can tell me how this is for you too -- often the code review is happening at a point so late in the process, where the feedback that you get may not be actionable. Have you experienced that?
JACOB: Before I answer that question, just to kind of echo the sentiment and maybe I'm being presumptuous, I feel like the code reviews that we do are actually very positive, so I haven't got to experience firsthand. Although I have seen conversations on GitHub where it looks kind of like a Celebrity Chef, where you have someone doing the code reviews like Gordon Ramsay up there just screaming and someone has put this plate of food in front of them and kind of picking it apart. That one is extreme but this is actually something that I struggle with, what you were talking about, what is the appropriate point at which to get feedback.
I agree that you want to get feedback as soon as possible and sometimes, when you've invested weeks and weeks into something or you're like at Mile 100 and they're like, "You know, at Mile 2, you were supposed to turn right," and now, you're off in the forest and you've been tracking 98 miles in the wrong direction.
JACOB: Yeah and the work is due, right? This needs to get ships tomorrow.
CHARLES: Right, so you've got massive pressure. This is something that I struggle with myself is when is an appropriate time to really try and be public about what it is that you're doing.
JACOB: Yeah. I think that is a really good question and I think what you're getting at and I would agree is that, the sooner, the better and when you can tighten the intervals between feedback is probably better.
I'll just take a step back and I'm going to take a longer route to go and get to my point. I am a career changer and before I was in this career, I was a high school theater teacher, so it was really different and I won't give answer why I changed other than this is the greatest [inaudible]. But one thing that I really struggled with is I was working with teenagers and I really wanted to see them grow and improve but at the same time, these were kids and they have fragile egos and I don't want to tear them down, so I came across this really interesting framework for feedback. It is called the Liz Lerman's Critical Response Process and I give credit to her in the talk.
This comes out of the dance world. Liz Lerman is a pretty accomplished dancer and choreographer and what she found is that in the dance world and I think it's not too dissimilar from our industry is that the feedback received was often given in a way that was leaving people feel really torn down and mostly, not feeling inspired to go back to their work and make it better. It really felt like feedback is about giving you a grade. It's like, "I'm going to tell you how good of a job you do," and there's certainly a time and place for that but the inspiring question -- I guess the rhetorical question -- that she made is, "Shouldn't the big point about feedback be that it makes you so excited about the work you're doing that you just can't wait to go back to your keyboard and keep working on it," and she found or in the case, back to the dance studio, it really sort of structures this framework for how people can give feedback to a creator and that could be a creator of anything.
You mentioned cooking. This could be about food as well that sort of set some guardrails for how we can give feedback that is useful, it's inspiring and it's kind. I'm going to really distinguish between kind and nice. Nice would be, here I'm going to say things that are only pleasant about your work but what I mean by kind is feedback that is really taking care of your team and making them feel like they are respected and cared for as human beings so they don't go home every Friday afternoon and cry on their couch and just drag and coming back on a Monday. That's kind of the basic idea of why we need, maybe a kind of a framework for getting feedback.
CHARLES: I agree totally. It's almost like you need to conceive of your feedback is not a gate to quality but a gift to embolden somebody. It's like they've just been doing battle with this code, with this problem, they've been grappling with it and it needs someone to wipe their brow and maybe give them a stiff drink, so that they can get back into the ring and be invigorated.
TARAS: What I'm hearing in this conversation so far is it's kind of like a tone or way of communicating to the person receiving the feedback but sometimes, no matter what your tone is, depending on how your team is set up, depending on the context of your actual code review, it can still kind of land in the wrong place? Have you experienced that where the team conditions impact your ability to actually provide feedback?
JACOB: I think I know what you mean. I think what you're talking about is this sort of the organizational structures that are set up are sort of lend themselves to certain modes of feedback and discourage others. I will give this example that I've heard from numerous people and I think this is what you're getting at is feedback that's given at the end. Just like I said, feedback that is given the day before, it has to be shared. Or feedback that it's almost like if we work in an environment where sort of like the hair on fire environment where it's like everything was due yesterday, that's not an environment that's going to be conducive to slowing down, taking a step back and saying like, "Let's point out what we think this work is doing? What questions we have about it? Who has opinions about the direction that's being taken on it?" And really zoom out a little bit more.
CHARLES: Do you have any concrete examples of how that early stage feedback has taken place at your work? Is it just over Slack? Maybe, the whole people need to step back from the idea that working on one-week iterations or two-week iterations and at the end of the iteration, everything is due and everything will get merged at that point. How do you kind of break up that structure to say, "No, we're going to try and have checkpoints and milestones?" What are deliverables that you can decompose the work into that fit inside the framework, that are inside the big deliverables, which is sensibly, the feature that you're working on?
JACOB: I think first of all, it's the way this thing goes about. I don't think this framework works over Slack. I think it has to be immediate, I think it has to be either in personal or on Skype or Hangouts or something.
One of the points of this type of feedback is really about checking in with each other as a team and I think what's great about Slack is that it lets you leave a message and walk away and the unfortunate thing about Slack is it's not meant for sort of attaching how people feel about things or what people's reactions were to them. I think you all have to be in the same space, hopefully with your camera on, if possible and really, just sort of checking in with each other as a team.
I can point to times with my team that I think that's really worked out. I think you made a good point when it comes to really getting started with a project because there are times where I made the mistake of not trying to get feedback from my team early on when I was going to start a project and as you can imagine, did that really cost me? It's really getting feedback from my team and my supervisor about the direction this is going to want to go and I'll say from experience, I work on legacy codebases and as you can probably imagine, it's easy to paint yourself into a corner and what the thing about legacy code is that you don't know what pitfalls you're working into. You can get started and you can sort of find into the process, there is some reality about this code that you didn't know and it is really getting in the way of your work that had you known about it, it would have saved you a lot of trouble because you could have planned your way around it.
Then the fortunate thing is drawing on the wisdom from people who they know about it because they struggled with it already if they've been around longer than I have. I think that's a really good point. This is a good thing to do. As you're getting started and you can be sharing this is my just initial idea of how I'm going to go about this. What my tech stack is or my understanding of the problem space, all of the above and to really sort of check your assumptions and see if they really check out.
CHARLES: I want to circle back a little bit to something you'd mentioned before and that is you want to be kind in a code review and I would say, you probably want to be kind anytime you're giving feedback or interacting with your teammates but what's the process that you can go through if you find yourself struggling? How can I deliver this message that I want to deliver and have it come across this kind? What's a process or checklist that I can go so that I don't open my mouth up and say something that I can't take back or that is going to land wrong?
JACOB: I'm glad you asked that and I think that this is a great way to introduce the guidelines for the critical response process. There's basically four steps to it and the way it's structured is you have the person who has created the thing. It could be the person or the team that has created the feature. You have other people who are responders to it. They could be people within your team or they could be others in the organization who are invested in your success. They're not here to tear you down or give you a grade. They're here because they want to see the project do well and then, there's going to be someone who is a facilitator.
The way it works and I think this is directly addressing your question is there are guardrails that are going to help you not steer into territory that is going to leave someone feeling torn down. The first step to this process is all the responders are going to say statements of meaning about the work and what I mean by that is you're going to make things that stand out to you that are not attached with an opinion. You could say, for example, "This project is using React hooks. That's something I noticed." You're not going to say, "I think that's a good idea or a bad idea," but you're going to say, "This is what I'm noticing," and that is something that can get jotted down because that's going to be fodder for discussion later on like, "Let's talk about this new feature in React," and let's talk about it later. We can talk about if we think that's a good thing or not or what the implications are for that.
The next step after that is that the person who has made the work of the team, they get a chance to ask questions of everybody else about what they thought. You've probably noticed that in a lot of pull requests, someone puts their work out there and then, the next thing that happens is everybody starts commenting on the work and saying what they think about it. This flips it. At first, you as the creator, start asking questions or you can say, "This thing over here, I think it's maybe a little wonky or it's a little hacky but I couldn't think of a better way to do it. What do you think? Do you think it's right? Do you think it's a bad idea?" Or this bit over here, "I'm pulling in the third party library. I think maybe, it's worth it but what do you think? Is it not worth it?"
CHARLES: I like that because ultimately, the people who have created the thing are the most familiar with the problem space. They've spent a lot of time thinking about it and so, they can actually direct the conversation to the parts of the implementation that really are the most iffy and the most unknown because everybody is going to feel this need to comment but it's the classic case of bikeshedding really, the true experts or the people who've just been spent all this time implementing and so, people will comment up to their greatest point of familiarity with the problem, which could actually be not that great. Can you say like, "Can you really focus your mental energy on this?" I like that a lot.
JACOB: Yeah and really, it sets a good tone. The assumption behind all of this is that the creator, like you said knows the work best and really ought to be in the driver seat when it comes to feedback, so it really sets the tone there and say like, "The creator knows what's most important. Let's give them the first opportunity to frame that," and I know plenty of times like if I'm asked to review a PR and I'm not given any kind of prompt or direction, I will probably scroll to the file. Maybe I'll find the file in that PR that I'm actually familiar with or I'll look for some pattern that's something that's like, "I understand what's going on here. I can give feedback," and if it's all that other thing over there, I'm completely confused, I'm going to ignore it.
But the creator could illuminate me a little bit, then I would understand a little bit more and then, I'm in a position to comment on that thing that I otherwise wouldn't have understood. That's the second step. The third step is now the responders get a chance to ask their questions but the important thing about that is that there are neutral questions. The assumption here is that the responders need to better understand the context from which this code was written in order to be able to give their opinion.
Here's an example coming from the Rails world. I could say, "Tell me your thought process for using Factory Bot," in this example. If anyone doesn't know that is somewhat of a contentious issue in the Rails community, rather than just coming out guns blazing and say like, "I think this was a bad idea." It's like, "Tell me your process because I want to understand the context you came from and then we can together evaluate if coming from that context makes sense or if it doesn't," so neutral question. They have to be neutral questions.
By the way and we've probably all heard this before, this is not a neutral question, "What were you thinking when you decided to do blah-blah-blah-blah-blah." Everyone knows what that means.
CHARLES: Right. I was going to say, you can be very, very passive-aggressive with questions.
JACOB: Yeah, exactly and this is a place where having a facilitator can really help -- facilitator who is not one of the creators. Someone can just say, "Let's back up. Can you rephrase that without the opinion embedded? Can you just say that again?" and with that again, those are some of the guardrails that keep us on track.
After the responders have been able to ask their questions how hopefully everyone has a better understanding of the context from which the code was written, then it's time for opinions with consent of the creators. The way it works is the responders can say, "I have an opinion about using React hooks in this codebase. Would you like to hear it?" The responders can say, "Yes, please. Let me know," or they can say, "No, thank you," because the responders, having the best knowledge of the context, might know that that feedback is not useful. Maybe, they have a really good reason for using React hooks or maybe, they know what's coming in the future or maybe, they know if there's no time to fix it now or it's not worth fixing now. They know the tradeoffs best and so again, those are guardrails and it puts the creator in the place of saying, "That's actually not useful feedback right now. Let's just not use it." They can say, "Yes, please tell me," or they can say, "No, thank you. Let's not talk about that."
CHARLES: In the context of a pull request, the process you're describing could be played out in any number of media but in the context of a pull request, the creator is the person actually submitting the code, how do you handle the issue of who pushes the merge button if there's still some opinions that haven't been voiced? For example, a creator says, "No, I don't think that's helpful feedback," is the assumption of then the creator can go ahead and just push the merge button? Or is it basically saying, "I don't want to hear your opinion," relatively rare?
JACOB: That is a great question. I think I tried to get at this in the talk. Before one thing, I am probably, like most people don't have the option to just say to my manager, "No, I don't want to hear your opinion." I get that. There is a contrast between the pure version of the feedback process and then reality. They have to balance. But teams can sort of work out the way they give feedback.
I have example of an anecdote that someone shared with me once, when I was doing research for this talk. There was this sort of agreement with the manager that their manager wouldn't give feedback on Friday afternoon. They just wouldn't. Everyone preferred that. Everyone sort of wanted, say on Friday afternoons, I'm really going to be just focusing on winding down for the week and I don't want to get dumped on a bunch of feedback. The point being, even though you can't just blanket-ignore feedback, you can work out circumstances with your team for the best way that feedback can be given and circumstances under which, it can be politely declined.
CHARLES: I see.
TARAS: I'm curious about a different part of this because a lot of this is how to give feedback but I'm really curious about the why part. I think many of us take it for granted that good code reviews are very valuable because a lot of teams that I've encountered that are taking on really big challenges but didn't have a code review process and so, one of things I'm kind of curious is for people or for teams that don't have it in place, what kind of symptoms can they observe in their daily operations that would suggest that maybe code review is something that they need to put in place.
CHARLES: Taras, you're talking about kind of the places where we've seen where the culture is just push everything to a branch, there's a 1000 commits there, open up a pull request and no description, no name. It's like, "Here's this thing. I'm taking comments for the next three hours and if everything goes well, let just merge." Are you talking about those kind of situations where really a big culture of pull request or just feedback around change is very, very nascent.?
TARAS: Yeah, a lot of times, it's the 'ship it' culture, like this is getting in the way of shipping it.
CHARLES: So you're saying like how you sell the entire idea?
TARAS: Yeah and if someone is listening who is noticing that, a lot of people would know that we're not really doing code reviews but what are the symptoms that they could be observing that could say like really, this is we need to change, like this can't continue.
JACOB: Yeah. One thing that occurs to me as if there's all high level of surprise when you read it, when pull requests are read, it's like, "Oh, you went in that direction." I think that could be an indication that maybe, we could have checked in at the halfway point or even sooner because there seems to be differences of perspective on where this is going or where it should end up that's why [inaudible].
TARAS: At what point do you think people would see this? Is this something that would happen kind of way down the road? Like actually, "How did this end up in the codebase?"
CHARLES: That's surprising except deferred even further, right?
JACOB: Yeah, who wrote this last few. In having that kind of feedback process, let's sort of take a look at where this project has come in the last few months and see if we can sort of learn from what went well and what didn't.
CHARLES: This is related to the concept of surprise, if you see a proliferation of many different patterns to accomplish the same thing, that means the communication is not there. People are not learning from each other and not kind of creating their own code culture together. If that's missing and that manifests itself in all kinds of ways, in bugs, in weird development set up that takes me two hours to get this local environment set up and things like that, if you're seeing those things, chances are you need some way to come together in a code review culture is really, really good for that.
JACOB: Yeah and I think in the ideal code review culture, everyone that's sort of brought on board is saying, "I am going to share responsibility in this patch, doing what it's supposed to do and not breaking anything or not burning down the world." You mentioned the 'ship it' culture, I could imagine toxic cultures where the person who shipped it, if it broke everything, it's on them to fix it and they have to get woken up or whatever and the idea about feedback is now we're sort of forming a community around what was done, so it's like the person that push the merge button isn't the only person involved. It's like if we have a culture where we say everyone that participated in the PR is collectively sharing the consequences and that will happen eventually and say like, everyone who's on this thread, it's on all of us if something goes wrong to fix it. I think that is certainly something that one would hope you'd see.
TARAS: I'm curious, where do you see this kind of observations usually come from because sometimes, I can imagine there, being a developer, coming on the team and they're like, "Why wouldn't I do code reviews?" and they're like, "Well, we have always not done code reviews," but then there could be someone like a product manager or somebody who's like, "Why wouldn't I do code reviews? We should start code reviews." Have you seen ways of introducing these ideas to teams that have worked out well?
JACOB: Yeah and I should probably say that, I'm not a manager, I'm certainly not an expert in how this works so I actually don't have a really great example, personally. I can churn example from working in a previous team, where everyone secretly wanted to be more collaborative but didn't know how to do it because if I'm the first person that puts myself out there and no one knows else knows how to collaborate with me, how to reciprocate, then what was the point? For the top 5% of teams that are just really have great energy together, they don't need a framework to do this sort of thing. They're just doing it naturally.
I think for everybody else, we need some kind of guidelines to do this because for better or worse, this is the industry that we're in right now. It isn't built around us. We don't know how to function this way and it's no one's fault. It's just sort of that's the way we've all sort of learn to work in this industry and I suspect we're not the only industry like this but we need some kind of guidelines to do it.
TARAS: Maybe it's a difficult question to answer. It varies probably from team-to-team.
CHARLES: Yeah and maybe, we can kind of shift the question just a little bit because I have one that sits alongside not quite the same question but I think related and can bridge it and maybe we can find the answer there. We've talked about a little bit and there's definitely more to unpack there, how to give feedback that's kind and honest and I think to... What was the third?
CHARLES: Inspiring, that's right. What about from the flip side? This is something that actually comes up with us as consultants but I think it's something that other people will encounter in their jobs too, is what do you do when you are the creator and you're trying to present or share and ultimately solicit feedback from a stakeholder, the CEO of your company, one of your clients, one of your customers and you see them engaging in kind of a mode of feedback that's less than constructive. They're nitpicking on things that aren't really important and maybe, this could be completely and totally inadvertent. Their intention could be that they're trying to help you out but it's really not being helping at all and it's kind of like either tearing you down or just not being productive and it makes you feel... What's the word I'm looking for? Just brings an air of contention to the conversation that's not really helpful to producing the best result for everybody involved. How do you, as the creator actually engage with those people in a positive way and kind of help establish the guardrails and be that agent of change when those guardrails don't exist in their minds yet?
JACOB: Yeah, how do you do it, right? It's probably rare that there's going to be an environment where someone's going to say, "We're going to do this framework for feedback," and everyone are onboard from Day 1.
I think one of the things that you're probably getting at is the frustration that happens when people start giving feedback. You have this perception that they're giving you feedback that's unuseful and they're only giving it because that's the only thing they can think of or --
CHARLES: Exactly. They got to say something, they need to contribute their two cents to the conversation and some people are trying to be helpful and just aren't. Some people are just trying to appear smart.
JACOB: Yeah and it's like, "Oh, boy. They're just really off."
CHARLES: But you can derail the main narrative that you're trying to establish and get off in the weeds, kind of skirmishing with these people and after that happens, you're like, "Wait, no. I don't want to end up over there. I was trying to tell a story."
JACOB: When I gave this talk once, one idea that someone threw out was when you make a PR, mark up your own code first with everything that you want to draw people's attention to. I think you were getting at this as like, "One frustrating thing is when people getting feedback seem to have less invested than you do." They sort of just flying by and dumping on you and they probably, actually couldn't care less and that can be frustrating.
When you're engaging with people that maybe don't know how to get deeply involved in it yet or maybe don't have the time to, you can sort of gently nudge them to sort of like, "I want to talk about this part of it." It's almost like you're giving the answers to the test, which was like, "If you want to be part of the smart conversation, comment over here," and I think from the responders perspective, just speaking personally, I would appreciate that. It gives me an opportunity to feel like I'm actually being useful. We can all probably point to times where all the code review we have to do feels like homework that isn't the best use for our time. It's like, maybe the responder can make us feel like our opinions matter and they will be put to good use when you tell them, "If you comment here, it will probably be put to good use."
I think the sort of the way to get started is the responder can just say, "I would really like feedback over here," and I can't speak for everybody but I would suspect that more people than you think would be more than happy to be gently guided in what feedback they should get.
CHARLES: Right. I'm thinking how you would do this, for example in the context of a demo that you're giving to stakeholders because there's maybe the inkling of the idea to do that but it's often presented as an apology like, "This screen doesn't work," or, "Your handling isn't quite right. Sorry we're going to fix that." Look at the stuff that's over here and maybe, the way to frame that is a really hard problem based on the legacy architecture that we have for displaying errors and I'm not quite sure how to do it in a robust way and I could really use some feedback there. It's an area of exploration or something that we really need to focus on. You put that out there as I'm demoing this main functionality right now.
JACOB: Yes. You sort of say like, "Here's something to watch out for and please, let us know what you think," and then after you could say like, "As a team, we thought up these three possible solutions but we didn't want to move on them because we wanted to get your feedback first, so please impart on us what is the right way to do it." You know, flattery goes a long way.
TARAS: I have this imagery coming up in my mind as I'm hearing you guys talk about this that I keep seeing this kind of difference between a line and a triangle, where a line is kind of a tug and pull between, "Did I do this right? No, I didn't do this right." I think those are kind of a bad code review because it's very personal. It's not really where you kind of want to go and then the other way is like a triangle where the end goal that you're trying to get to is somewhere that is beyond both places where you let two people: the recipient of the code review and the giver of the feedback, the end goal that you want to get to is actually someplace else.
When we deliver the code and we say, "My code is done," then it invites this kind of linear feedback where it's like, "No, you didn't do it right," but in the other way, "This is where I got to so far. Tell me where you think we could take it next. If you don't think we need to change anything, then we're done. We can merge this."
JACOB: Yes. The very intelligent Jessica Kerr said recently on another podcast, there's no such thing as done but you can always make it better. I think you're getting at that point. That's a great question, by the way to ask of your responders -- where should we go next? Where do you see this going next? What will make it better? What would make it more robust? What would make us happier six months down the line when we're looking back on this? But I think of it as the firing range. That's the analogy I gave where it was like, "You put a pull request out and you assert that it is done and if no one can find fault with it, then it's done," and I just don't think that that makes sense. I don't think, really most people actually want to work that way. It's maybe not necessarily even healthy but I think everyone can find, at least I hope, a process that invites them to come into the process and share the way they see things. It can hopefully be enriching and just make everyone feel better along the way.
TARAS: This sounds to me like the inspiration part of this conversation because one thing I really like about working at Frontside, I'm an to experienced developer but I know that Frontside is dedicated to doing something much greater than I can do as an individual. When I ask, "What do you think about this?" then I know the feedback is going to be because there something always that is just beyond the reach that could be a little bit better than what we have right now and it's not until I can actually get the feedback from Charles, from Jeffrey and hear, "What do you guys think? Is this it?" and they're like, "What about this?" and I know that the next step is going to be a little bit or maybe even a lot better than what I have right now. I think that's the part that inspires me. I know I have actually gone a little bit further beyond my personal ability to get us to that vision of like this being much better than we could do as individuals.
JACOB: Yes and as opposed, "Oh, I screw it up and now, I have to fix it." The framework of find all the errors that I made, even though there may be errors. Let's be honest, there could be things that would be really bad, that would be a security problem but for a growth mindset, to think about it, it's like, "This is a way to make it better."
CHARLES: One of the things that you can do to help that is try and find inside every change, try and see the potential that hasn't yet been realized but is enabled by this change, like what exciting paths does this change unlock in your mind, right? And then you can share that. That's a great way to 'inspiration is infectious,' so if you can find inspiration to change, then you might be able to share that with the creators. If something is very personally exciting to you when you see something, maybe spend a little time searching for what you find to be exciting about it.
JACOB: Yeah, nice. That's great.
CHARLES: Yeah, we might have touched on that. I just bring that up because so often, I'll see the changes that people on my team are submitting and sometimes, it can feel like a cloud burst of like, "We could do this or we could do this or we could do this," and it's great to get excited.
JACOB: Yeah. I can share -- recently, there was an example. My coworker opened a pull request and it unlocked something for me where I said like, "You know what? This is making me think about this other thing that I've always hated doing with our legacy codebase. We should do that thing you're doing more because boy, would it make life easier?" and I wonder if it would be worth the time in refactoring X, Y, Z because then I would never ask you A, B, C again and I would be so much happier.
TARAS: It makes me think that we need to revisit our pull request template like what would that like? What would be the sections on a pull request template that would facilitate this kind of way?
CHARLES: I don't know. I know we're almost a time but before we even get into that, this is a question I have because we talk about pull requests templates, how do you match the amount of process with the scope of the change? Because it's probably a little bit heavy weight if I want to fix a typo and say, "Now we're going to have the creators lay out their case that they're going to ask questions of the reviewers and then the reviewers are going to ask questions and once everybody's been able to write down things that they observe the questions that they have, completely and totally divorced from opinion, now we can talk about opinion that is welcomed." If you're capitalizing one letter, that's probably a little bit heavy weight but on the flip side, it's probably absolutely warranted if it's a major feature that's going to be affecting a huge portions of your revenue stream and so, this is one of the problems I have with pull requests templates is they are one-size, fits-all.
Sometimes, a pull request template feels like it's supporting you and sometimes, it feels like the epitome of busy work and I have to spend all this time deleting the sections for the pull requests template. I wish there were ways you could choose different pull requests templates. Maybe, there are.
JACOB: So do I.
CHARLES: That's a little bit of a quibble that I have is the amount of ritual and ceremony that you have to go through is fixed with a pull request template but it seems like you want to match the amount of process to the scope of the change.
JACOB: Yeah, you do and the flipside is also joy. You don't want to give someone too little homework when you really needed the same work. Maybe there's a way to say, when a pull request is opened, the person who opened it or the manager or maybe someone else, has the option to sort of tag the pull request as saying, "This is going to be a bigger conversation. We cannot merge it until we have a face-to-face conversation first with these various stakeholders." Maybe, one of the questions, the first form that everyone gets for every PR gets is what level of PR is this? Is this a quick change? And what people that you just need some quick feedback on? Or is this the long form that you need where there needs to be a sit down with these people?
TARAS: Actually, I was thinking what's the adjustment that could be made for pull request is to say, "Here's what a complete pull request looks like. You can opt into whatever section you want," so you decide based on your pull request, what the actual sections of this template are appropriate but then someone can, on the flip side say, "Look, I would really like to learn about the motivations of this pull request. Can you add motivation section?" and understand that from your pull requests.
JACOB: Absolutely. You filled out Section A, please answer Section B and C. Yeah, cool.
TARAS: Yeah. Because I think what part of the challenge is that we have people look to us, especially people who have a lot of experience, or developers look to us to know what is the right thing to do sometimes or often and I think it's helpful to be a little bit more gentle and saying, "You can decide what is the right amount of detail to set the right conditions for this code review but I will give you some directions for what are things you can consider in including.
CHARLES: All right. We're a little bit over time, so we should probably go ahead and wrap it up. You are absolutely right, Jacob. This is a topic that keeps on giving. We didn't really move much beyond the pull request and feedback and stuff but we moved a lot around within that topic because it's a big one. Jacob, is there anything that we should mention? Any upcoming talks, meetups?
JACOB: No, I have a one-year old and it's all about work and family in this part of the life, so I have nothing to speak of at this point. You can come find me on Twitter as JStoebel.
CHARLES: Okay, awesome. Well, thank you so much, Jacob for coming and talking to us. This is a very rich topic. We only really scratched the surface. That's it for our episode today and we'll see you next time.
Thank you for listening. If you or someone you know has something to say about building user interfaces that simply must be heard, please get in touch with us. We can be found on Twitter at @TheFrontside or over just plain old email at Contact@Frontside.io Thanks and see you next time.
Mar 14 2019