<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: kate astrid</title>
    <description>The latest articles on Forem by kate astrid (@kate_astrid).</description>
    <link>https://forem.com/kate_astrid</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1154209%2F48fdfa0a-d2bf-4410-bb49-6fcec9e039da.jpeg</url>
      <title>Forem: kate astrid</title>
      <link>https://forem.com/kate_astrid</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kate_astrid"/>
    <language>en</language>
    <item>
      <title>From Chaos to Clarity: Fixing Our Monorepo</title>
      <dc:creator>kate astrid</dc:creator>
      <pubDate>Tue, 19 Aug 2025 11:45:37 +0000</pubDate>
      <link>https://forem.com/epilot/from-chaos-to-clarity-fixing-our-monorepo-2bih</link>
      <guid>https://forem.com/epilot/from-chaos-to-clarity-fixing-our-monorepo-2bih</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction: Why This Story Might Save You Some Headaches&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;If you’ve worked in a large codebase, you’ve probably seen this: the code runs, but every change takes far longer than it should. Updating one feature often breaks another. Adding a dependency means worrying about conflicts. Old build tools still linger, and no one feels safe upgrading packages that half the system depends on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadw3szflwaorl8fxe66t.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fadw3szflwaorl8fxe66t.png" alt=" " width="800" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That’s exactly what we faced in our &lt;code&gt;journey-monorepo&lt;/code&gt;, the main repository for our team. Dependencies were wired together in inconsistent ways, different teams had introduced multiple overlapping build tools, and some libraries hadn’t been touched in years. Proposing a cleanup felt like asking to redesign a city while people were still living in it — risky, disruptive, and easy to delay indefinitely.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;So why did we bother?&lt;/strong&gt;
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Development had slowed to a crawl.&lt;/em&gt; Builds were taking too long, and waiting minutes just to see a change in the browser was killing productivity.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Every change felt risky.&lt;/em&gt; The dependency spaghetti meant a small tweak in one package could break multiple apps — often in ways we wouldn’t notice until much later.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Onboarding new developers was painful.&lt;/em&gt; It took too long for new team members to get up to speed, mostly because they had to learn multiple bundlers, testing setups, and outdated tooling quirks.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Technical debt was blocking new features.&lt;/em&gt; We were spending more time patching, debugging, and wrestling with the repo than building the actual features our users cared about.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Costs were adding up.&lt;/em&gt; Longer build times meant higher CI costs, and outdated packages made security updates and maintenance more expensive in the long run.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In short, the longer we waited, the more time, money, and momentum we were losing.&lt;/p&gt;

&lt;p&gt;And, hey, now we get a good story out of it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hcmyun9s9ew3gqoyx5w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hcmyun9s9ew3gqoyx5w.png" alt=" " width="800" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Journey-Monorepo in a Nutshell&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykolpl8sntrwe4pdeoqc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fykolpl8sntrwe4pdeoqc.png" alt=" " width="800" height="548"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Journey-monorepo&lt;/em&gt; is the central place on the epilot platform for everything related to journeys. What you see in the screenshot above represents two main apps: &lt;em&gt;journey-app&lt;/em&gt; on the left side and &lt;em&gt;journey-builder&lt;/em&gt; on the right. &lt;em&gt;Journey-builder&lt;/em&gt; is responsible for configuring journeys, and &lt;em&gt;journey-app&lt;/em&gt; for rendering them. &lt;br&gt;
Like in many startups, the repo started out clean and well-structured, but as the product grew quickly, the codebase expanded in unplanned ways — things were added wherever they seemed to fit at the time.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;The “BEFORE” Setup&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Apps:
- journey-builder.               
- journey-app
- entity-mapping
- journey-view

Packages:
- blocks-configurators
- blocks-renderers
- journey-elements
- journey-utils
- journey-logics-common
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let me show you the rough map of dependencies we had step by step. We are interested in two main apps: &lt;code&gt;journey-builder&lt;/code&gt; and &lt;code&gt;journey-app&lt;/code&gt;, so I am going to dive deeper into their connections. It is not important which app or package does what. What IS important is to see how many connections we had to keep in mind every time we needed to change anything.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ok, this is fine.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf5p4t1zdjxf169gq22z.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkf5p4t1zdjxf169gq22z.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This is too.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8udxll5y9ewrp6q8nboq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8udxll5y9ewrp6q8nboq.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Yeah, cool.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuy2gcleacdlwo85nozw0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuy2gcleacdlwo85nozw0.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Packages already become tangled, let's keep going.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncrjunqvi3x0zojsp82d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fncrjunqvi3x0zojsp82d.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ok, even more connections.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qeqtr5pcsd766pxyhld.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6qeqtr5pcsd766pxyhld.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Well, this is just a delinquent madness.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptjuqypr9w8yp04lzbmj.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fptjuqypr9w8yp04lzbmj.png" alt=" " width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You might say: Kate, come on, this is what happens in every big project - things become deeply intertwined, and it is a normal thing to experience. &lt;br&gt;
I will answer: yes, but I haven't finished.&lt;/p&gt;

&lt;p&gt;Let's now add the build tools to this table to have the full picture.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jfmqmed9opca1t4cy1h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3jfmqmed9opca1t4cy1h.png" alt=" " width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Well, what we have here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Webpack;&lt;/li&gt;
&lt;li&gt;Craco;&lt;/li&gt;
&lt;li&gt;Tsup;&lt;/li&gt;
&lt;li&gt;Tsx;&lt;/li&gt;
&lt;li&gt;Tsdx.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I don't know about you, but I hadn't worked with half of them before I started working on this repo. &lt;/p&gt;

&lt;p&gt;In the end, it was a web of “if you change this, you might break that” — and “that” could be anywhere.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;How We Tackled It&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;We kicked things off with an RFC — basically, “let’s write this down so we don’t lose the plot halfway through.”&lt;br&gt;
Our two big goals:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unify the tooling so we weren’t juggling five different build setups.&lt;/li&gt;
&lt;li&gt;Untangle dependencies so teams could work without stepping on each other’s toes.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And this is exactly what we did.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Cut the Cord on Unnecessary Dependencies&lt;/strong&gt;&lt;br&gt;
The first thing we had to do was face the dependency jungle. Over time, different teams had introduced overlapping packages, and no one was quite sure what depended on what anymore. Cleaning this up gave us a chance to regain control.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Untangled all the apps and packages as much as possible.&lt;/em&gt; We mapped out how everything connected and then started cutting back the unnecessary links. This meant reducing cross-dependencies that caused fragile builds.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Moved blocks-configurators into journey-builder.&lt;/em&gt; These configurators were never meant to be used outside, so pulling them closer to where they belong simplified the dependency graph.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Moved blocks-renderers into journey-app.&lt;/em&gt; Renderers were core to the application itself, so consolidating them in the main app made the architecture more intuitive.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Deleted journey-utils and journey-elements.&lt;/em&gt; &lt;em&gt;Journey-utils&lt;/em&gt; was a very small package with some utilities that were moved to other packages. And &lt;em&gt;journey-elements _ were later replaced by _concorde-elements&lt;/em&gt;. You can read more about it in &lt;a href="https://dev.to/epilot/building-a-scalable-react-component-library-lessons-from-concorde-elements-kdi"&gt;this article written by my partner in crime.&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a painful step, but once the dust settled, the repo felt lighter and easier to reason about. We no longer had to worry about accidentally breaking other parts of the system when making small changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Standardize the Tooling&lt;/strong&gt;&lt;br&gt;
After trimming the dependencies, the next big challenge was our tooling. Different parts of the repo used different build systems, which slowed everyone down and made onboarding new developers a headache.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Phased out Craco, Tsup, and Tsdx by switching to Vite.&lt;/em&gt; These older tools had been added over time, each solving a narrow need. Vite gave us a unified, modern setup with faster builds and simpler configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Swapped Jest for Vitest&lt;/em&gt; — faster tests, modern setup. Jest had served us well, but it was slow and required custom patching to keep working. Vitest gave us near-instant feedback and worked seamlessly with Vite, making the dev experience far smoother.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By unifying the tooling, we not only sped up day-to-day work but also reduced cognitive load. Developers no longer had to remember which tool applied to which package — everything just worked the same way everywhere.&lt;/p&gt;

&lt;p&gt;This is how the "AFTER" setup looks:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxglsvhwnlvjy7jtopxd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxglsvhwnlvjy7jtopxd1.png" alt=" " width="800" height="411"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, the monorepo is now far more streamlined — there are significantly fewer dependencies crisscrossing between packages, and we’ve eliminated most of the variations in build tools. This makes the structure easier to understand, faster to work with, and much less fragile when changes are introduced. &lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;After the Restructuring: What We Learned&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;When the dust settled, it wasn’t just that the dependency graph was cleaner — we were thinking about the repo differently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Immediate Wins&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Changing things stopped feeling dangerous.&lt;/em&gt; Before, touching a shared package felt like pulling a brick from a Jenga tower. Now, fewer connections mean less risk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Builds and tests stopped feeling like a punishment.&lt;/em&gt; Vite’s dev server = instant feedback. Vitest shaved minutes off test runs. Devs started running tests more often just because they could.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Onboarding went from “ugh” to “okay.”&lt;/em&gt; New folks could get set up without learning the quirks of four bundlers first.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Slower Payoffs&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- Tooling swaps aren’t magic.&lt;/em&gt; Some Webpack plugins didn’t have a Vite equivalent, so we had to rethink features or drop them.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- Vitest exposed bad tests.&lt;/em&gt; Some “passing” tests were only passing thanks to Jest’s quirks. Painful, but worth fixing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trade-Offs &amp;amp; Reality Checks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- Not everything got unified.&lt;/em&gt; A couple of apps still run on legacy setups because migrating them wasn’t worth the risk — for now.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- Shared packages need rules.&lt;/em&gt; We now ask “does this really need to be shared?” before creating new ones.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;- Refactoring is never “done.”&lt;/em&gt; There is always room for improvement, we all know. that. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tips If You’re Thinking About Doing This&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Draw your dependency graph before you start — it’ll help convince others (and yourself) that the cleanup’s worth it.&lt;/li&gt;
&lt;li&gt;Expect setbacks. Some PRs will break things. That’s normal.&lt;/li&gt;
&lt;li&gt;Automate checks for unused or outdated packages — saves a ton of review time.&lt;/li&gt;
&lt;li&gt;Celebrate small wins. Removing the last Webpack config deserved cake.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Final Thoughts&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;This wasn’t a quick tidy-up — it was a half-year-long deliberate overhaul alongside working on other features. But it’s made a massive difference to how we work: faster builds, fewer “don’t touch that” areas, and a general feeling that the repo is ours again, not a beast we’re afraid of.&lt;/p&gt;

&lt;p&gt;If I had to wrap it all up in one bit of advice?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Keep it simple.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Every extra dependency, tool, or package you skip today is one less thing you’ll have to untangle in the future.&lt;/p&gt;

</description>
      <category>refactoring</category>
      <category>monorepo</category>
      <category>epilot</category>
      <category>frontend</category>
    </item>
    <item>
      <title>What To Expect When You Join Epilot</title>
      <dc:creator>kate astrid</dc:creator>
      <pubDate>Mon, 03 Feb 2025 13:24:46 +0000</pubDate>
      <link>https://forem.com/epilot/what-to-expect-when-you-join-epilot-1hc1</link>
      <guid>https://forem.com/epilot/what-to-expect-when-you-join-epilot-1hc1</guid>
      <description>&lt;p&gt;Hey you, awesome engineer.&lt;/p&gt;

&lt;p&gt;Let's imagine that you are joining epilot tomorrow. Would you like to have a sneak peek at your nearest future?&lt;/p&gt;

&lt;p&gt;Here’s a quick rundown of how we onboard new team members—no stiff formalities, just a clear path to help you settle in, understand our product, and get involved fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A Friendly Start&lt;/strong&gt;&lt;br&gt;
On the day one we’ll introduce you to your team lead and a dedicated onboarding buddy—think of them as your go-to guides for all things at epilot. Need pointers on our processes, product roadmap, or just want to figure out who to chat with about a certain topic? They’ve got you covered.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your First Week&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Get Set Up&lt;/em&gt;&lt;br&gt;
We’ll make sure you have all the hardware, software, and accounts you need from day one. We’ll give you a handy checklist so you can get everything in place without the guesswork. Of course, your onboa buddy is always there to help you with everything.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Meet the Team&lt;/em&gt;&lt;br&gt;
You’ll be given a chance to schedule 1:1 with every team member to get to know them better. Regardless of being remote-friendly company, we value real connections and friendly relationships, and make sure that everyone feels valued and supported.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Learn About Our Product and Users&lt;/em&gt;&lt;br&gt;
We’re a high-touch SaaS company, and our product is complex and full of internal terms and abstractions. It might feel overwhelming in the beginning, but don't worry, we've got you. You will be given lots of resources like recordings of product demos and docs about different topics about epilot. No rush—just learn at your own pace and ask all the questions you have.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Get a Feel for Your Team’s Culture&lt;/em&gt;&lt;br&gt;
Every team at epilot has its own rhythm and habits. Hop into Slack conversations, daily stand-ups, and team meetings to get a sense of what’s going on and how decisions get made. And feel free to share your ideas and suggestions - we are always eager to improve.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Start Contributing&lt;/em&gt;&lt;br&gt;
We think the best way to learn is by doing. Early on, you’ll probably tackle a small assignment to get familiar with our systems and processes. Consider it your first real taste of epilot in action.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Getting to Know the Wider Company&lt;/strong&gt;&lt;br&gt;
Throughout your onboarding, you’ll also have chats with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Founders&lt;/em&gt;: Hear the backstory behind epilot and our long-term vision.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Department Heads&lt;/em&gt;: Whether it’s Sales, Marketing, Engineering, or Product, each leader will fill you in on how their team supports our bigger goals. The idea is to see how all the pieces fit together and create the vibe.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Engineering &amp;amp; Product Leads&lt;/em&gt;: If you love diving into tech details, these sessions will give you insights into our architecture, tools, and future product plans.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Seeing the Product in Action&lt;/strong&gt;&lt;br&gt;
Our platform is built around microservices, but don’t worry if that’s new to you. We’ll walk you through the basics. We also encourage you to check out how our customers actually use epilot—like checking live customer feedbacks. It’s a great way to see what’s working and where we can improve.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Balance Between Work and Collaboration&lt;/strong&gt;&lt;br&gt;
At epilot, we keep things productive but also supportive:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Team Events&lt;/em&gt;: You’ll get invites to company-wide announcements, product demos, company events, and more.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Open Communication&lt;/em&gt;: Slack, shared docs, and frequent check-ins mean you’ll never be left guessing.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Culture Matters&lt;/em&gt;: We appreciate everyone’s contribution, whether it’s project-related or just sharing something fun. We are the team, and this is what matters.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Looking Ahead&lt;/strong&gt;&lt;br&gt;
After a few weeks, you’ll have a good handle on how things work here—and you’ll know who to reach out to when you need help. We’ll likely ask for your thoughts on onboarding so we can keep improving the process for the future.&lt;/p&gt;

&lt;p&gt;If this relaxed but purposeful approach resonates with you, we look forward to hearing from you. At epilot, we want every new hire to find their footing, make meaningful contributions, and grow in their role—without all the usual corporate fluff.&lt;/p&gt;

&lt;p&gt;Happy to have you on board ✨.&lt;/p&gt;

</description>
      <category>onboarding</category>
      <category>culture</category>
      <category>workplace</category>
      <category>hiring</category>
    </item>
    <item>
      <title>Have you heard about the anterior midcingulate cortex?</title>
      <dc:creator>kate astrid</dc:creator>
      <pubDate>Sun, 07 Jan 2024 20:45:07 +0000</pubDate>
      <link>https://forem.com/kate_astrid/have-you-heard-about-the-anterior-midcingulate-cortex-4dcd</link>
      <guid>https://forem.com/kate_astrid/have-you-heard-about-the-anterior-midcingulate-cortex-4dcd</guid>
      <description>&lt;p&gt;The anterior midcingulate cortex (aMCC) is an amazing area in the human brain that plays a vital role in decision-making, emotional processing, and even pain perception. More interestingly, it acts as a crucial network hub for those tough cost/benefit calculations that fuel our perseverance, willpower, and tenacity.&lt;/p&gt;

&lt;p&gt;Let's talk about facing challenges. Whether it's cracking complex equations or gearing up for a marathon, we all respond differently. Some might find the effort too overwhelming and step back, while others dig in their heels and push through without immediate rewards. This trait of persistence, increasingly spotlighted in research of the aCMM, correlates with better outcomes in health, academics, and career success.&lt;/p&gt;

&lt;p&gt;Now, here's where it gets really cool: when programming, especially during those head-scratching moments that we might not particularly enjoy, our aMCC gets super active. Ever found yourself in a coding conundrum, feeling frustrated to the point of wanting to quit? That's your aMCC in action, getting stronger. It's akin to facing a steep climb while running; challenging, maybe not enjoyable, but incredibly effective in building mental strength and resilience.&lt;/p&gt;

&lt;p&gt;So, remember, pushing through a tough coding problem does more than solve an issue on your screen. It's an aMCC workout, enhancing your brain's capacity to navigate complex tasks and manage emotions. It's a double win - improving your coding skills and boosting brain power, even when it feels tough at the moment =).&lt;/p&gt;

&lt;p&gt;Nice to know, right?&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Common Cognitive Biases That May Affect Us As Developers</title>
      <dc:creator>kate astrid</dc:creator>
      <pubDate>Sat, 16 Sep 2023 10:38:14 +0000</pubDate>
      <link>https://forem.com/kate_astrid/common-cognitive-biases-that-may-affect-us-as-developers-1gkm</link>
      <guid>https://forem.com/kate_astrid/common-cognitive-biases-that-may-affect-us-as-developers-1gkm</guid>
      <description>&lt;p&gt;As developers, we need to think straight to create solid, clean code. But hey, we're all human, and sometimes our brains make errors that can muddle up our decisions. Scientists call these errors cognitive biases. They can lead us down the wrong path, but they're actually part of how our brains handle the crazy amount of information we get all the time. Without these biases, it would be super tough to process everything logically.&lt;/p&gt;

&lt;p&gt;Still, it's important to keep these biases in check, as they can twist our view of reality and lead to not-so-great decisions. So, I thought I'd share some common biases that we, as developers, can bump into:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Confirmation Bias: We might lean towards solutions or tech that fit with what we already know or believe. This can stop us from picking up something that could be even better.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Anchoring Bias: We sometimes stick too much to the first piece of info we get (the "anchor") when we're making decisions. For instance, we might guess how complex a task is based on something similar we've done before, even if it's not really the same thing.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dunning-Kruger Effect: If we're not that experienced, we might think we're better at coding than we really are. This can make us too confident and cause mistakes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Survivorship Bias: We might only focus on the projects or tech that did well and ignore the ones that flopped. This can make us too optimistic about how likely something is to succeed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Not Invented Here (NIH) Syndrome: Sometimes we might dismiss solutions made by others and end up making new tools or frameworks when we could just use what's already there.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Recency Bias: We might pay too much attention to things that happened recently, like a bug we just ran into. This could skew our view of how reliable a project or tech really is.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So there you have it, folks – a quick rundown of some of the mental trip-ups we might face as developers. It's essential to remember that we're all susceptible to these biases, no matter how skilled or experienced we are. By being aware of them, we can work smarter, make better decisions, and create code that really shines. Keep coding, stay aware, and let's build great stuff together!&lt;/p&gt;

</description>
      <category>rationality</category>
      <category>cognitivebiases</category>
      <category>bias</category>
    </item>
    <item>
      <title>Ten Red Flags That Obstruct Systems Thinking</title>
      <dc:creator>kate astrid</dc:creator>
      <pubDate>Sat, 16 Sep 2023 10:33:59 +0000</pubDate>
      <link>https://forem.com/kate_astrid/ten-obstacles-to-systems-thinking-540l</link>
      <guid>https://forem.com/kate_astrid/ten-obstacles-to-systems-thinking-540l</guid>
      <description>&lt;p&gt;Hey cool people! 👋&lt;/p&gt;

&lt;p&gt;Today I want to share with you a piece of useful knowledge about systems thinking that helps me analyze systems and their connection to each other and allows me to improve my understanding of any process I interact with, be it companies, code bases, or even human bodies.&lt;/p&gt;

&lt;p&gt;In general, systems thinking is an approach to understanding and solving complex problems by looking at the bigger picture. Instead of focusing on individual parts or events, systems thinking considers how those parts are interconnected and how they impact each other. This approach helps to identify the root causes of problems and create long-lasting solutions, rather than just addressing the symptoms. In simple terms, systems thinking is like looking at a whole forest rather than just individual trees, recognizing how everything is connected and influences each other.&lt;/p&gt;

&lt;p&gt;There are ten statements — red flags — that act as obstacles to systems thinking:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;“Let’s fix it quick!”
While systems thinking doesn't demand slow problem-solving, hastily jumping into solutions without understanding the problem is counterproductive.&lt;/li&gt;
&lt;li&gt;“Just put a Band-Aid on it.”
Temporary fixes can hide symptoms while the underlying issue continues to harm the organization.&lt;/li&gt;
&lt;li&gt;“We need the budget finalized!”
Focusing on budgets and deadlines promotes linear thinking, moving away from systems thinking principles.&lt;/li&gt;
&lt;li&gt;“We must respond right away!”
Rushing to address problems encourages linear thinking, while calmly analyzing the situation fosters systematic thinking.&lt;/li&gt;
&lt;li&gt;“Who cares?”
Apathy hinders creativity and problem-solving, preventing organizational growth and effective solutions.&lt;/li&gt;
&lt;li&gt;“We need more information.”
Collecting data is important, but linear thinking arises when expecting data alone to solve problems without proper analysis and action.&lt;/li&gt;
&lt;li&gt;“You are overthinking things.”
Disagreements may be seen as overthinking. Systems thinking requires stretching beyond comfort zones and embracing complex solutions.&lt;/li&gt;
&lt;li&gt;“Forget the rest of the organization.”
Linear thinkers prioritize personal needs with win-lose solutions. Systems thinking seeks win-win solutions that benefit everyone.&lt;/li&gt;
&lt;li&gt;“We don’t want any conflict.”
Avoiding conflict at all costs can prevent addressing real problems. Confronting conflicts is necessary for effective problem-solving.&lt;/li&gt;
&lt;li&gt;“We will do it this way.”
Imposing one's will stifles creativity, innovation, and collaboration, hindering effective problem-solving and growth within the organization.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I truly believe that systems thinking can introduce new perspectives, reveal hidden problems if they exist, and help existing processes to thrive and prosper 💃 .&lt;br&gt;
Lets's discuss it. Have you tried this approach? 👀&lt;/p&gt;

</description>
      <category>rationality</category>
      <category>systemsthinking</category>
      <category>cognitivebiases</category>
    </item>
    <item>
      <title>How to Maintain the Performance of a React Application on a Daily Basis</title>
      <dc:creator>kate astrid</dc:creator>
      <pubDate>Wed, 06 Sep 2023 07:42:59 +0000</pubDate>
      <link>https://forem.com/epilot/how-to-maintain-the-performance-of-a-react-application-on-a-daily-basis-304k</link>
      <guid>https://forem.com/epilot/how-to-maintain-the-performance-of-a-react-application-on-a-daily-basis-304k</guid>
      <description>&lt;p&gt;I'm a fast-paced person: I eat quickly, walk briskly, and make decisions in a snap. What I can't stand, though, is a slow app — especially one I'm working on. So, I always find myself compelled to scrutinise its performance: examining how many times it re-renders, the size of the DOM, and the speed of user interactions, among other things. Armed with this data, I incrementally improve the app's performance by refining the codebase in a targeted way.&lt;/p&gt;

&lt;p&gt;Now, I'd like to share some strategies that could help enhance your app's performance:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Be Mindful of the Hooks You Use in Each Component&lt;/strong&gt;: From my perspective, this is crucial. &lt;code&gt;useState&lt;/code&gt; and &lt;code&gt;useEffect&lt;/code&gt; are the most commonly used hooks, but sometimes they can be eliminated with a bit of refactoring, without sacrificing functionality. Fewer hooks mean fewer re-renders, which in turn means a faster app. Other noteworthy hooks are &lt;code&gt;useCallback&lt;/code&gt; and &lt;code&gt;useMemo&lt;/code&gt;, which memoize values, storing them in memory. On a larger scale, this can have an impact on performance. The same goes for &lt;code&gt;React.memo()&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Simple example:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Imagine you have a component that tracks a user's first name, last name, and age. A naive approach could be to declare three separate &lt;code&gt;useState&lt;/code&gt; hooks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const UserProfile = () =&amp;gt; {
  const [firstName, setFirstName] = useState('');
  const [lastName, setLastName] = useState('');
  const [age, setAge] = useState(0);

  // Multiple function calls to update the user profile
  const updateUserProfile = () =&amp;gt; {
    setFirstName('John');
    setLastName('Doe');
    setAge(30);
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{`${firstName} ${lastName}`}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Age: {age}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={updateUserProfile}&amp;gt;Update Profile&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every time each of those hooks is called, the component will re-render, even if it happens simultaneously. We could condense this into a single &lt;code&gt;useState&lt;/code&gt; by using an object:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const UserProfile = () =&amp;gt; {
  const [user, setUser] = useState({
    firstName: '',
    lastName: '',
    age: 0,
  });

  // Single function call to update the user profile
  const updateUserProfile = () =&amp;gt; {
    setUser({
      firstName: 'John',
      lastName: 'Doe',
      age: 30,
    });
  };

  return (
    &amp;lt;div&amp;gt;
      &amp;lt;h1&amp;gt;{`${user.firstName} ${user.lastName}`}&amp;lt;/h1&amp;gt;
      &amp;lt;p&amp;gt;Age: {user.age}&amp;lt;/p&amp;gt;
      &amp;lt;button onClick={updateUserProfile}&amp;gt;Update Profile&amp;lt;/button&amp;gt;
    &amp;lt;/div&amp;gt;
  );
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, we have only one hook, and only one re-render when the hook is called. Bingo.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Minimise the Number of DOM Nodes&lt;/strong&gt;: I always ask myself, "Can this HTML tag be safely removed?" If the answer is yes, I remove it. Fewer nodes lead to better performance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Simple example:&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you find the code using empty &lt;code&gt;div&lt;/code&gt;s solely for styling purposes, consider using CSS Grid or Flexbox to achieve the same layout, thus reducing the number of DOM nodes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Before
&amp;lt;div className="wrapper"&amp;gt;
  &amp;lt;div className="innerWrapper"&amp;gt;
    &amp;lt;Component /&amp;gt;
  &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;

// After
&amp;lt;div className="optimizedWrapper"&amp;gt;
  &amp;lt;Component /&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Favor Class-Based Styling Over Inline Styles&lt;/strong&gt;: Inline styles are considered new objects on each render, which can make React think something has changed, triggering unnecessary re-renders and affecting performance. It's also worth noting that maintaining styles in separate files helps keep the styling consistent.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Simple example:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Before
&amp;lt;div style={{ display: 'flex' }}&amp;gt;

// After
&amp;lt;div className='container'&amp;gt;

// In a separate css file: 
.container: {
  display: flex
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prefer Simple &lt;code&gt;div&lt;/code&gt;s to &lt;code&gt;Box&lt;/code&gt; from Material UI or Similar UI Libraries:&lt;/strong&gt; Native HTML elements generally offer better performance because they don't carry the overhead of additional React components, including lifecycle methods and context consumption.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Simple example:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Before
&amp;lt;Box p={2}&amp;gt;

// After
&amp;lt;div className="container"&amp;gt;

// In a separate css file: 
.container: {
  padding: '2px'
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Prefer Conditional Classes to Conditional Styles in &lt;code&gt;makeStyles&lt;/code&gt; from Material UI or Similar UI Libraries:&lt;/strong&gt; Using predefined classes that are toggled based on conditions can be more performant, as it doesn't generate new classes at runtime. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Simple example:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Before
const useStyles = makeStyles({
  root: {
    backgroundColor: props =&amp;gt; props.isActive ? 'blue' : 'white',
  },
});

// After
const className = isActive ? 'active' : 'inactive';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Opt for Functional Components:&lt;/strong&gt; There are several compelling reasons for this. First, functional components are easier for build tools like Webpack to optimize through "tree shaking," which only includes the code that's actually being used in the final bundle. Second, functional components often result in a smaller component tree and fewer lifecycle methods, allowing React's diffing algorithm to make quicker updates to the DOM. Lastly, functional components use less memory than class components, which is especially beneficial in environments where memory is limited.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Simple example:&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Before
class MyComponent extends React.Component {
  state = { /* ... */ };
  componentDidMount() { /* ... */ }
  render() { /* ... */ }
}

// After
const MyComponent = () =&amp;gt; {
  const [state, setState] = useState(/* ... */);
  useEffect(() =&amp;gt; { /* ... */ }, []);
  return (/* ... */);
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By giving these tips a go and making them a regular part of your coding routine, you're not just on the path to a speedier React app, but you're also gonna make things a whole lot smoother for your users. &lt;br&gt;
Let's create better apps together =).&lt;/p&gt;

</description>
      <category>react</category>
      <category>performance</category>
      <category>css</category>
    </item>
  </channel>
</rss>
