<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
  <title>Jessie&#39;s Portfolio</title>
  <subtitle>I am writing about my experiences as a naval navel-gazer.</subtitle>
  <link href="https://jessieheald.com/feed.xml" rel="self" />
  <link href="https://jessieheald.com/" />
  <updated>2026-01-20T15:30:30Z</updated>
  <id>https://jessieheald.com/</id>
  <author>
    <name>Jessie Heald</name>
  </author>
  <entry>
    <title>Agile code, refactoring, and FOSS projects</title>
    <link href="https://jessieheald.com/blog/agile-code-foss-and-context-switching/" />
    <updated>2025-11-12T00:00:00Z</updated>
    <id>https://jessieheald.com/blog/agile-code-foss-and-context-switching/</id>
    <content type="html">&lt;p&gt;Developing 11tyCMS has taught me so much about the impact of agile code on productivity. In early alpha, the code was inconsistent and difficult to follow. There were many quirks, all causing frequent bugs, slowing down debugging and draining  my energy. It was starting to put me off working on it.&lt;/p&gt;
&lt;p&gt;tedt  &lt;/p&gt;
&lt;p&gt;I spent so much time in &amp;quot;MVP mode&amp;quot;, I lost sight of the quality I was aiming for: adaptable code that worked with me, not against me. But, knowing I&#39;m opening the source code soon motivated me to refactor. I wanted a code base that other developers could work with, without worrying they&#39;d struggle to understand everything. A FOSS project can only be as good as the contributors you&#39;re lucky enough to have!&lt;/p&gt;
&lt;h2 id=&quot;knowing-when-to-refactor&quot;&gt;Knowing when to refactor&lt;/h2&gt;
&lt;p&gt;None of this is to say working toward an MVP is bad. On the contrary: as a kid, I used to &lt;em&gt;start&lt;/em&gt; with achieving perfection, getting the perfect code... Thing is, this is literally impossible when you&#39;re starting from nothing. Worse yet? I never finished any projects. I got so obsessed with trying to create the perfect end product from zero that it froze me. You have no idea what the parameters of your problems are until you&#39;ve got an MVP out the door. Once everything functions, you have a better idea what the scope of your variables, functions and files should be. At this point, you can think about rewriting what you&#39;ve done to be more elegant, reusable and understandable.&lt;/p&gt;
&lt;p&gt;There comes a stage &lt;em&gt;after&lt;/em&gt; you&#39;ve reached MVP where inspiration floods in for new features. You get excited, there&#39;s so many ideas. You get to work, let&#39;s implement that new feature! But you find that your code is a little inflexible and difficult to read. It&#39;s not impossible though, it just takes more effort. You spend a few hours implementing this new feature, maybe adding a few extra quirks to the code to make it work. The new feature works! The code could use a refactor. But time is short and it&#39;s a side FOSS project after all.  A week goes by, you get busy with your job. You have less energy to work on your project now, the code&#39;s rigidity and quirks kinda puts you off. It feels like you&#39;re fighting with your code, and you just... Give up for a bit.&lt;/p&gt;
&lt;p&gt;3 months pass, work has died down a little and it feels like you have more time and energy for your beloved FOSS project. So you fire up your IDE, and start working on yet &lt;em&gt;another&lt;/em&gt; feature. You&#39;re really excited, there&#39;s so many ideas to work on! But then you realize what you left behind all those months ago: inflexible code that&#39;s difficult to read, with quirks bolted on top to implement the other features. It becomes clear: you can&#39;t implement these features until you&#39;ve refactored the code. Not without wasting precious time and energy, which are already at a premium for side projects. It&#39;s at this point you start thinking about how you can refactor.&lt;/p&gt;
&lt;h2 id=&quot;the-power-of-refactoring&quot;&gt;The power of refactoring&lt;/h2&gt;
&lt;p&gt;The problem with the refactoring phase is that... It depends on how late you left it. For many reasons, the MVP stage and all the quirks that come with it may have &lt;em&gt;well&lt;/em&gt; overstayed its welcome. If your project is still small and there&#39;s not too many files and lines of code to change, its not too painful. But if its a bigger project? The devil you know starts looking very alluring. Particularly with all the friction involved with restructuring everything, &lt;em&gt;and&lt;/em&gt; relearning your muscle memory to work with the refactor. Thankfully though, my relentless drive for writing maintainable and clear code makes it difficult to &lt;em&gt;NOT&lt;/em&gt; do this early on. &lt;/p&gt;
&lt;p&gt;A good example of this is my Electron project: &lt;a href=&quot;https://11tycms.com&quot;&gt;11tyCMS&lt;/a&gt;. It was a project I started on holiday, I rarely had the energy or time to work on it outside of work, as is often the case for many FOSS project maintainers. This also contributed to a vicious cycle. The time I can spend on it is very sporadic, and refactoring looked like such a huge task, it felt difficult to justify. But I hit a wall: there was &lt;em&gt;that&lt;/em&gt; feature, one I literally couldn&#39;t implement unless I did some major refactoring. So I made a start... I began restructuring how I did IPC in my Electron app.&lt;/p&gt;
&lt;p&gt;In Electron, your app is split in two: you have the &amp;quot;main process&amp;quot; and the &amp;quot;renderer&amp;quot;. Main is where all the Node JS code is, the renderer is where the &amp;quot;browser&amp;quot; side of things are. IPC is the mechanism allowing the main process and the renderer to communicate with each other. So in 11tyCMS&#39;s case, this allows me to call NodeJS functions from my React code.&lt;/p&gt;
&lt;p&gt;In Electron, you have to register every function if you wanted it exposed via IPC. You register it under a channel in the main process, and then you expose it to your renderer via the &lt;code&gt;preload&lt;/code&gt; file. Each time you have to refer to your functions perfectly, with the correct channel name, and all the correct arguments (baring in mind that, in preload, you have to get the order right with &lt;code&gt;event&lt;/code&gt; being the first argument). This made creating new functions a &lt;em&gt;nightmare&lt;/em&gt;. I would frequently mess up the order of arguments, forget channel names. This meant constantly switching between different files to confirm I was getting things right, that there were no typos. This needed to change!&lt;/p&gt;
&lt;p&gt;In the end? created a new file: &lt;code&gt;functions.js&lt;/code&gt; . In here, I import all the files that have functions I want to expose to the renderer (you just need to export your functions in an object), and I pass them into an object called &lt;code&gt;functionsByChannels&lt;/code&gt; each key being the name of the files I imported. Then, I have a for loop that checks for the names of each function in these imports: if it&#39;s name starts with an underscore, its a private function to be kept to the main process. Otherwise? put it in the &lt;code&gt;exposedFunctions&lt;/code&gt; object that the functions file exports. In the end? I end up with an object that has consistent channel names based on the file names, along with the correct consistent function names and argument orders:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; files &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./functions/files&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;import&lt;/span&gt; site &lt;span class=&quot;token keyword&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;./functions/site&#39;&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; exposedFunctions &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;exposeChannelFunction&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;func&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channelName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    exposedFunctions&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;channelName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; func&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; functionsByChannels &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    files&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt;
    site
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; channelParentName &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; functionsByChannels&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; childFuncKey &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; functionsByChannels&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;channelParentName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;token keyword&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;childFuncKey&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;_&quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;token keyword&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
        console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&quot;Registering &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; childFuncKey&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&quot; under &quot;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channelParentName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;token function&quot;&gt;exposeChannelFunction&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;functionsByChannels&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;channelParentName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;childFuncKey&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token template-string&quot;&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;channelParentName&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;childFuncKey&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;`&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;token keyword&quot;&gt;default&lt;/span&gt; exposedFunctions&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, in the main process, all I have to do is import the &lt;code&gt;functions.js&lt;/code&gt; file, and register the functions to IPC:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; channelName &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; exopsedFunctions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
    ipcMain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;handle&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;exopsedFunctions&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, we&#39;re now ready to expose these to the renderer:&lt;/p&gt;
&lt;pre class=&quot;language-javascript&quot; tabindex=&quot;0&quot;&gt;&lt;code class=&quot;language-javascript&quot;&gt;&lt;span class=&quot;token keyword&quot;&gt;let&lt;/span&gt; api &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; channelName &lt;span class=&quot;token keyword&quot;&gt;in&lt;/span&gt; exposedFunctions&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  console&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;registering function&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; exposedFunctions&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token string&quot;&gt;&#39;with channel&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channelName&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  api&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;exposedFunctions&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;ipcRenderer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;token keyword&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;token function-variable function&quot;&gt;registerApiFunction&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;func&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; channelName&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;{&lt;/span&gt;
  api&lt;span class=&quot;token punctuation&quot;&gt;[&lt;/span&gt;func&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;name&lt;span class=&quot;token punctuation&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token parameter&quot;&gt;&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token operator&quot;&gt;=&gt;&lt;/span&gt;ipcRenderer&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;invoke&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;args&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  ipcMain&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;handle&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;channelName&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; func&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
  contextBridge&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exposeInMainWorld&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;api&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; api&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;token punctuation&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;token operator&quot;&gt;...&lt;/span&gt;

contextBridge&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;exposeInMainWorld&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token string&quot;&gt;&#39;api&#39;&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;,&lt;/span&gt; api&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;  &lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And bam. Now all I need to do is call: &lt;code&gt;window.api.functionName&lt;/code&gt; in my renderer, and I have what I need!&lt;/p&gt;
&lt;p&gt;This tweak changed &lt;em&gt;everything&lt;/em&gt;. Because now, all I needed to do was add a function to a file&#39;s export to have it exposed to the renderer, adding new features was WAY faster. Development picked up pace again, I had more energy to work on it, things took less time and it felt &lt;em&gt;good&lt;/em&gt; to work with. With these energy gains, I had more motivation to do even more refactoring... So I implemented Zustand into the React side of the app.&lt;/p&gt;
&lt;p&gt;Zustand is by far my favorite state management library for React. Its so lightweight and simple, but its impact is profound. No more drilling props through 5 different components, only to lose track of where they originated and getting weird bugs as a result. Just centralized store files for each type of data, each one integrating beautifully with this IPC system I&#39;ve built up. Upon implementing this, the React side of things became joyful to work with. Everything feels so clean, and easy to work with now. If I have a problem with data? I&#39;m not sifting through 10 different component files to find the culprit. Again, giving me even &lt;em&gt;more&lt;/em&gt; energy and time to work on my project. So I began working on routing, which again, made it even better to work with.&lt;/p&gt;
&lt;p&gt;Can you see the domino effect a well timed and placed refactor can have on a project? Especially for FOSS. When time and energy is so limited, you want a code base that works &lt;em&gt;with you&lt;/em&gt; not against you. The easier it is to work on, the less energy it will take to work with. Better yet? New contributors will have a much easier time adding new features and donating their time for bug fixes. Everyone wins!&lt;/p&gt;
&lt;p&gt;This isn&#39;t to say that the code I have now is perfect. Far from it, not even sure if that&#39;s possible! But there&#39;s one thing I&#39;m sure of: the quality of my code base is no longer a barrier to adding new features, and I think that&#39;s a healthy sign of a good refactor.&lt;/p&gt;
</content>
  </entry>
  <entry>
    <title>What 3 years and 1000+ hours of mentoring taught me</title>
    <link href="https://jessieheald.com/blog/what-3-years-of-mentoring-has-taught-me/" />
    <updated>2026-01-20T15:30:30Z</updated>
    <id>https://jessieheald.com/blog/what-3-years-of-mentoring-has-taught-me/</id>
    <content type="html">&lt;p&gt;I started my tutoring business in 2020. The lockdowns were in full swing, lots of people were using the downtime to switch careers. This got me thinking: I should start a business teaching people to code. When I was 14, I taught my brother&#39;s friend who did web design at uni how to code. It was an awesome experience and taught me so much. &lt;/p&gt;
&lt;p&gt;I started with a very diverse client base: a range of skill levels from total beginners to mid and senior developers who needed an extra brain to think with. It made me realise how many different skills are involved in mentoring (to name a few!):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Reducing complex problem solving into small steps, making them more approachable&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Teaching with empathy and respect for the learner. Everyone has a different learning styles and experiences, so adapting your method to the person is key.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Walking your student through your thinking process, and teaching them to show theirs. This is 90% of teaching the core coding skill: problem solving.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;what-i-learnt-over-my-1000-hours-of-teaching&quot;&gt;What I learnt over my 1000+ hours of teaching&lt;/h2&gt;
&lt;p&gt;Working with each skill level taught me something new. I firmly believe that everyone from all backgrounds and skill levels has something to teach me, and this has proven it!&lt;/p&gt;
&lt;h3 id=&quot;teaching-beginners&quot;&gt;Teaching beginners&lt;/h3&gt;
&lt;p&gt;As a senior, you take your knowledge for granted: you understand variables, for loops and the difference between arrays and objects. Someone new? They know little to nothing. But, you get to teach them the fundamentals, and watch as their understanding grows. They start off overwhelmed, but as you help build their understanding, they take on more and start experimenting outside their comfort zone.&lt;/p&gt;
&lt;p&gt;Teaching beginners makes you think about how you code and &lt;em&gt;why&lt;/em&gt;. A beginner will look at 2 blocks of code that do the same thing, and ask why one approach over the other? You get to teach them to think about they differ, and why one might be better. Another way of doing this was by demonstrating a mistake, and getting them to point out what might be wrong with it, helping them grow their problem solving muscle.&lt;/p&gt;
&lt;p&gt;Teaching people to walk through and spot problems, is building the skill central to coding: problem solving. My students have learnt so much from me by pointing out mistakes in &lt;em&gt;my&lt;/em&gt; code, and walking me through &lt;em&gt;why&lt;/em&gt; it won&#39;t behave the way it should. This has taught me the importance of showing colleagues that their contributions are important, because you never know what others will spot that you won&#39;t.&lt;/p&gt;
&lt;p&gt;It&#39;s not just problem solving or debugging, either... It&#39;s the art of project management. How do you take an idea and turn it into code? How do you make it production ready? Some beginners get so trapped in perfectionism, that they don&#39;t start their passion project. I found success in helping them to develop an MVP, &lt;em&gt;then&lt;/em&gt; figure out improvements! After all, the more projects someone can take on (and finish!) the faster their skills and confidence will build. &lt;/p&gt;
&lt;p&gt;A lot of them also forget learning to learn! Learning is a poorly taught art, one that few schools teach their pupils. My first lessons involved teaching students evidence based studying techniques: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Work smarter, not harder: use the &lt;a href=&quot;https://en.wikipedia.org/wiki/Pomodoro_Technique&quot;&gt;Pomodoro Technique&lt;/a&gt;, studying in 30 minute blocks. Rest well and let your brain digest what you&#39;ve learnt.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use the &lt;a href=&quot;https://en.wikipedia.org/wiki/Learning_by_teaching#Plastic_platypus_learning&quot;&gt;Feynman technique&lt;/a&gt;: explain what you&#39;re learning back to others in the simplest of terms to consolidate your learning.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Leverage &lt;a href=&quot;https://en.wikipedia.org/wiki/Spaced_repetition&quot;&gt;spaced repetition&lt;/a&gt;! Revise what you&#39;ve learnt in increasing gaps, take advantage of shallowing your &lt;a href=&quot;https://en.wikipedia.org/wiki/Forgetting_curve&quot;&gt;forgetting curve&lt;/a&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Teaching beginners, I learnt that programming isn&#39;t just languages or syntax. They&#39;re irrelevant. What coding truly is, is problem solving, project management and communication skills. Beginners can get so caught up in syntax and learning the language, that they forget the true skills are all the above.&lt;/p&gt;
&lt;h3 id=&quot;teaching-mid-level&quot;&gt;Teaching mid-level&lt;/h3&gt;
&lt;p&gt;Teaching mid-level developers is awesome. They understand fundamentals, now they&#39;re applying them autonomously. They just need support with implementation: what tools? How do we make it scaleable? Which infrastructure choices are best?&lt;/p&gt;
&lt;p&gt;I love working with them on projects, and guiding them and suggesting different approaches. Seeing them figure out which ones are best for them and their project is an awesome sight, you&#39;re watching them build the experiences they need to build reliable solutions in realtime!&lt;/p&gt;
&lt;p&gt;Working with mid levels showed me that: if your fundamentals aren&#39;t sound, you&#39;ll struggle to apply your skills to new challenges. It also opened my eyes to how we should teach developers about sustainability:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Are you going to understand this code in 2 weeks time? Can others understand it?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is it performant?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Does it work reliably? &lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Is the code self documenting?&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are so important, often forgotten parts of the learning process. Because in my experience if you skip any of these, you end up stuck. Your bottleneck becomes the fact you&#39;re not writing readable code, or that its not self documenting. &lt;/p&gt;
&lt;h2 id=&quot;transferrable-skills&quot;&gt;Transferrable skills&lt;/h2&gt;
&lt;p&gt;All these experiences have enriched communication skills. It&#39;s driven me to show my thinking to a range of different skill levels and backgrounds, helping me describe my thought process in an accessible way. &lt;/p&gt;
&lt;p&gt;It&#39;s also helped me learn about project management. I&#39;ve helped so many students manage their projects from start to finish, even starting businesses with them! &lt;/p&gt;
&lt;p&gt;It&#39;s taught me about common pitfalls: Working with so many developers has taught me to spot common mistakes that lead to vulnerabilities, and how to avoid them. &lt;/p&gt;
&lt;p&gt;But most of all? It&#39;s taught me the importance of leading with empathy and patience. People don&#39;t like to feel incompetent, they don&#39;t like feeling frustrated, and so many have fraught education experiences. I&#39;ve learnt to adopt a teaching style that I hope centers patience, kindness and curiosity. All essential qualities for fostering a good learning experience, ones I wish I had from my mentors growing up.&lt;/p&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;When I started tutoring, I thought it&#39;d be a nice side gig, with supplemental income. But it turned into working with people from across the globe, from America, to Dubai. With a diverse range of skills and backgrounds, each having something to bring to the table.&lt;/p&gt;
&lt;p&gt;I&#39;m so grateful for these experiences. I&#39;m so proud to have kickstarted careers and to have helped setup my student&#39;s startups in my time tutoring. Here&#39;s what a few of them had to say:&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://jessieheald.com/img/BYwKm8L5-0-1418.avif 1418w&quot; sizes=&quot;100vw&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://jessieheald.com/img/BYwKm8L5-0-1418.webp 1418w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://jessieheald.com/img/BYwKm8L5-0-1418.png&quot; alt=&quot;5 star review, saying: &amp;quot;They&#39;re one of the best sellers that I have ever met on Fiverr. Very smart, considerate, professional and helpful. I would recommend them to anyone who&#39;s interested in learning web development.&amp;quot;&quot; width=&quot;1418&quot; height=&quot;436&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://jessieheald.com/img/LIqqvCLVUW-1418.avif 1418w&quot; sizes=&quot;100vw&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://jessieheald.com/img/LIqqvCLVUW-1418.webp 1418w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://jessieheald.com/img/LIqqvCLVUW-1418.png&quot; alt=&quot;5 star review, saying: &amp;quot;Excellent young professional. Helped me out with concepts that I struggled the most as well as tailored his lesson to my needs. Definitely ordering again. Highly recommended!&amp;quot;&quot; width=&quot;1418&quot; height=&quot;436&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
&lt;p&gt;&lt;picture&gt;&lt;source type=&quot;image/avif&quot; srcset=&quot;https://jessieheald.com/img/nWU1aoZ4bi-1418.avif 1418w&quot; sizes=&quot;100vw&quot;&gt;&lt;source type=&quot;image/webp&quot; srcset=&quot;https://jessieheald.com/img/nWU1aoZ4bi-1418.webp 1418w&quot; sizes=&quot;100vw&quot;&gt;&lt;img loading=&quot;lazy&quot; decoding=&quot;async&quot; src=&quot;https://jessieheald.com/img/nWU1aoZ4bi-1418.png&quot; alt=&quot;5 star review, saying: &amp;quot;Jessie is an excellent react tutor, very knowledgeable on the subject and was able to explain it in a way I could understand. I highly recommend working with them!&amp;quot;&quot; width=&quot;1418&quot; height=&quot;388&quot;&gt;&lt;/picture&gt;&lt;/p&gt;
</content>
  </entry>
</feed>