 Hi everyone, my name is Julia. I'm a software engineer at Crunchy Bananas. I am so thrilled to be here with all of you in person. The last time I spoke at Ember Comp was 2019 and a lot has happened since then. I became a parent for the first time. I learned what it is to be truly deeply tired. And my relationship to the world around me shifted dramatically. It was so hard. It was joyous, it was terrible. My life was in a constant state of chaos. These were new experiences and new problems that required substantial adaptation. And it required an immediate shift in perspective in order to manage the complexity without drowning. So something happens after you've exhausted all episodes of Chef's Table and you haven't slept for months. You start to ask yourself questions. I needed to frame my experience as part of something larger in order to move forward. What gradually emerged was a system, the various mechanisms of my life adjusted to meet new demands. When I returned to work after parental leave, I was struck by the parallels between the problems I was solving as an engineer and the challenges I was navigating as a parent. I began to understand my relationship with my work and my development team differently. Just as I was cultivating a system as a new parent, I began to view systems thinking as a crucial aspect of successful development. First, let me loosely define what I mean when I refer to a system in this talk. Here, I have to acknowledge my brilliant uncle William Donaldson, his writing is a key reference point for this talk and much of my awareness of systems thinking I owe to him. In his book, Simple Complexity, he writes, what distinguishes a system from merely an assemblage of the elements is the interactions the elements engage in by design or by happenstance and the way those interactions shape the system dynamics. By design or by happenstance, this is important. A system can exist without being organized or efficient, which brings me to the first lesson. If you're not careful, everything is going to get sticky. A system is in place, whether you've designed it with intention or not. My parenthood journey did not begin with organization. I had no idea what I was doing. I began with a reactionary system to survive those first few months, and it was painful. When the system of your app designs itself through happenstance, every part is impacted. It can be easy to wind up with redundant server requests, unintended side effects, or a code base that no one enjoys working on because of the complexity of making even small changes. It also becomes a significant mental burden to keep track of a runaway system. A simple question from my pediatrician, like how many ounces of milk does he drink in a day? Felt like I was being asked to solve complex equations because I had no reliable anchor points. It can be tempting to react to messiness with a plan for the perfect solution. Entire industries exist to sell us systems that will solve all of our problems. As I struggled to regain control of my life, I downloaded various apps to help me manage my baby's day. I read books about how I could apply a structural approach to encourage sleep. I scrolled feeds for parenting hacks. And none of it worked exactly as promised. They ended up being too rigid because there were always, without fail, be a dirty diaper. A well-designed system embraces the inevitability that things will go wrong and not fit. Part of the design must include some kind of escape valve that allows you to contain a negative impact. It has to be flexible enough to allow for messiness and inefficiency as you work towards improvement. What I had failed to recognize was that a system is not a static structure. It is constantly evolving and growing. I began to conceptualize each day with my son as an iteration of the system, rather than a failure to adhere to boundaries that no longer served us. Iteration is a key process for any application that intends to scale. Similarly, it is essential to consistently re-evaluate the boundaries that you are imposing throughout your code base and whether or not they still fit your needs. This can be particularly difficult. Anyone who has worked on long-lived applications knows how legacy structural decisions tend to calcify over time. And this leads me to the next lesson. Change is inevitable and it is constant. And the anticipation of change must be built into your decision-making. You must strengthen your ability to pivot when a previous solution is breaking down because there is no finish line. There is a special kind of defeat that you feel when you have painstakingly created a lovely dinner for your child and they refuse to eat it. This is not unlike spending weeks building a feature only to be told by management that it needs to completely change. And it can be hard to let go of the work that we are proud of. But the real job of an engineer is not only to build but to know how to pivot and to write code that maintains optionality for the future. I ended up ditching elaborate recipes for my child because it wasn't working for us in the larger context of our day. The meals I serve daily might not be Pinterest-worthy but they achieve my ultimate goal which is to keep my child healthy and fed. If my child is being picky, I can easily swap out carrots for grapes and not feel disheartened. For me, it is counterproductive to insist that he eat something using the rule because I said so. I'm not willing to declare dinner time a failure because it doesn't strictly adhere to my expectations. I'm also not willing to abandon dinner time completely and let him eat applesauce pouches all day. There has to be a balance while we work to iterate and improve. These are the kinds of trade-offs and decisions we are constantly making as parents and as engineers. If you conceptualize your system as a set of rules, there is no room for growth without conflict. Any deviation, even a necessary one, will cause friction and using rules as a way to enforce your system inadvertently discourages engagement and analysis because adhering to a rule does not require contextual awareness. Framing things within context is essential to moving forward productively. When you're working within a certain vantage point, a lack of context about the rest of the system can inadvertently create competing interests. When you leave things that you do this because I said so, you invite your child or other members within the system to invent their own context. Approaching resistance with explanation and context is far more fruitful. And system awareness should not just be reserved for those with more senior positions within the system. Children are constantly searching for context by questioning why repeatedly. Contextual awareness is essential for processing a barrage of new information and by providing them some level of context, we empower them to help towards our shared goals. Because context is not just about aligning all system parts. It is also about building a path towards greater system knowledge for everyone involved. A junior developer's awareness of Ember data likely begins with the outermost API and a conceptual model of the store that exists for the life cycle of the app. A more senior engineer has probably brought in that contextual awareness to include adapters and serializers, internal library code, and so on. When system awareness is present at all levels, the door is open for everyone to scale their knowledge up and contribute meaningfully. We don't want developers to be siloed, making components in a box and never engaging with the rest of the application architecture. My son is two and his understanding of each day generally falls into one of these models. Food, rest, and play. And those core concepts will still be in place as he grows to understand them with more complexity. As an adult, my understanding of food as a concept is far more nuanced than his. I understand how food intersects with physical health, mental health, and even social issues. But the shared mental model of food as an important part of each day is in place for us to expand on together. Ultimately, we are both engaged in the system of learning together. And it's important to note that the learning is not one way. I am constantly evolving and learning how to be a better parent every single day based on his feedback. So what has all of this got to do with Ember? The last time I experienced such a transformative life event was in 2016 when I was first learning how to code. When I spoke at Ember Comp in 2019, the main thesis of my talk was that Ember's conventions facilitate communication, collaboration, and growth. I still believe Ember excels at this, but a lot has changed in Ember since then. I first began working with Ember version two. The framework has shed a lot of weight since. We can now rely on native solutions for many legacy Ember features, and Ember has pioneered many concepts that have been adopted by the broader ecosystem. Which begs the question, as Ember feels lighter and closer to native JavaScript than ever before, what exactly is Ember providing? I have come to think of Ember as similar to a climbing wall of anchor points. It gives you just enough of a foundational system to forge your own path, because of course no one system can meet the needs of everyone. When you start with Ember, you're starting with those conceptual anchor points that are the building blocks of a great system. It empowers developers of all skill levels to engage with an application at the system level. And Ember provides a system without imposing unrealistic rigid boundaries. There are APIs for isolating those dirty diapers that inevitably will exist, so you can still move your product forward. You need to use jQuery for something, put your jQuery code in a modifier instead of allowing it to halt forward momentum completely. Having drive-through franchise for dinner one night doesn't need to negate all of the progress. Ember's approach to deprecations is about ensuring the integrity of these conceptual building blocks while moving the technology forward. Nap time can be deprecated in favor of quiet time, but the system model of rest remains in place. Ember embraces that there is no finish line, both for itself and the applications built with it. I will quite literally never be finished with raising my son. Similarly, it is not an option for me to just throw my hands up, declare defeat, and start over. You can choose to see mistakes made along the way, or you can choose to see lessons that gave way to growth, refining your system. This is hard work and it's messy. To borrow Ember's marketing slogan, it's ambitious.