<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Building web in 2026</title><description>kalabro.tech by Kate Marshalkina</description><link>https://kalabro.tech/</link><item><title>My tech year in review (2025)</title><link>https://kalabro.tech/my-tech-year-in-review-2025/</link><guid isPermaLink="true">https://kalabro.tech/my-tech-year-in-review-2025/</guid><description>AI, conferences, and DDD rants to end the year</description><pubDate>Tue, 30 Dec 2025 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;As AI tools improve, many programming activities seem to move faster. This year, I merged more pull requests, touched more repositories, resolved more bugs, paid down more tech debt, built more prototypes, and explored more new tools than ever before.&lt;/p&gt;
&lt;p&gt;In comparison, some other things felt surprisingly slow. In this post, I want to reflect on them.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#conferences&quot;&gt;Conferences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#blogging&quot;&gt;Blogging&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#reading&quot;&gt;Reading&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#domain-driven-design&quot;&gt;Domain-Driven Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#whats-next&quot;&gt;What’s next&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conferences&lt;/h2&gt;
&lt;p&gt;Before I fully switched to JavaScript tech stack in 2023, I regularly attended Drupal conferences and meetups, often as a speaker. I enjoy the creative challenge of presenting to a like-minded crowd and learn a ton while preparing.&lt;/p&gt;
&lt;p&gt;I’ve started applying to JS conferences in 2023 with several proposals from software architecture to interviewing tips to web performance. At first, it was all rejections. In 2024, I finally got an approval for a lightning talk at React Alicante. And in 2025, I had the pleasure of speaking at five (!) conferences:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;React Paris (&lt;a href=&quot;/react-paris-2025&quot;&gt;my review&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;CityJS London (&lt;a href=&quot;/cityjs-london-2025&quot;&gt;my review&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;React Summit&lt;/li&gt;
&lt;li&gt;BcnDev&lt;/li&gt;
&lt;li&gt;React Alicante (&lt;a href=&quot;/react-alicante-2025&quot;&gt;my review&lt;/a&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Interestingly, all conferences selected the same talk, “At the top of the pyramid: Playwright testing at scale”. Indeed,
my 2024 was all about testing, and I learned Playwright quite well.&lt;/p&gt;
 &lt;a href=&quot;https://youtube.com/watch?v=OYZNTPp04hw&quot;&gt; &lt;span&gt;Play&lt;/span&gt; &lt;/a&gt;  
&lt;p&gt;Building a speaker profile, growing my network, developing talk ideas, rehearsing, and physically traveling to conference locations all takes a lot of time and energy.&lt;/p&gt;
&lt;h2&gt;Blogging&lt;/h2&gt;
&lt;p&gt;Since I was busy with conferences, I didn’t have enough energy left for blogging. For me, the most intense part of writing is thinking, reflecting, and discovering insights from my own experiences. It takes time and patience.&lt;/p&gt;
&lt;p&gt;Proofreading and adding interactivity became much easier, though. I wanted to make &lt;a href=&quot;/balancing-coupling-in-software-design-book&quot;&gt;“Balancing Coupling in Software Design” (book review)&lt;/a&gt; easier to read, so with AI assistance, I migrated my blog to Astro and built interactive quiz components.&lt;/p&gt;
&lt;p&gt;To keep this blog alive while on “writing holidays”, I’ve added a quick &lt;a href=&quot;/weekly&quot;&gt;“This Week I Learned”&lt;/a&gt; section.&lt;/p&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;AI gives accurate, personalized answers to dozens of my questions daily. That’s great for getting the task at hand done. But these effortless interactions rarely leave me with deep understanding. For that, I still prefer high-quality, curated content written by domain experts.&lt;/p&gt;
&lt;p&gt;A couple of examples from healthcare analytics, since that’s what I’ve been exploring lately:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ohdsi.github.io/TheBookOfOhdsi/&quot;&gt;The Book of OHDSI&lt;/a&gt; - basics of healthcare analytics (focused on the OMOP Common Data Model)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://r4ds.hadley.nz/&quot;&gt;R for Data Science&lt;/a&gt; - a great intro to how scientists think and work in R&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Domain-Driven Design&lt;/h2&gt;
&lt;p&gt;I’ve been practicing DDD to various extents since discovering it in 2022 (&lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book&quot;&gt;“Learning Domain-Driven Design” - the software architecture &lt;span&gt;🐒&lt;/span&gt; book that makes sense&lt;/a&gt;). Instead of sharing how amazing and impactful it is, I want to reflect on some challenges I’ve faced so far.&lt;/p&gt;
&lt;p&gt;In 2024, I joined Aetion (now part of Datavant) to work on a complex healthcare business domain.
I followed my own advice from &lt;a href=&quot;/onboarding-yourself&quot;&gt;“Onboarding yourself as a Senior Software Engineer”&lt;/a&gt;, got promoted to Staff Engineer, worked in two teams, and contributed to both code and culture in several meaningful ways. Yet, I’m still figuring out the business domain.&lt;/p&gt;
&lt;p&gt;Recently, I spent a few months redesigning a drug analytics module. While my official task was to conduct a technical design, most of the time was spent figuring out what the hell we were trying to build. It took several months of using the product, reading documentation, and talking to experts before I could write a first draft. Not exactly the timeline you’d expect in the age of AI. Of course, I used AI to support my explorations, but the core thinking was on me and my colleagues.&lt;/p&gt;
&lt;p&gt;This is the cost of building something unique in the “core” business domain, the one that brings companies their competitive advantage.&lt;/p&gt;
&lt;p&gt;While Domain-Driven Design is supposed to simplify this process, in practice it’s not always that easy.&lt;/p&gt;
&lt;h4&gt;DDD Obstacle 1: The name is overloaded&lt;/h4&gt;
&lt;p&gt;Most backend developers are aware of the Domain-Driven Design methodology. Some practiced tactical DDD focused on aggregates and value objects. Lucky ones participated in EventStorming sessions a few times, but most of us only read or heard about it.&lt;/p&gt;
&lt;p&gt;As a result, when developers talk about applying DDD, it usually leads to misunderstandings.
The best solution I’ve found is to avoid talking about DDD in the first place.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/ddd-fight-club.COibOLcX_ZPl7x8.webp&quot; alt=&quot;First rule of DDD: don&apos;t talk about DDD&quot; loading=&quot;lazy&quot; width=&quot;594&quot; height=&quot;499&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;DDD Obstacle 2: Domain learning is a side quest&lt;/h4&gt;
&lt;p&gt;I’ve met developers with years of experience in the same company and yet not knowing much about its core business domain. Some intentionally avoid investing in less transferable niche knowledge; others simply don’t have enough time.&lt;/p&gt;
&lt;p&gt;In day-to-day work, we developers often prioritize writing code over learning the product. Building software is already hard and requires a lot of technical learning, from programming languages to distributed systems to frontend frameworks and everything in between.&lt;/p&gt;
&lt;p&gt;As a result, developers have neither the time nor cognitive capacity to learn the business domain. In my particular case, I have been in healthcare analytics for almost two years now, and I still have a lot to learn.&lt;/p&gt;
&lt;h4&gt;DDD Obstacle 3: It’s not interesting&lt;/h4&gt;
&lt;p&gt;Many of us became developers because we genuinely love building software. The idea to learn something completely different, like medicine, law, or insurance, might not sound that exciting.&lt;/p&gt;
&lt;p&gt;On the other hand, not all domain experts are equally excited to explain the basics again and again to the disengaged engineering crowd.&lt;/p&gt;
&lt;p&gt;Many facilitation activities exist to help overcome these issues. Needless to say, one has to practice a lot to master EventStorming, Domain Storytelling, or similar techniques.&lt;/p&gt;
&lt;h2&gt;What’s next&lt;/h2&gt;
&lt;p&gt;This post was partially inspired by the talk &lt;a href=&quot;https://www.youtube.com/live/I-2TlTJschA?si=xLfgw5M9gBYZlqwl&amp;amp;t=162&quot;&gt;“Slow down to speed up your decision-making”&lt;/a&gt; from Gien Verschatse at GSAS Barcelona 2025. In the age of AI, it’s important to remember that some things should be slow. Next year, I’ll continue my DDD journey with the book &lt;a href=&quot;https://collaborative-software-design.com/&quot;&gt;“Collaborative Software Design”&lt;/a&gt;, which Gien co-authored.&lt;/p&gt;
&lt;p&gt;Another inspiration of the year is &lt;a href=&quot;https://duckdb.org/&quot;&gt;DuckDB&lt;/a&gt;. It can process enormous volumes of data super fast on a typical macbook. In combination with my data analytics experiences at work, DuckDB made me curious about data processing beyond traditional relational databases. Slowly, and with a lot of handwritten notes, I’m finally reading the &lt;a href=&quot;https://www.oreilly.com/library/view/designing-data-intensive-applications/9781098119058/&quot;&gt;“Designing Data-Intensive Applications”&lt;/a&gt; book.&lt;/p&gt;
&lt;p&gt;Yet another area I’m curious about is local-first and sync engines, a topic that became even louder after the TanStack DB release.&lt;/p&gt;
&lt;p&gt;I’m excited about AI acceleration in coding and looking forward to spending more time on the slow things! &lt;span&gt;🎄&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Previous editions: &lt;a href=&quot;/my-tech-year-in-review-2019&quot;&gt;2019&lt;/a&gt;, &lt;a href=&quot;/my-tech-year-in-review-2023&quot;&gt;2023&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>A story of one regexp</title><link>https://kalabro.tech/story-of-one-regexp/</link><guid isPermaLink="true">https://kalabro.tech/story-of-one-regexp/</guid><description>An anecdote from my recent experience with regular expressions featuring Java and PHP. Enjoy!</description><pubDate>Sun, 23 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I find regexp writing very entertaining. When I need to perform some boring text manipulation - let’s say extracting URLs from raw logs - I’d rather spend 10 minutes tweaking a regexp than the same amount of time doing it manually.&lt;/p&gt;
&lt;p&gt;Back in my PHP days, I was lucky to write hundreds of regular expressions for matching URL paths, tweaking HTML, or validating user input. I’ve heard horror stories about dramatic regexp incidents, but I’ve never experienced anything like that myself. Until this year.&lt;/p&gt;
&lt;h3&gt;Not a database problem&lt;/h3&gt;
&lt;p&gt;This year, I’ve been working a lot on a large Java monolith known for its severe performance issues.&lt;/p&gt;
&lt;p&gt;One of these issues was reported by a user who couldn’t open an entity report screen in one of their projects. Normally, the GET endpoint responsible for the report responds in 1-3 seconds, which is acceptable&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; for that use case. In the user’s case, it was taking &lt;strong&gt;18 minutes&lt;/strong&gt;, which obviously resulted in a timeout error.&lt;/p&gt;
&lt;p&gt;The entity in question had hundreds of dependent entities and nested configurations. The team was pretty sure the slowdown was due to some ORM cruelties resulting in billions of database queries. Indeed, the telemetry trace confirmed 196 SELECT queries, but nothing particularly slow. The response was getting stuck right before the end of the processing, without any meaningful tracing information.&lt;/p&gt;
&lt;p&gt;I followed the code for quite some time until I finally found it, the topic for this article!&lt;/p&gt;
&lt;h3&gt;The problem&lt;/h3&gt;
&lt;p&gt;The entity reports are generated in markdown using a custom heading ID syntax. These heading IDs are replaced by HTML anchors when rendering the report to HTML&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. A quick &lt;code&gt;replaceAll&lt;/code&gt; with a regexp is invoked to perform the replacement.&lt;/p&gt;
&lt;p&gt;If you like regular expressions as much as I do, try to solve this problem using a regexp in JavaScript. Find the last occurring word in square brackets in each line. In the example below, &lt;code&gt;ref_heading_1&lt;/code&gt; and &lt;code&gt;ref_another_heading&lt;/code&gt; should be matched.&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;The original code used something like this (click to reveal):&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;&lt;/em&gt;
&lt;p&gt;It suffers from the problem known as “catastrophic backtracking,” the same issue that brought down Cloudflare six years ago&lt;sup&gt;&lt;a href=&quot;#user-content-fn-3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In the regexp above, the &lt;code&gt;[^\n]*&lt;/code&gt; part greedily matches the entire line and then backtracks character by character in an attempt to find a &lt;code&gt;\[(\w+)\]&lt;/code&gt; match. When executed as is, without any optimizations, this results in exponential time complexity.&lt;/p&gt;
&lt;h3&gt;18 min vs 7ms&lt;/h3&gt;
&lt;p&gt;Before fixing the problem, I want to take a quick detour and share how that poor regexp is executed by different languages.&lt;/p&gt;
&lt;p&gt;I took ~80k lines of markdown with 14 matching square brackets and ran this regexp on my M2 mac. Try to guess my results:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;This is not a proper benchmark by any means, but now you know why I didn’t have any problems with regular expressions early in my career.&lt;/p&gt;
&lt;p&gt;Apparently, PHP has always been very tolerant to poor regexp design by using a highly optimized PCRE library under the hood. Since 7.3, it uses PCRE2 with JIT, which makes regexp execution blazing fast, as you could see in my mini-benchmark.&lt;/p&gt;
&lt;p&gt;On the other hand, Java does not rely on any library by default. It provides its own regexp implementation, which is far less optimized than specialized libraries. I could literally follow all the backtracking steps in the debugger to see how bad it was.
As soon as I installed a specialized library&lt;sup&gt;&lt;a href=&quot;#user-content-fn-4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;, I’ve got acceptable performance, although it was still nowhere near PCRE2 written in C.&lt;/p&gt;
&lt;p&gt;If you check the leaderboard of the Java &lt;a href=&quot;https://github.com/gunnarmorling/1brc&quot;&gt;One Billion Row Challenge&lt;/a&gt;, you’ll notice that beyond a certain threshold, all solutions are essentially C code disguised as Java. Such optimizations must be as entertaining as regexp, but not for a sane production codebase.&lt;/p&gt;
&lt;h3&gt;A better regexp&lt;/h3&gt;
&lt;p&gt;Could we rewrite this regexp to achieve acceptable performance?&lt;/p&gt;
&lt;p&gt;I usually start from the part I really want to match and then build the rest of the regexp around it. In this case I need a word starting with &lt;code&gt;ref_&lt;/code&gt; in square brackets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;\[&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ref_&lt;/span&gt;&lt;span&gt;\w&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;\]&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will match all words in square brackets, but we only need the last one. We can specify that none of the next characters until the new line can be a square bracket:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;\[&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;ref_&lt;/span&gt;&lt;span&gt;\w&lt;/span&gt;&lt;span&gt;+&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;span&gt;\][&lt;/span&gt;&lt;span&gt;^&lt;/span&gt;&lt;span&gt;\[]&lt;/span&gt;&lt;span&gt;*&lt;/span&gt;&lt;span&gt;\n  ✅&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Figured out a better one? Share in comments!&lt;/p&gt;
&lt;h3&gt;The fix&lt;/h3&gt;
&lt;p&gt;As I said, I find regexp writing very entertaining. Still, the production code is not the right place for that. The mix of escaped square brackets makes this regexp hard to read and review.&lt;/p&gt;
&lt;p&gt;Instead, I wrote a simple loop that iterates over the lines of the input text, looks for the specific pattern &lt;code&gt;[ref_&lt;/code&gt; using &lt;code&gt;String.contains&lt;/code&gt;, and only if a match is found, invokes the &lt;code&gt;replaceFirst&lt;/code&gt; method.&lt;/p&gt;
&lt;p&gt;This solution is much faster than any regexp I tried, and also much easier to maintain. Now, time to look into those 196 SELECT queries &lt;span&gt;😈&lt;/span&gt;&lt;/p&gt;
&lt;section&gt;&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Acceptable for that particular system in that particular phase of its maintenance cycle &lt;span&gt;🤓&lt;/span&gt; &lt;a href=&quot;#user-content-fnref-1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A more common format would be &lt;code&gt;{#heading-id}&lt;/code&gt; but migrating would require much more effort: &lt;a href=&quot;https://www.markdownguide.org/extended-syntax/#heading-ids&quot;&gt;https://www.markdownguide.org/extended-syntax/#heading-ids&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://blog.cloudflare.com/details-of-the-cloudflare-outage-on-july-2-2019/#appendix-about-regular-expression-backtracking&quot;&gt;Details of the Cloudflare outage on July 2, 2019 (Appendix: About Regular Expression Backtracking)&lt;/a&gt; &lt;a href=&quot;#user-content-fnref-3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/google/re2j&quot;&gt;RE2/J&lt;/a&gt; is a port of C++ library RE2 to pure Java. &lt;a href=&quot;#user-content-fnref-4&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>React Alicante 2025</title><link>https://kalabro.tech/react-alicante-2025/</link><guid isPermaLink="true">https://kalabro.tech/react-alicante-2025/</guid><description>Full list of talks with my short comments.</description><pubDate>Mon, 13 Oct 2025 08:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On this page, you can find a full list of all &lt;a href=&quot;https://reactalicante.es/&quot;&gt;React Alicante 2025&lt;/a&gt; talks with my short comments. A longer opinionated summary at the end.&lt;/p&gt;
&lt;p&gt;Enjoy and feel free to reuse it if you need a summary for your team or employer.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-1&quot;&gt;Sessions - Day 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-2&quot;&gt;Sessions - Day 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#my-summary&quot;&gt;My summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sessions - Day 1&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;16 high quality talks on React Server Components, Compilers, CSS and personal projects.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Building for You by Kadi Kraman&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/kadikraman&quot;&gt;&lt;strong&gt;@kadikraman&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kadi, a software developer at Expo, set a theme for this year’s conference: personal side projects built out of curiosity and passion.
She touched on common obstacles like procrastination, scope creep, and goal setting when building something outside of work.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://newsletter.getprimitive.ai/p/when-to-design-for-emergence&quot;&gt;When to Design for Emergence by Kasey Klimes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://maggieappleton.com/home-cooked-software&quot;&gt;Home-Cooked Software and Barefoot Developers by Maggie Appleton&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Developing Waku and Exploring Client State with React Server Components by Daishi Kato&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/dai_shi&quot;&gt;&lt;strong&gt;@dai_shi&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The author of Zustand and Jotai talks about &lt;a href=&quot;https://waku.gg/&quot;&gt;Waku&lt;/a&gt;, the project he initially built to explore React Server Components but ended up
with a fully functional React framework that offers a minimalistic alternative to Next.js.
Daishi demystified the RSC API by breaking it down to serializing and deserializing components. As a state management guru, he went deeper and explored
how jotai may look like in RSC world. The result is &lt;a href=&quot;https://github.com/wakujs/waku-jotai&quot;&gt;waku-jotai&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Building Interactive Async UI with React 19 and Ariakit by Aurora Scharff&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/aurorascharff&quot;&gt;&lt;strong&gt;@aurorascharff&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aurora took a real life example of a dropdown component with some data fetching logic and walked us through a series of refactorings
to make it more accessible, maintainable, and user friendly. The synergy between React, Ariakit and Tailwind made code much more compact and declarative.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://ariakit.org/&quot;&gt;Ariakit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/aurorascharff/next15-account-selector&quot;&gt;Github repo used in the talk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The 2025 State of React Testing by Daniel Afonso&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/danieljcafonso&quot;&gt;&lt;strong&gt;@danieljcafonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The past, present and future of frontend testing featuring Vitest Browser Mode, MSW, Playwright, and emerging AI tools.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://oxc.rs/&quot;&gt;Oxc&lt;/a&gt; and &lt;a href=&quot;https://biomejs.dev/&quot;&gt;Biome&lt;/a&gt; as possible replacements for ESLint/Prettier&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vitest.dev/guide/browser/&quot;&gt;Vitest Browser Mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bytedance/ui-tars?tab=readme-ov-file&quot;&gt;UI-TARS-2&lt;/a&gt; - vision-language model (VLM)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ministryoftesting.com/articles/creating-self-healing-automated-tests-with-ai-and-playwright&quot;&gt;Creating self-healing automated tests with AI and Playwright&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://midscenejs.com/&quot;&gt;Midscene.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Compilers, User Interfaces &amp;amp; the Rest of Us by Matheus Albuquerque&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/ythecombinator&quot;&gt;&lt;strong&gt;@ythecombinator&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://speakerdeck.com/ythecombinator/react-alicante-2025&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Typical frontend work can feel distant from computer science theory, but many of the tools we use every day actually involve compilers.
The deck is packed with links to libraries, concepts and articles that I’m yet to explore. In the past, I would be overwhelmed by this talk,
but with AI I feel I can easily dig couple layers deeper if I need to.&lt;/p&gt;
&lt;h3&gt;React Beyond the DOM by Erik Rasmussen&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/erikras&quot;&gt;&lt;strong&gt;@erikras&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The talk started as a typical overview of React internals but suddenly turned into a fascinating live demo that blew everyone’s mind &lt;span&gt;💡&lt;/span&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/wojtekmaj/react-pdf&quot;&gt;react-pdf&lt;/a&gt; and &lt;a href=&quot;https://github.com/vadimdemedes/ink&quot;&gt;ink&lt;/a&gt; as examples of custom React renderers&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/erikras/react-html-to-markdown&quot;&gt;Github repo used in the talk&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=wraith13.bracket-lens&quot;&gt;Bracket Lens&lt;/a&gt; (I spotted it on Erik’s screen)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Legacy Starts Tomorrow: Surviving the Refactoring Loop by Paulina Chojnowska&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/AntariaPaulina&quot;&gt;&lt;strong&gt;@AntariaPaulina&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A much needed reminder that we should never stop refactoring despite it’s rarely immediately profitable. Advice from Paulina is as obvious as
“sleep well and brush your teeth” and yet it has to be said: refactor all the time, plan for it, own the code.&lt;/p&gt;
&lt;h3&gt;Feature Flags 101: Transforming Your Development with a Simple Switch by Luis Oliveira&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/_luisFilipePT&quot;&gt;&lt;strong&gt;@_luisFilipePT&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Feature flags allow us to control behavior without deploy. Luis clarifies use cases for environment variables vs feature flags and shares
some common patterns like “Kill Switch”.&lt;/p&gt;
&lt;h3&gt;Building component libraries with designers, not for them by Przemek Krupiński&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/pppemo&quot;&gt;&lt;strong&gt;@pppemo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Przemek is a regular React Alicante attendee who came back this year with a lighting talk on collaborating with designers. He focused
on the importance of building shared language, trust and cross-functional transparency.&lt;/p&gt;
&lt;h3&gt;Local first is the new black by Miquel Company&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/solilokiam&quot;&gt;&lt;strong&gt;@solilokiam&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Miquel builds a cool personal project, The Pyrenees Challenge event for motorcycle enthusiasts. He shared his local-first journey starting with
DIY Zustand+Yjs, continuing with Tinybase and its performance issues, and eventually settling on &lt;a href=&quot;https://jazz.tools/&quot;&gt;jazz tools&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://lofi.so/&quot;&gt;https://lofi.so/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Level up your React knowledge with vibe coding by Heather Thacker&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/hhthacker&quot;&gt;&lt;strong&gt;@hhthacker&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A lightning talk on how AI can be used to learn React.&lt;/p&gt;
&lt;h3&gt;How I used AI Workflows with Figma &amp;amp; Playwright MCPs to accelerate my development time by Aris Markogiannakis&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/arismarko&quot;&gt;&lt;strong&gt;@arismarko&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://www.canva.com/design/DAFqwlKyZ5o/fMvjcBAcd1dZp0F73Lzhbg/edit&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;MCPs made a lot of noise when they were first introduced, but it’s not always clear how they can be used in our day to day work.
Aris shared some examples from his own workflows.&lt;/p&gt;
&lt;h3&gt;Scaling a React Application from 0 to a Brazilian users by Dan Neciu&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/neciudan&quot;&gt;&lt;strong&gt;@neciudan&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dan shared a brief story of co-founding CareerOS and surviving its early days. Some technical tips include starting component
library early and bringing wrappers for all 3rd party libraries.&lt;/p&gt;
&lt;h3&gt;My CSS is Faster Than Your React! Writing CSS only React Search! by Evyatar Alush&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/evyataral&quot;&gt;&lt;strong&gt;@evyataral&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Evyatar blew everyone’s mind by building a fully functioning search with just CSS. In fact it was used in his library &lt;a href=&quot;https://github.com/ealush/emoji-picker-react&quot;&gt;emoji-picker-react&lt;/a&gt; (&lt;a href=&quot;https://github.com/ealush/emoji-picker-react/blob/6c27ae29cb95b628cc86246b54f4cb6d410d7661/src/components/header/Search/CssSearch.tsx&quot;&gt;code&lt;/a&gt;) before he replaced it with vistualization.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ealush/flairup&quot;&gt;FlairUp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Reacting to Surprises: Creating Engaging Hidden Features by Courtney Yatteau&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/c_yatteau&quot;&gt;&lt;strong&gt;@c_yatteau&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Courtney shared a few examples of easter eggs in apps that can make user experience more engaging.&lt;/p&gt;
&lt;h3&gt;Nearly Familiar: Can Web Developers Relate to Genealogy? by Kevin Maes&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/kvmaes&quot;&gt;&lt;strong&gt;@kvmaes&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kevin wrapped up the first day with an insanely well-built personal project for exploring genealogical data, his longtime hobby.
While we learned a lot about genealogy and visualization pipelines, the main takeaway for us was to reconnect with our inner creativity.
It can be very satisfying and educational to build something for fun.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://stately.ai/docs/system&quot;&gt;XState actor system&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://p5js.org/&quot;&gt;p5.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.comfy.org/&quot;&gt;ComfyUI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sessions - Day 2&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Another 16 talks on React 19.2, animations, and of course AI!&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;The State of React and the Community in 2025 by Mark Erikson&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/acemarke&quot;&gt;&lt;strong&gt;@acemarke&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://blog.isquaredsoftware.com/presentations/2025-06-state-react-community/&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Mark acknowledged the complicated state of React community caused by the weird and intense Vercel’s push for React Server Components.
Several years later, the community is still recovering. Just a few days after this talk, React introduced the &lt;a href=&quot;https://react.dev/blog/2025/10/07/introducing-the-react-foundation&quot;&gt;React Foundation&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.isquaredsoftware.com/2025/06/react-community-2025/&quot;&gt;Blog post&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Suspense Continues: ViewTransition and Activity by Chance Strickland&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/chancethedev&quot;&gt;&lt;strong&gt;@chancethedev&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Just a few days before React Alicante, React 19.2 was released and Chance gave us a live demo of the new features.&lt;/p&gt;
&lt;h3&gt;The Beachcomber’s Guide to Type-Safe Design Systems by Kathleen McMahon&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/resource11&quot;&gt;&lt;strong&gt;@resource11&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kathleen covered several important topics, such as the polymorphic component smell (&lt;code&gt;&amp;lt;Button as=&quot;a&quot; /&amp;gt; 💩&lt;/code&gt;), the semantics of &lt;code&gt;interface&lt;/code&gt; vs &lt;code&gt;type&lt;/code&gt; in component libraries, and the power of typed design systems. She also led an accessibility workshop at the conference and shared with me that overall awareness of a11y is growing!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.figma.com/community/plugin/843461159747178978/tokens-studio-for-figma&quot;&gt;Token Studio&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Unleashing the Magic of JavaScript Generators by Mattia Manzati&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/mattiamanzati&quot;&gt;&lt;strong&gt;@mattiamanzati&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://github.com/mattiamanzati/magic-of-js-generators&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Generators have been around longer than async/await and yet most of us without Python background don’t quite understand them.
“Generators are iterators &lt;em&gt;and&lt;/em&gt; iterables that provide pull-based data flow” - Mattia unpacked this for us starting small and ending up
with its own UI rendering engine powered by generators.&lt;/p&gt;
&lt;p&gt;Surprisingly, there is not much educational content on the topic. The most relevant I found is &lt;a href=&quot;https://fnayre.github.io/2018-11-19-algebraic-effects-series-1/&quot;&gt;Algebraic Effects in JavaScript&lt;/a&gt; series by Redux Saga author.&lt;/p&gt;
&lt;h3&gt;The Dark Side of UI – Avoiding Common Frontend Anti-Patterns by Bree Hall&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/bytesofbree&quot;&gt;&lt;strong&gt;@bytesofbree&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Bree walked us through a few poorly written React components and offered better approaches, featuring libraries like TanStack Query
and TanStack Vistualization.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;github.com/PatrickJS/awesome-cursorrules&quot;&gt;Awesome Cursor Rules&lt;/a&gt; (or &lt;a href=&quot;https://github.com/github/awesome-copilot&quot;&gt;awesome-copilot&lt;/a&gt;) to communicate your preferences to AI&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Navigating the hype driven world of AI development without going crazy by Kitze&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/thekitze&quot;&gt;&lt;strong&gt;@thekitze&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Super fun talk ridiculing the hype around AI as well as our FOMO around it.
For Kitze, coding is a form of procrastination. He doesn’t allow himself to write code manually and instead forces himself to always use AI. The &lt;a href=&quot;https://x.com/PR0GRAMMERHUM0R/status/1974625610124148844&quot;&gt;“Managers have been vibe coding forever”&lt;/a&gt; slide immediately went viral&lt;/p&gt;
&lt;h3&gt;Zen and the art of code maintenance by Beth Swingler&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/bethylogism&quot;&gt;&lt;strong&gt;@bethylogism&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Using Zen as analogy, Beth highlighted some common code maintenance problems. Bonus points for mentioning the &lt;a href=&quot;https://kalabro.tech/tidy-first/&quot;&gt;Tidy First?&lt;/a&gt; book! &lt;span&gt;😻&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Fun with emails by Daniel Mocan&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/danielsmocan&quot;&gt;&lt;strong&gt;@danielsmocan&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Daniel gave us a quick intro to &lt;a href=&quot;https://react.email/&quot;&gt;React Email&lt;/a&gt;, a great library to dramatically simplify email templating.&lt;/p&gt;
&lt;h3&gt;End-to-end testing: the hard parts by Kate Marshalkina&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/kalabro&quot;&gt;&lt;strong&gt;@kalabro&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I gave a shorter version of my &lt;a href=&quot;https://www.youtube.com/watch?v=OYZNTPp04hw&quot;&gt;“Playwright testing at scale”&lt;/a&gt; talk focusing on the hard parts.
More on my speaker experience at the end of the post.&lt;/p&gt;
&lt;h3&gt;Deploying an app with Docker by Forbes Lindesay&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/ForbesLindesay&quot;&gt;&lt;strong&gt;@ForbesLindesay&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A friendly intro to Docker for frontend developers who want to deploy their apps outside Vercel.&lt;/p&gt;
&lt;h3&gt;Boosting React Native Performance with React Compiler: A Sneak Peek into the Future by Ilda Neta&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ildaneta&quot;&gt;&lt;strong&gt;@ildaneta&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Ilda demonstrated how React Compiler can be used in a React Native project. I didn’t know about &lt;code&gt;&quot;use no memo&quot;&lt;/code&gt; directive to opt out of automatic memoization.&lt;/p&gt;
&lt;h3&gt;Make development easier with your own browser extensions by Łukasz Nowak&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/LukaszNowakPL&quot;&gt;&lt;strong&gt;@LukaszNowakPL&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Łukasz wanted to build a helper extension for himself and his teammates but it turned out to be tricker than expected. He faced several challenges
such as embedding React, communicating with the main page, and debugging.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/LukaszNowakPL/browser-extensions&quot;&gt;Github repo used in the talk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Audio recording and playback complexity across browsers by Vinu Vijy Nair&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/vinu-phoenix&quot;&gt;&lt;strong&gt;@vinu-phoenix&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Vinu shared how he attempted to build a new audio feature for ManyChat fully in the browser, what challenges he faced and
of course what he learned.&lt;/p&gt;
&lt;h3&gt;The Missing Middle Ground: Fast &amp;amp; Real Testing for React Native by Łukasz Chludziński&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/lukasz_app&quot;&gt;&lt;strong&gt;@lukasz_app&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another testing talk, this time in React Native space. Łukasz demoed a new library &lt;a href=&quot;https://www.npmjs.com/package/react-native-harness&quot;&gt;&lt;code&gt;react-native-harness&lt;/code&gt;&lt;/a&gt; that allows testing native capabilities while keeping tests fast and developer friendly.&lt;/p&gt;
&lt;h3&gt;Running WebAssembly in React Native Applications by Shivay Lamba&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/HowDevelop&quot;&gt;&lt;strong&gt;@HowDevelop&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;WebAssembly is not super common in React Native due to the differences between web and mobile platforms. Apparently, there are some interesting
use cases and solutions in this space.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/callstackincubator/polygen&quot;&gt;Polygen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Practical guide to animation in React by Kateryna Porshnieva&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/krambertech&quot;&gt;&lt;strong&gt;@krambertech&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This year Kateryna demystified animations for the rest of us. Very visual and practical talk covering everything from basics
to spring physics.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/transform-origin&quot;&gt;transform-origin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/animation-fill-mode&quot;&gt;animation-fill-mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/animation-delay&quot;&gt;animation-delay&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://easings.net/&quot;&gt;https://easings.net/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://easingwizard.com/&quot;&gt;https://easingwizard.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.joshwcomeau.com/animation/a-friendly-introduction-to-spring-physics/&quot;&gt;A Friendly Introduction to Spring Physics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gsap.com/&quot;&gt;https://gsap.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://motion.dev/&quot;&gt;https://motion.dev/&lt;/a&gt; &amp;amp; &lt;a href=&quot;https://motion.dev/studio&quot;&gt;https://motion.dev/studio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://lucide.dev/&quot;&gt;https://lucide.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://animate-ui.com/&quot;&gt;https://animate-ui.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://icons.pqoqubbw.dev/&quot;&gt;https://icons.pqoqubbw.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;My summary&lt;/h2&gt;
&lt;p&gt;It was my third (!) React Alicante conference in a row and the fourth (!) React conference this year. I’ll be honest, I was not sure I would enjoy it that much, given that I had already heard from many of the speakers earlier this year.&lt;/p&gt;
&lt;p&gt;Turns out, I had no reason to worry. After visiting so many conferences, React Alicante is still one of my favorites:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I prefer single-track conferences with a larger audience - it feels more engaging.&lt;/li&gt;
&lt;li&gt;I love the packed agenda, with 32 talks plus optional workshops.&lt;/li&gt;
&lt;li&gt;The average talk quality is high, with some lightning talks outperforming full talks.&lt;/li&gt;
&lt;li&gt;Tickets are cheaper than most other conferences.&lt;/li&gt;
&lt;li&gt;The organization is always very smooth. For a regular attendee, everything just works, while behind the scenes the organizers work hard to fix all the random issues.&lt;/li&gt;
&lt;li&gt;A very special location creates vacation vibes.&lt;/li&gt;
&lt;li&gt;The lovely community spirit and super friendly atmosphere &lt;span&gt;❤️&lt;/span&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Speaker experience&lt;/h3&gt;
&lt;p&gt;Delivering the same talk at multiple conferences is efficient but boring.&lt;/p&gt;
&lt;p&gt;For React Alicante, I decided to rework my material into something new.
I love the time constraint that a lightning talk imposes - it requires me to be laser-focused on what’s important. Last year, I gave a deck-free inspirational &lt;a href=&quot;https://www.youtube.com/watch?v=bZoji7jCSU8&quot;&gt;speech on mentorship&lt;/a&gt;. This year, I decided to go technical and even included a short live coding demo. I had a lot of fun, and I hope the attendees enjoyed it as well!&lt;/p&gt;
&lt;h3&gt;Popular topics&lt;/h3&gt;
&lt;p&gt;This year’s agenda was very well balanced. AI topics were carefully kept under control, and I really appreciated it.&lt;/p&gt;
&lt;p&gt;React remained at the center of attention, complemented by a mix of evergreen frontend topics like testing, design, and refactoring.
I was a bit surprised by the lack of TanStack deep dives, especially given the recent TanStack Start v1 RC release. To compensate, I read &lt;a href=&quot;https://frontendatscale.com/blog/tanstack-db/&quot;&gt;“An Interactive Guide to TanStack DB”&lt;/a&gt; on my flight back.&lt;/p&gt;
&lt;h3&gt;Videos&lt;/h3&gt;
&lt;p&gt;All sessions were recorded and will be available on YouTube. While waiting, checkout React Conf 2025 recordings (&lt;a href=&quot;https://www.youtube.com/watch?v=zyVRg2QR6LA&quot;&gt;day 1&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=p9OcztRyDl0&quot;&gt;day 2&lt;/a&gt;).&lt;/p&gt;</content:encoded></item><item><title>Bullet points from CityJS London 2025</title><link>https://kalabro.tech/cityjs-london-2025/</link><guid isPermaLink="true">https://kalabro.tech/cityjs-london-2025/</guid><description>Highlights from the conference and what&apos;s next</description><pubDate>Thu, 01 May 2025 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Nine things from my CityJS London 2025 notes:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;The community is excited about MCP. New user experience. No more glue code. LLM is the glue (&lt;a href=&quot;https://www.epicai.pro/letting-ai-interface-with-your-app-with-mcps-talk&quot;&gt;Kent’s talk&lt;/a&gt;, &lt;a href=&quot;https://modelcontextprotocol.io/specification/2025-03-26&quot;&gt;MCP spec&lt;/a&gt;, &lt;a href=&quot;https://x.com/shadcn/status/1917597228513853603&quot;&gt;shadcn/ui registry MCP demo&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Testing is a hot topic (Soumaya Erradi, Daniel Afonso, and your humble author each presented in packed rooms). Tools mentioned: Selenium, Cypress, Playwright, Vitest Browser Mode, Biome, Oxc, msw-auto-mock.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lynx - a new React Native alternative open-sourced by the TikTok team. Yes, CSS is supported (&lt;a href=&quot;https://lynxjs.org/react&quot;&gt;ReactLynx&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;AI generates vulnerable code, and even security experts like Liran Tal find it difficult to review it.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&quot;https://chromewebstore.google.com/detail/accessibility-insights-fo/pbjjkligggfmakdaogkfomddhfmpjeni?hl=en&quot;&gt;Accessibility Insights Chrome extension&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;New asynchronous model is coming to Svelte (&lt;a href=&quot;https://github.com/sveltejs/svelte/discussions/15845&quot;&gt;discussion&lt;/a&gt;)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;HTMX didn’t take off because developers love the component model from React.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Meetups are dead (I don’t agree as I’m attending a few in Barcelona).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Huge thanks to the organizers — I finally have a cup to drink my tea in! &lt;span&gt;😅&lt;/span&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img alt=&quot;CityJS London 2025 - my cup&quot; loading=&quot;lazy&quot; width=&quot;413&quot; height=&quot;550&quot; src=&quot;/_astro/cityjslondon-cup.wW1mJ5qj_Z1bSwoV.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Of course, my notes are incomplete and only capture a fraction of this large 3-track event! Check the official videos when they’re out.&lt;/p&gt;
&lt;h2&gt;What’s next?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://reactsummit.com/&quot;&gt;React Summit&lt;/a&gt; (June 13th, 2025)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.devbcn.com/&quot;&gt;DevBcn&lt;/a&gt; (July 8th - 10th, 2025)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://reactalicante.es/&quot;&gt;React Alicante&lt;/a&gt; (October 2nd - 4th, 2025)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See you there &lt;span&gt;👋&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>React Paris 2025</title><link>https://kalabro.tech/react-paris-2025/</link><guid isPermaLink="true">https://kalabro.tech/react-paris-2025/</guid><description>Full list of talks with my short comments.</description><pubDate>Tue, 25 Mar 2025 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On this page, you can find a full list of all &lt;a href=&quot;https://react.paris/&quot;&gt;React Paris 2025&lt;/a&gt; talks with my short comments. A longer opinionated summary at the end.&lt;/p&gt;
&lt;p&gt;Enjoy and feel free to reuse it if you need a summary for your team or employer.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-1&quot;&gt;Sessions - Day 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-2&quot;&gt;Sessions - Day 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#my-summary&quot;&gt;My summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sessions - Day 1&lt;/h2&gt;
&lt;p&gt;A day full of diverse React talks including a keynote by Kent C. Dodds.&lt;/p&gt;
&lt;h3&gt;Abracadabra: The Vanishing Network by Kent C. Dodds&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/kentcdodds&quot;&gt;&lt;strong&gt;@kentcdodds&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;React superstar Kent C. Dodds opened the event with his Abracadabra talk.
Many of us had seen it already, but it didn’t matter - we all love Kent so much.&lt;/p&gt;
&lt;p&gt;One of the questions from the audience concerned the blurry line between frontend and backend in React Server Components.
Kent’s take was that it’s not necessarily a bad thing if you’re not married to the traditional frontend/backend team split.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=E8LLty9rTWw&quot;&gt;Abracadabra: The vanishing network — Kent C. Dodds | React Universe Conf 2024&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.epicweb.dev/the-webs-next-transition&quot;&gt;The Web’s Next Transition&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Building a design system with React in 2025, what’s new? by Jean Burellier&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/shepsheplu&quot;&gt;&lt;strong&gt;@shepsheplu&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Jean and his team at Sanofi have built a design system from scratch, even the date picker! In their highly regulated pharmaceutical field, a bespoke
solution was the only viable option and was actually cheaper than using existing libraries.&lt;/p&gt;
&lt;h3&gt;I Can’t Believe It’s Not JavaScript by Jemima Abu&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/jemimaabu&quot;&gt;&lt;strong&gt;@jemimaabu&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;“We went from JS &lt;em&gt;supporting&lt;/em&gt; the web to JS &lt;em&gt;running&lt;/em&gt; the web” — Jemima shared a brief history of JavaScript and how it became massively overused
in the modern web. She shared several examples where plain HTML and CSS could do a much better job than JavaScript, bringing us back to the fast and accessible web.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Popover_API&quot;&gt;Popover API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/:target&quot;&gt;:target&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://scroll-driven-animations.style/&quot;&gt;https://scroll-driven-animations.style/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Demystifying Accessibility in React Apps by Kateryna Porshnieva&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/krambertech&quot;&gt;&lt;strong&gt;@krambertech&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A variation of Kateryna’s talk on accessibility walked us through some common UI elements and how to make them accessible. When the audience asked how to justify accessibility work to project managers, Kateryna confidently suggested to “just do it” - and I fully agree it should be part of the Definition of Done.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://krambertech.notion.site/Demystifying-accessibility-in-React-apps-15efe3ecdbc84cf59a22baaace09c629&quot;&gt;Slides and resources&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://webaim.org/projects/million/&quot;&gt;The WebAIM Million&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.w3.org/WAI/ARIA/apg/patterns/&quot;&gt;https://www.w3.org/WAI/ARIA/apg/patterns/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.radix-ui.com/&quot;&gt;https://www.radix-ui.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://react-spectrum.adobe.com/react-aria/index.html&quot;&gt;https://react-spectrum.adobe.com/react-aria/index.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Goodbye, useState by David Khourshid&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/davidkpiano&quot;&gt;&lt;strong&gt;@davidkpiano&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;David started by sharing some common examples of &lt;code&gt;useState&lt;/code&gt; hell - “Vibe State Management”. Modern React offers many alternatives to &lt;code&gt;useState&lt;/code&gt;, and David walked us through some of the most popular ones.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://react.dev/reference/react/useReducer&quot;&gt;useReducer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tanstack.com/query/latest&quot;&gt;Tanstack Query&lt;/a&gt; and &lt;a href=&quot;https://tanstack.com/form/latest&quot;&gt;Tanstack Form&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://immerjs.github.io/immer/&quot;&gt;Immer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://stately.ai/docs/xstate-store&quot;&gt;XState Store&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Type-Safe URL State Management in React with nuqs by François Best&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/fortysevenfx&quot;&gt;&lt;strong&gt;@fortysevenfx&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;François is the author of &lt;a href=&quot;https://nuqs.47ng.com/&quot;&gt;&lt;code&gt;nuqs&lt;/code&gt;&lt;/a&gt; — URL state manager for React. In his talk, he explained some benefits of storing state in the URL as well as some common challenges that &lt;code&gt;nuqs&lt;/code&gt; solves.&lt;/p&gt;
&lt;p&gt;It’s always great to have open source contributors on stage!&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://nuqs.47ng.com/react-paris&quot;&gt;Slides and supporting materials&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://x.com/housecor/status/1799435036736778364&quot;&gt;Picking a React State Approach&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;React Server Components: Elevating Speed, Interactivity, and User Experience by Aurora Scharff&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/aurorascharff&quot;&gt;&lt;strong&gt;@aurorascharff&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Aurora teaches RSC using live coding approach. This time she took a very slow Next.js app and progressively improved its UX using latest React features. As a bonus, she integrated the app with &lt;code&gt;nuqs&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/aurorascharff/next15-filterlist&quot;&gt;Github repo used in the talk&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What we learned rebuilding the largest Nordic electronic retail website in Next.js? by Tomas Jansson&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/tomasjansson&quot;&gt;&lt;strong&gt;@tomasjansson&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A case study of the largest Nordic electronics retail website rebuilt with idiomatic Next.js and hosted on Vercel. The achieved performance boost speaks for itself, but it wasn’t easy to get there. Tomas shared advice on how to push innovation and get buy-in within larger organizations.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://presentations.2mas.xyz/reactparis&quot;&gt;Slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://flags-sdk.dev/&quot;&gt;https://flags-sdk.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Bridging Code and Creativity: Level Up Your Game as a Frontend Engineer by Yu Ling Cheng&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/YuLingEC&quot;&gt;&lt;strong&gt;@YuLingEC&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yu Ling took us on a journey from a typical developer who struggles to communicate with designers and product managers to an influential leader who helps the whole team collaborate and build better products.&lt;/p&gt;
&lt;p&gt;I noted down a magic phrase for when I have doubts but am not ready to express them yet: “Let me double check and get back to you.”&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://drive.google.com/drive/folders/1QZGOXs5FD24ncwjIiuN1Ev_BC3xsx9Lc&quot;&gt;Slides&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sessions - Day 2&lt;/h2&gt;
&lt;p&gt;The second day was much more focused on AI with a great vibe keynote by Tejas Kumar.&lt;/p&gt;
&lt;h3&gt;Using AI Effectively in 2025 by Tejas Kumar&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/tejaskumar_&quot;&gt;&lt;strong&gt;@tejaskumar_&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A live coding session with Tejas who built a streaming AI chat first without any libraries at all to help us understand the basics,
and then with Vercel AI SDK which solves most of the complexity for us. The second part of the talk demoed a simple AI agent capable of rendering React components,
playing videos, and interacting with browser APIs such as location. Super cool!&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.npmjs.com/package/ai&quot;&gt;https://www.npmjs.com/package/ai&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ndjson/ndjson-spec&quot;&gt;https://github.com/ndjson/ndjson-spec&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/TanStack/create-tsrouter-app?tab=readme-ov-file#mcp-model-context-protocol-support-experimental&quot;&gt;TanStack Start MCP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tanstack.com/query/latest/docs/reference/streamedQuery#streamedquery&quot;&gt;Streaming in TanStack Query&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Let’s build K.I.T.T. with JavaScript by Nico Martin&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/nic_o_martin&quot;&gt;&lt;strong&gt;@nic_o_martin&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Imagine a LEGO car that understands human language, knows everything about 90 episodes of Knight Rider, and runs around the stage at React Paris.&lt;br /&gt;
That’s what Nico built using Tiny Llama running in the browser, IndexedDB to store data about all the episodes, and a bit of JavaScript magic.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/WebGPU_API&quot;&gt;WebGPU&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/mlc-ai/web-llm&quot;&gt;WebLLM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://huggingface.co/docs/transformers.js/en/index&quot;&gt;Transformers.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/hexgrad/kokoro/tree/main/kokoro.js&quot;&gt;Kokoro.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kitt.nico.dev/&quot;&gt;kitt.nico.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;From Chaos to Clarity: Mathematical Foundations for Maintainable React Applications by Héla Ben Khalfallah&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/b_k_hela&quot;&gt;&lt;strong&gt;@b_k_hela&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Héla started with a list of typical JavaScript codebase issues: spaghetti code, callback hell, lack of testing, and so on.
She believes all that is curable with math, and gave us an intro to Graph Theory, Category Theory, Functional Programming
and Lambda Calculus.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://helabenkhalfallah.com/2024/11/20/from-chaos-to-clarity-mathematical-foundations-for-maintainable-js/&quot;&gt;From Chaos to Clarity: Mathematical Foundations for Maintainable JS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/helabenkhalfallah/code-health-meter&quot;&gt;https://github.com/helabenkhalfallah/code-health-meter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/helabenkhalfallah/dsa-toolbox&quot;&gt;https://github.com/helabenkhalfallah/dsa-toolbox&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Work Smarter, not Harder with Chrome DevTools by Dominika Zając&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/domizajac&quot;&gt;&lt;strong&gt;@domizajac&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dominika shared some less known Chrome DevTools tips and tricks that I tried first thing at work the next day. Very useful!
Of course, AI was involved again!&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/css-overview&quot;&gt;https://developer.chrome.com/docs/devtools/css-overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/accessibility/contrast&quot;&gt;https://developer.chrome.com/docs/devtools/accessibility/contrast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/blog/full-accessibility-tree&quot;&gt;https://developer.chrome.com/blog/full-accessibility-tree&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/rendering/performance#paint-flashing&quot;&gt;https://developer.chrome.com/docs/devtools/rendering/performance#paint-flashing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/Document/designMode&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/Document/designMode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://developer.chrome.com/docs/devtools/recorder&quot;&gt;https://developer.chrome.com/docs/devtools/recorder&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;A Tale of Two Components: Mastering A/B Testing in React by Violina Popova&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/PopovaViolina&quot;&gt;&lt;strong&gt;@PopovaViolina&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Violina gave an intro to A/B testing and how to do it in React. She also shared some real-life results from
A/B campaigns her team ran at ClipMyHorse.TV, a YouTube for horse lovers!&lt;/p&gt;
&lt;h3&gt;At the top of the pyramid: Playwright testing at scale by Kate Marshalkina&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/kalabro&quot;&gt;&lt;strong&gt;@kalabro&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I also had a pleasure to speak at React Paris! This time I shared a story about end-to-end testing and Playwright. More on my speaker experience at the bottom.&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://playwright.dev/docs/best-practices&quot;&gt;https://playwright.dev/docs/best-practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/playwright-community/eslint-plugin-playwright&quot;&gt;https://github.com/playwright-community/eslint-plugin-playwright&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vitalets/playwright-network-cache&quot;&gt;https://github.com/vitalets/playwright-network-cache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://vitest.dev/guide/browser/&quot;&gt;https://vitest.dev/guide/browser/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://martinfowler.com/articles/2021-test-shapes.html&quot;&gt;On the Diverse And Fantastical Shapes of Testing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;React Query API Design - Lessons Learned by Dominik Dorfmeister&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/tkdodo&quot;&gt;&lt;strong&gt;@tkdodo&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dominik started his journey as a React Query user, then became active in the community answering questions and writing documentation.
Today, he is the key maintainer of the de-facto standard library for data fetching in React. In this talk, he shared some lessons he learned
working on such a cool project. It was a pleasure to meet and learn from him!&lt;/p&gt;
&lt;h3&gt;Using Remix, the wrong (?) way by Antoine Chalifour&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/antoinechalifour&quot;&gt;&lt;strong&gt;@antoinechalifour&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I really enjoyed Antoine’s honest story about building his product with Remix and having quite a few battles with the opinionated framework.
Remix is great, but Antoine’s project didn’t quite fit its router model. Luckily, Antoine found a way to make it work and also learned a lot on his way!&lt;/p&gt;
&lt;h3&gt;A journey into the fiber by Matias Nahuel Gonzalez Fernandez&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/matiNotFound&quot;&gt;&lt;strong&gt;@matiNotFound&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Matias wrapped up the event with the inspiring demos of custom React Fiber implementations, including Doom in React!&lt;/p&gt;
&lt;p&gt;Links:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/matiasngf/experiment-compilers/tree/main/fiber&quot;&gt;https://github.com/matiasngf/experiment-compilers/tree/main/fiber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pmndrs/react-three-fiber&quot;&gt;https://github.com/pmndrs/react-three-fiber&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jimp-dev/jimp&quot;&gt;https://github.com/jimp-dev/jimp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;My summary&lt;/h2&gt;
&lt;p&gt;React Paris offered a great speaker lineup, but my biggest highlight was the very special and friendly atmosphere between the talks.
With generous coffee and lunch breaks, I had plenty of time to meet interesting people, share laughs, and enjoy the beautiful location in the heart of Paris.&lt;/p&gt;
&lt;p&gt;At React Paris 2025, I met the most female developers I’ve ever seen at a tech conference. This speaks a lot about both the event and the state of the community!&lt;/p&gt;
&lt;h4&gt;Speaker experience &lt;span&gt;📣&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;Honestly, I didn’t expect much interest in the testing topic. That’s why I put extra effort in making my talk more fun for everyone. It worked out &lt;a href=&quot;https://x.com/kentcdodds/status/1903090545729081581&quot;&gt;well&lt;/a&gt;, and the audience was very positive and responsive - what a gift for a speaker!&lt;/p&gt;
&lt;p&gt;This time, I had some minor issues with the microphone during my talk, and while I absolutely hated it, I also love in-person events for exactly this kind of unpredictable and live experience.&lt;/p&gt;
&lt;p&gt;Next stop is &lt;a href=&quot;https://london.cityjsconf.org/&quot;&gt;CityJS London&lt;/a&gt;! I already have a few ideas on how to improve my talk &lt;span&gt;🎉&lt;/span&gt;&lt;/p&gt;
&lt;h4&gt;Popular topics &lt;span&gt;📊&lt;/span&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;The community is split between Next.js flavor of React and a more traditional approach with TanStack Query / React Router&lt;/li&gt;
&lt;li&gt;There is a lot of excitement about TanStack Start&lt;/li&gt;
&lt;li&gt;AI code assistants are the new norm, and Cursor sets the bar high being the most popular option&lt;/li&gt;
&lt;li&gt;Dated codebases with React versions lagging behind are a common theme, as well as lack of testing and time for refactoring&lt;/li&gt;
&lt;li&gt;Performance is a major pain point, too&lt;/li&gt;
&lt;li&gt;Accessibility slowly becomes more mainstream as regulatory pressure grows&lt;/li&gt;
&lt;li&gt;People are curious about local-first approaches&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Organization &lt;span&gt;❤️&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;The event went super smoothly, but I know that it’s the result of hard work by the organizers. I’m impressed and I’m definitely keeping an eye on everything the &lt;a href=&quot;https://x.com/BeJS_&quot;&gt;BeJS&lt;/a&gt; team is doing!&lt;/p&gt;</content:encoded></item><item><title>Full Stack coding interviews - how it was in 2024</title><link>https://kalabro.tech/full-stack-interviews-2024/</link><guid isPermaLink="true">https://kalabro.tech/full-stack-interviews-2024/</guid><description>In this article, I want to  zoom in on coding interviews for Senior Full Stack JavaScript roles at small to medium-sized companies in Europe.</description><pubDate>Fri, 27 Dec 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In this article, I want to zoom in on coding interviews for &lt;strong&gt;Senior Full Stack JavaScript roles at small to medium-sized companies&lt;/strong&gt; (not FAANG!). Below, I share my experiences interviewing for these roles from both sides of the table.&lt;/p&gt;
&lt;h2&gt;Categories of tasks&lt;/h2&gt;
&lt;p&gt;Good news: Most companies can’t afford a super complicated full stack coding task in a typical 1-hour interview. They can’t have too many interview rounds either because both candidates and interviewers are busy.&lt;/p&gt;
&lt;p&gt;As a result, most companies come up with something relatively standard, often not too relevant to the actual role, but certainly manageable after some prep work. I identified five categories (or archetypes) of live coding tasks for Full Stack JavaScript roles.&lt;/p&gt;
&lt;h3&gt;Category 1: Data Structures and Algorithms (DSA)&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎯&lt;/span&gt; Goal: demonstrate confident usage of arrays, loops, hash maps etc.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;From my modest experience, LeetCode-like questions are still very popular in interview pipelines, including for Full Stack roles. While I see them as a waste of time, they do have their benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Programming language independent&lt;/li&gt;
&lt;li&gt;Easy to measure (solved / not solved, in what time, Big O, etc.)&lt;/li&gt;
&lt;li&gt;Large pool of tasks of various levels&lt;/li&gt;
&lt;li&gt;Tests-friendly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prep tips:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Focus on easy (70%) and medium (30%) tasks (&lt;a href=&quot;https://leetcode.com/studyplan/leetcode-75/&quot;&gt;LeetCode 75&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Talk out loud as you solve a problem (imagine you’re streaming on Twitch)&lt;/li&gt;
&lt;li&gt;Use TypeScript (but perhaps solve a couple in plain JS)&lt;/li&gt;
&lt;li&gt;Implement Bubble Sort and Quick Sort from memory (&lt;a href=&quot;https://frontendmasters.com/courses/algorithms/&quot;&gt;ThePrimeagen’s course&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;(Re)read Big O section from the Cracking the Coding Interview book (or alternative)&lt;/li&gt;
&lt;li&gt;Solve a couple of easy problems using lightweight TDD approach&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Because &lt;a href=&quot;https://youtu.be/bZoji7jCSU8?si=6WMkjwv2tLlxSw9f&amp;amp;t=27&quot;&gt;I don’t sort arrays in place&lt;/a&gt; in my normal professional life, this type of task requires the most prep effort from me.&lt;/p&gt;
&lt;p&gt;Real problems from my interviewing experience:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Determine if a given number is a prime number.&lt;br /&gt;
This is one of the first examples in “Cracking the Coding Interview”, and yet people still ask it in interviews as a “sanity check”&lt;/li&gt;
&lt;li&gt;Calculate the N-th number in the Fibonacci sequence.&lt;br /&gt;
I was asked to use my own IDE and took the opportunity to drive the solution with tests, which gave me bonus points with the interviewer&lt;/li&gt;
&lt;li&gt;Return an array of sums of columns in a matrix&lt;/li&gt;
&lt;li&gt;Shift all zeros to the end of an array&lt;/li&gt;
&lt;li&gt;Flatten a deeply nested JS object into a new object with properties in the format “propNameLevel1.propNameLevel2.propNameLevel3”.&lt;br /&gt;
I got lost in recursive calls and failed that round&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Category 2: React (Vue/Angular) exercise&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎯&lt;/span&gt; Goal: demonstrate confident frontend coding&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the role involves React, the pipeline will almost certainly include a React coding exercise.&lt;/p&gt;
&lt;p&gt;Prep tips:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Practice building simple components from scratch, with minimal dependencies&lt;/li&gt;
&lt;li&gt;Try to keep all code in one file for as long as possible. If it gets too long, you are doing it wrong&lt;/li&gt;
&lt;li&gt;Make use of all common hooks. In practice, I’ve only needed useState and useEffect during my interviews, but it’s good to be overprepared&lt;/li&gt;
&lt;li&gt;Reread the entire &lt;a href=&quot;https://react.dev/reference/react/useEffect&quot;&gt;useEffect&lt;/a&gt; documentation page (I learn something new every time!)&lt;/li&gt;
&lt;li&gt;Build a simple Todo app using built-in fetch for data fetching&lt;/li&gt;
&lt;li&gt;Challenge your data fetching implementation for potential race conditions, missing error handling, CORS, slow network support etc.&lt;/li&gt;
&lt;li&gt;Cover your app with different types of tests&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Nothing feels more awkward in a React interview than when a candidate struggles to write &lt;code&gt;useState&lt;/code&gt; without Copilot. A day of prep can make a huge difference.&lt;/p&gt;
&lt;p&gt;Real problems from my interviewing experience:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;React Like Button (&lt;a href=&quot;https://app.codility.com/programmers/trainings/8/react_like_button/&quot;&gt;example&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Redux Shopping Cart (&lt;a href=&quot;https://github.com/reduxjs/redux/tree/master/examples/shopping-cart&quot;&gt;example&lt;/a&gt;) - yes, Redux is still a thing&lt;/li&gt;
&lt;li&gt;React StarRating component&lt;/li&gt;
&lt;li&gt;React Stopwatch component&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Category 3: REST endpoint&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎯&lt;/span&gt; Goal: demonstrate confident backend coding&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Another popular task is to build a REST endpoint and/or read data from it.&lt;/p&gt;
&lt;p&gt;Prep tips:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Build a simple CRUD REST API using two different REST libraries (e.g. Express and Hapi)&lt;/li&gt;
&lt;li&gt;Implement GET, POST, PATCH, DELETE verbs with fake/in-memory data&lt;/li&gt;
&lt;li&gt;Implement basic pagination&lt;/li&gt;
&lt;li&gt;Build a simple endpoint in raw Node.js (for example, streaming a big CSV file)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Real problems from my interviewing experience:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Given a JSON contract, build GET and PUT endpoints&lt;/li&gt;
&lt;li&gt;Fetch data from an external resource, sort and expose via GET endpoint&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Category 4: Take home tasks&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎯&lt;/span&gt; Goal: set the stage for the in-person discussion&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Take home tasks allow companies to go beyond basic fetch, GET and useState by letting candidates spend more time on the task.
Remember that just solving a take home task is not enough to succeed. You need to prepare for further discussion and live code changes.&lt;/p&gt;
&lt;p&gt;Prep tips:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add tests!&lt;/li&gt;
&lt;li&gt;Make sure you are proud of the code you’ve written. A personal touch is a plus too.&lt;/li&gt;
&lt;li&gt;If you had to write a lot of code, reassess. Is there a simpler way?&lt;/li&gt;
&lt;li&gt;Make sure you understand every single line of it.&lt;/li&gt;
&lt;li&gt;Be able to explain every decision you’ve made: libraries, naming, algorithms, testing strategy, etc.&lt;/li&gt;
&lt;li&gt;Come up with a couple of additional features for the task and try to implement them without sharing with the interviewer&lt;/li&gt;
&lt;li&gt;Add tests!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Real problems from my interviewing experience:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Implement search UI by screenshot&lt;/li&gt;
&lt;li&gt;Build markdown editor&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;Category 5: code katas&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎯&lt;/span&gt; Goal: demonstrate professional coding style (testing, debugging, refactoring, pairing, etc.)&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Unlike LeetCode questions where the main goal is to solve the problem, code katas are focused on the process rather than the end result. In fact, many of them are open-ended and can have many “correct” solutions.&lt;/p&gt;
&lt;p&gt;Prep tips:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Practice popular katas (Gilded Rose, String Calculator, Mars Rover, Tennis, Bank Account)&lt;/li&gt;
&lt;li&gt;Practice them again. The whole point of katas is to repeat them again and again to sharpen your skills and uncover nuances.&lt;/li&gt;
&lt;li&gt;Find a community to practice collaborative design and pairing (or organize one)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I haven’t experienced classic code katas in interviews, but I know they are not uncommon. Practicing them can help with other types of tasks too.&lt;/p&gt;
&lt;h3&gt;Mixing categories&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎯&lt;/span&gt; Goal: demonstrate broad set of skills&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;In practice, companies only have an hour or two to assess a candidate’s coding skills. As a workaround, they may come up with a Full Stack task that contains a bit of everything: design a contract, implement custom business rules, expose an API endpoint and render it with React. While it sounds like a lot, the interviewers likely expect simple, standard solutions that you can surely implement.&lt;/p&gt;
&lt;h2&gt;Traits of strong candidates&lt;/h2&gt;
&lt;p&gt;Now that we’ve covered all common categories of live coding tasks, let me share my observations on what makes a Full Stack developer stand out in a live coding interview.&lt;/p&gt;
&lt;h3&gt;Bias, bias, bias&lt;/h3&gt;
&lt;p&gt;A lot of candidates that I liked just played to my biases. They mentioned something I strongly agreed with. They impressed me by writing a reduce function on first try. They named a variable &lt;code&gt;applesauce&lt;/code&gt;, etc. Despite our best efforts to address our biases, interviewing will never be fair and objective.&lt;/p&gt;
&lt;p&gt;Now, to the actual traits.&lt;/p&gt;
&lt;h3&gt;Keep code green&lt;/h3&gt;
&lt;p&gt;Successful candidates tend to test their code often even if there are no actual tests. It can be as simple as refreshing the browser or printing a variable via console.log. As a result, code is always green (runnable), without random typos or unfinished pseudocode.&lt;/p&gt;
&lt;h3&gt;Show off without writing code&lt;/h3&gt;
&lt;p&gt;Candidates often trap themselves when they try to show off. I noticed that strong candidates prefer mentioning unessential code improvements (like useMemo) without actually implementing them. Usually interviewers are happy enough to move on and get an impression that the candidate knows how to code what they’ve just suggested.
I’ve seen multiple times how this helped candidates pivot or extend code quicker because they kept it simple. It’s tempting to extract code into a separate function, file, or component, but great candidates know to delay it until absolutely necessary.&lt;/p&gt;
&lt;h3&gt;Know coding symbols names in English&lt;/h3&gt;
&lt;p&gt;Slow and error-prone coding without an AI assistant can be perceived as confident and professional if accompanied by clear communication of what’s happening. Knowing the names of all the common symbols is essential.&lt;/p&gt;
&lt;h3&gt;Engage the interviewer&lt;/h3&gt;
&lt;p&gt;A coding interview is supposed to focus on code, but at least half of its success lies in great communication. Clarifying the task and expectations, deciding on the approach, nailing the details, offering improvements and opinions - all of that affects how the candidate will be judged. Unfortunately, we all are biased, and what works for one interviewer may not work for another. Great candidates listen to signals from the interviewers and calibrate their communication style accordingly.&lt;/p&gt;
&lt;h3&gt;Confident coding basics&lt;/h3&gt;
&lt;p&gt;It’s difficult for candidates to communicate well if they are stuck mapping one array to another. Fluent knowledge of the basics of the language or framework frees up mental capacity for meaningful communication. For example, in a React exercise, the following can be considered the building blocks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A functional component with typed props&lt;/li&gt;
&lt;li&gt;useState&lt;/li&gt;
&lt;li&gt;useEffect&lt;/li&gt;
&lt;li&gt;Common JS Array functions (map, find, filter)&lt;/li&gt;
&lt;li&gt;Promises and async / await&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If all above sounds trivial, great! Just make sure you can code your way through those basics.&lt;/p&gt;
&lt;h3&gt;Keep a steady pace&lt;/h3&gt;
&lt;p&gt;Time constraint is real and it would be unfair to give “Don’t rush” advice. One has to rush to deliver meaningful results in the interview setting. Still, strong candidates somehow manage to keep a steady pace without creating a sense of rush.&lt;/p&gt;
&lt;h3&gt;Mention tests&lt;/h3&gt;
&lt;p&gt;The harsh reality is that very few developers write tests regularly. Strong candidates know how to bring up the topic of testing without necessarily applying TDD to the task at hand.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;Interviewing for Full Stack roles at small to medium-sized companies has its own specifics. For me, the key is to narrow my prep efforts to the right category of tasks and focus on the basics. Of course, coding interviews are just one part of the job hunting process. I found the recent &lt;a href=&quot;https://docs.google.com/document/d/19fr_36WOzKlq_zyGP2RdxMEsdNQMZdUqn1Vahncr2pY/edit?usp=sharing&quot;&gt;“An Engineering Leader’s Job Search Algorithm”&lt;/a&gt; extremely thorough and relevant. I hope this article complements it well for those who are looking at Senior Full Stack roles specifically.&lt;/p&gt;</content:encoded></item><item><title>“Balancing Coupling in Software Design” (book review)</title><link>https://kalabro.tech/balancing-coupling-in-software-design-book/</link><guid isPermaLink="true">https://kalabro.tech/balancing-coupling-in-software-design-book/</guid><description>Overview of the new Balancing Coupling model with examples and interactive quizzes. Enjoy!</description><pubDate>Mon, 14 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://amzn.to/3BIIPyk&quot;&gt;“Balancing Coupling in Software Design”&lt;/a&gt;, the new book by Vlad Khononov, can be summarised by one logical expression:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BALANCE&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;STRENGTH&lt;/span&gt;&lt;span&gt; XOR&lt;/span&gt;&lt;span&gt; DISTANCE&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;OR&lt;/span&gt;&lt;span&gt; NOT&lt;/span&gt;&lt;span&gt; VOLATILITY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If that seems a bit cryptic, don’t worry. Throughout this article, you’ll have a chance to play with each variable from the expression and get a sneak peek of the Balanced Coupling model. Inspired by Vlad’s approach to balancing theory and practice in his book, I’ve added little quizzes to test your software design intuition. If you’ve already read the book, use them to check yourself!&lt;/p&gt;
&lt;p&gt;Let’s get started with the first variable, or shall we say, dimension of coupling.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#integration-strength&quot;&gt;Integration Strength&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#distance&quot;&gt;Distance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#volatility---coupling-in-the-dimension-of-time&quot;&gt;Volatility - coupling in the dimension of time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#balancing-and-re-balancing&quot;&gt;Balancing and re-balancing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#fractal-geometry-of-software-design&quot;&gt;Fractal geometry of software design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#to-summarise&quot;&gt;To summarise&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Integration Strength&lt;/h2&gt;
&lt;p&gt;At the core of the book is the new model for evaluating the strength of coupling. The stronger the coupling, the more knowledge is shared between modules.&lt;/p&gt;
&lt;p&gt;Try to order Integration Strength levels from strongest to weakest:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;To come up with these levels, the author analysed two existing models from 1970s (&lt;a href=&quot;https://www.goodreads.com/book/show/946145.Structured_Design&quot;&gt;Structured Design&lt;/a&gt;) and 1990s (&lt;a href=&quot;https://www.goodreads.com/book/show/1441004.Practical_Guide_to_Structured_Systems_Design&quot;&gt;Connascence&lt;/a&gt;) and found that not only are they outdated, but they also have significant blind spots. To help us connect with the history, this part of the book includes code samples in Assembly, PL/I, and Fortran.&lt;/p&gt;
&lt;p&gt;Integration Strength inherits the best parts of both mentioned models, modernises them, and addresses some of the gaps.&lt;/p&gt;
&lt;p&gt;Let’s see if you can match situations on the right with their corresponding Integration Strength levels on the left:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;Let’s see how much knowledge is shared between modules in the scenarios above.&lt;/p&gt;
&lt;h3&gt;Intrusive coupling&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Instead of communicating through public interfaces, the downstream module communicates through, and thus depends on, the implementation details of the upstream module&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The strongest level of coupling is all about hacking around to get the job done in ways never intended for integration. Patching an external library requires understanding undocumented internals and keeping the patched behaviour in mind when applying updates. It’s worth mentioning that sometimes it’s the only way to go.&lt;/p&gt;
&lt;h3&gt;Functional coupling&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Functionally coupled modules share the knowledge of the functionalities they are implementing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;From a business perspective, checkout form validation is a single piece of work that must be completed before an order is placed.&lt;/p&gt;
&lt;p&gt;On the technical side, however, a subset of this validation begins on frontend to provide a better user experience with fast visual feedback. If frontend checks pass, it’s time to run full validation on backend. Every time the form changes, both frontend and backend have to stay in sync regarding their validation rules. They are functionally coupled.&lt;/p&gt;
&lt;h3&gt;Model coupling&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Model coupling takes place when the same model of the business domain is used by multiple modules.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If the previous levels share knowledge about behaviour, model coupling only shares knowledge about internal data structures. Typically, they are easier to reason about and change less frequently. In the example above, we used PostgREST to automatically expose a database table as REST API — handy! However, every time we rename or delete columns in our table, our API clients fail.&lt;/p&gt;
&lt;h3&gt;Contract coupling&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Modules are contract coupled if they communicate through an integration-specific model&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As Vlad puts it, a contract is “a model of a model”, a new level of abstraction that reduces amount of shared knowledge to the bare minimum. This makes contract coupling the weakest level of the Integration Strength model.&lt;/p&gt;
&lt;p&gt;In our example above, OAuth 2.0 is a standard protocol for authorization. If you’ve ever worked with it, you may argue that it requires a great deal of knowledge and patience to integrate with it properly.&lt;/p&gt;
&lt;p&gt;I intentionally chose this example to emphasise that contract coupling almost always involves overhead. Let’s revisit the
PostgREST situation. To “upgrade” it to the contract level, we could introduce a database view that would serve as an API contract. This would allow us to evolve the original table structure (internal model) without breaking the API, but we would need to maintain the introduced view.&lt;/p&gt;
&lt;p&gt;Now that we can reason about the first variable in the Balanced Coupling equation, let’s move on to the second one:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BALANCE&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;STRENGTH&lt;/span&gt;&lt;span&gt; XOR&lt;/span&gt;&lt;span&gt; DISTANCE&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;OR&lt;/span&gt;&lt;span&gt; NOT&lt;/span&gt;&lt;span&gt; VOLATILITY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Distance&lt;/h2&gt;
&lt;p&gt;Again, let’s start with a quiz. Sort the following encapsulation boundaries from the least to the most distant:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;In addition to the levels listed above, there are hidden levels that we humans create when working in groups.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The greater the &lt;strong&gt;ownership distance&lt;/strong&gt;, the higher the coordination effort needed to implement changes affecting multiple modules. Consequently, the perceived distance between the modules also increases accordingly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;For example, full stack web developers often reduce the distance between frontend and backend by using monorepos, sharing types, or even pieces of code between the two services. Sometimes this works out great, while other times it turns into a nightmare.&lt;/p&gt;
&lt;p&gt;Returning to the Balance equation, it has something to do with &lt;code&gt;STRENGTH XOR DISTANCE&lt;/code&gt;. Time to look deeper!&lt;/p&gt;
&lt;p&gt;You may have noticed that the expression uses boolean values. This is good enough for grasping the main trends. The book also introduces a hypothetical numeric scale to illustrate the nuances.&lt;/p&gt;
&lt;p&gt;Map boolean Strength and Distance values to the corresponding situations on the left:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;Let’s walk through all the combinations of &lt;code&gt;STRENGTH&lt;/code&gt; and &lt;code&gt;DISTANCE&lt;/code&gt; to see what we find. Click on the blurred items below to reveal the answers.&lt;/p&gt;




















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;Low distance&lt;/th&gt;&lt;th&gt;High distance&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Low strength&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;High strength&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Red items above reflect complexity while green ones contribute to modularity of the system. Apparently,&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;STRENGTH&lt;/span&gt;&lt;span&gt; XOR&lt;/span&gt;&lt;span&gt; DISTANCE&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; MODULARITY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Of course, the book goes deeper into the topics of modularity and abstractions, referencing Dijkstra, David Parnas, and John Ousterhout! It does the same with the topic of complexity by looking at phenomena from various angles including the Cynefin framework.&lt;/p&gt;
&lt;p&gt;For now, let’s move on to the final variable in the equation:&lt;/p&gt;
&lt;h2&gt;Volatility - coupling in the dimension of time&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Imagine a strongly coupled system. One, in which all components share excessive and extraneous knowledge across their boundaries. Even intrusive coupling is there. […] But if the components will never change, does the potential for cascading changes even matter?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Volatility reflects the frequency with which a software module changes. But how can we predict the frequency of changes without knowing future requirements? Vlad, who also happens to be the author of &lt;a href=&quot;https://www.goodreads.com/book/show/57573212-learning-domain-driven-design&quot;&gt;one of the best books on Domain-Driven Design&lt;/a&gt;, suggests deriving volatility from the type of DDD subdomain. The new book also includes a quick recap of DDD subdomain types if you need a refresher.&lt;/p&gt;
&lt;p&gt;Now, try to guess expected volatility for each subdomain type:&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Subdomain&lt;/th&gt;&lt;th&gt;Competitive Advantage&lt;/th&gt;&lt;th&gt;Complexity&lt;/th&gt;&lt;th&gt;Volatility&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Core&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Generic&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Low&lt;/td&gt;&lt;td&gt;High&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Supporting&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Low&lt;/td&gt;&lt;td&gt;Low&lt;/td&gt;&lt;td&gt;&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;It’s worth noting that as the business evolves, new subdomains may emerge, and existing ones may change in type. In addition, volatility can be influenced by team communication patterns, reorgs, and growth.&lt;/p&gt;
&lt;h2&gt;Balancing and re-balancing&lt;/h2&gt;
&lt;p&gt;Back to the Balance equation, it’s time to put all the variables together:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BALANCE&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;span&gt;STRENGTH&lt;/span&gt;&lt;span&gt; XOR&lt;/span&gt;&lt;span&gt; DISTANCE&lt;/span&gt;&lt;span&gt;) &lt;/span&gt;&lt;span&gt;OR&lt;/span&gt;&lt;span&gt; NOT&lt;/span&gt;&lt;span&gt; VOLATILITY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We’ve already discovered that the first part of the equation means modularity, the opposite of complexity:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;BALANCE&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; MODULARITY&lt;/span&gt;&lt;span&gt; OR&lt;/span&gt;&lt;span&gt; NOT&lt;/span&gt;&lt;span&gt; VOLATILITY&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;BALANCE&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; NOT&lt;/span&gt;&lt;span&gt; COMPLEXITY&lt;/span&gt;&lt;span&gt; OR&lt;/span&gt;&lt;span&gt; NOT&lt;/span&gt;&lt;span&gt; VOLATILITY&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is one more way to express it. Give it a try:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;p&gt;Volatility makes modularity optional. It’s okay to have a big ball of mud as long as it rarely changes. In other cases, we can tune strength and distance to achieve modularity. Examples of balancing (and rebalancing) are my favourite part of the book!&lt;/p&gt;
&lt;p&gt;Since in this article I want to share my understanding of the book, I’ve prepared my own example.&lt;/p&gt;
&lt;h3&gt;Example: abandoned component library&lt;/h3&gt;
&lt;p&gt;The team is working on a new frontend for a project and realises that there will, in fact, be two different frontend applications sharing the same backend and visual language.
To address this requirement the team identifies the following parts, each in its own repository:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Backend&lt;/strong&gt; at backend.acme.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI component library&lt;/strong&gt; at styleguide.acme.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frontend 1&lt;/strong&gt; at shop.acme.com&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frontend 2&lt;/strong&gt; at journal.acme.com&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In theory, everything looks great. Each part is independently deployable, and the same visual language is promoted by the centralised component library.&lt;/p&gt;
&lt;p&gt;However, the component library soon started to lag behind the actual look and feel of the application. In one instance, the design team was late for the demo and delivered
a large piece of visuals without identifying atomic components. As a result, the developed UI components were not optimised for reuse.&lt;/p&gt;
&lt;p&gt;In another instance, a tiny visual glitch was fixed directly in the application instead of being promoted to the component library.&lt;/p&gt;
&lt;p&gt;Slowly, more and more visual work was done directly in applications code. The product team began raising concerns about visual inconsistencies and duplicated work between the two frontend applications. The UI library was practically abandoned. What happened?&lt;/p&gt;
&lt;h4&gt;High distance&lt;/h4&gt;
&lt;p&gt;In the initial design, all parts were equally distanced from each other by using different repositories. For example, the distance between Frontend 1 and UI component library was the same as the distance between Frontend 1 and backend.&lt;/p&gt;
&lt;p&gt;At the same time, team structure didn’t quite reflect this, with one backend team and one frontend team (owning all frontend).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;DISTANCE = High (True)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Functional coupling&lt;/h4&gt;
&lt;p&gt;In the Integration Strength dimension, every frontend feature required changes in two repositories: the UI component library and the application itself. The idea was to organically grow the UI component library as part of the applications development. That meant constant switching between the two repositories:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Make a change to the UI component library&lt;/li&gt;
&lt;li&gt;Release&lt;/li&gt;
&lt;li&gt;Make a change to the application&lt;/li&gt;
&lt;li&gt;Realise the UI component has to be slightly adjusted&lt;/li&gt;
&lt;li&gt;Repeat&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;STRENGTH = High (True)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;Volatility&lt;/h4&gt;
&lt;p&gt;While the complexity of the frontend applications wasn’t high, they had to evolve at extreme pace: all new features were first implemented as frontend experiments, and only after validating user interest were they properly built on backend.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;VOLATILITY = High (True)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As you can see, all three variables are high, indicating that the system is not balanced. In fact, this state of the system is called &lt;em&gt;pain&lt;/em&gt;, or, in other words, high maintenance effort. Time for another quiz: try to complete the following equation:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;h4&gt;Self-regulation&lt;/h4&gt;
&lt;p&gt;Without realising it, the team “rebalanced” the system by quietly abandoning the UI component library.&lt;/p&gt;
&lt;h4&gt;Better solution&lt;/h4&gt;
&lt;p&gt;The self-regulation caused issues with product quality. To mitigate this, the team reduced the distance between the UI component library and the frontend applications by merging all frontend repositories into one monorepo. Coincidentally, this also reduced the distance between the two frontend applications. But that’s a story for another time.&lt;/p&gt;
&lt;p&gt;The book contains dozens of detailed examples and case studies that help to fully understand the Balanced Coupling model. In a couple of them, the author admits that rebalancing doesn’t always bring value; local complexity reappears at a higher level as global complexity and vice versa. Luckily, the solution is right in front of us:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Fractal geometry is nature’s way of mitigating complexity.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Fractal geometry of software design&lt;/h2&gt;
&lt;p&gt;Early in the book, Vlad draws our attention to a rather obvious fact:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A system’s component is almost always a subsystem in its own right. It consists of its own internal components, interacting to achieve its goal. Or, as Tim Berners-Lee put it, any system is a component in another, larger system&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Closer to the end, the book beautifully connects this idea with the new coupling model by introducing Fractal Modularity. Regardless of the level of abstraction we operate at, Balanced Coupling serves as a &lt;em&gt;self-similarity principle&lt;/em&gt; at all levels.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;Before discovering the Balanced Coupling model, I had a very vague understanding of the coupling phenomena.&lt;/p&gt;
&lt;p&gt;Once, I was asked to duplicate an algorithm for calculating premium subscription in two different microservices. It was the easiest way to get job done - copy paste 3 lines of code. The system in question was in the process of decoupling from the legacy monolith, and we were going to make it worse by duplicating business logic in two separate modules owned by two different teams. Not knowing how to convince the teams to rethink the approach, I simply gave up.&lt;/p&gt;
&lt;p&gt;The “Balanced Coupling” book refines our engineering language, enabling more productive conversations not only about coupling, but also about complexity, modularity, maintenance, stability, cost, growth, and innovation. Now it’s our turn to have these conversations, apply the new model in practice, and see how it works.&lt;/p&gt;
&lt;p&gt;Thanks for making it this far! I hope you enjoyed the little quizzes. Here’s the last one for today:&lt;/p&gt;
&lt;em&gt;Interactive content is not supported in RSS&lt;/em&gt;
&lt;h3&gt;Resources&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;📙&lt;/span&gt; &lt;a href=&quot;https://amzn.to/3BIIPyk&quot;&gt;Balancing Coupling in Software Design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;📹&lt;/span&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=KTy4rqgPOjg&quot;&gt;Balancing Coupling in Software Design - Vlad Khononov - DDD Europe 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;📹&lt;/span&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=1ZyR_tgGTp8&quot;&gt;The Fractal Geometry of Software Design - Vlad Khononov - DDD Europe 2022&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;span&gt;💡&lt;/span&gt; &lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;“Learning Domain-Driven Design” - the software architecture 🐒 book that makes sense&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>React Alicante 2024</title><link>https://kalabro.tech/react-alicante-2024/</link><guid isPermaLink="true">https://kalabro.tech/react-alicante-2024/</guid><description>Full list of talks with my short comments.</description><pubDate>Wed, 25 Sep 2024 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On this page, you can find a full list of all &lt;a href=&quot;https://reactalicante.es/&quot;&gt;React Alicante 2024&lt;/a&gt; talks with my short comments. A longer opinionated summary at the end.&lt;/p&gt;
&lt;p&gt;Enjoy and feel free to reuse it if you need a summary for your team or employer.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-1&quot;&gt;Sessions - Day 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-2&quot;&gt;Sessions - Day 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#my-summary&quot;&gt;My summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sessions - Day 1&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;17 high quality talks on React Server Components, Astro, SolidJS, a11y, and good old CSS!&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Composition is King by Chance Strickland&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://x.com/chancethedev&quot;&gt;&lt;strong&gt;@chancethedev&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Despite the fact that React is shifting to the server, its core principles, &lt;strong&gt;composition&lt;/strong&gt; and &lt;strong&gt;UI as a function of state&lt;/strong&gt;, won’t go anywhere.&lt;/p&gt;
&lt;h3&gt;Enhancing Forms with React Server Components and React 19 by Aurora Scharff&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://x.com/aurorascharff&quot;&gt;&lt;strong&gt;@aurorascharff&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://speakerdeck.com/aurorascharff/enhancing-forms-with-react-server-components&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;A hands on demo of server components and actions in Next.js. Aurora popularizes RSC in her talks, workshops, and &lt;a href=&quot;https://aurorascharff.no/&quot;&gt;a blog&lt;/a&gt; where she publishes in-depth RSC guides. She also recommended me a &lt;a href=&quot;https://youtu.be/4wOqpPdR1tg?si=AFMRpjZ5Q2lFJj4E&quot;&gt;case study talk from Tomas Jansson&lt;/a&gt; as an example of RSC in production (of course, in Next.js).&lt;/p&gt;
&lt;h3&gt;Debugging JS and React by Mark Erikson&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://x.com/acemarke&quot;&gt;&lt;strong&gt;@acemarke&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://blog.isquaredsoftware.com/presentations/2023-06-debugging-js/?slideIndex=0&amp;amp;stepIndex=0&quot;&gt;older version of slides from 2023&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;A good refresher on debugging techniques from Redux maintainer. I’ve never used &lt;code&gt;console.table()&lt;/code&gt; or &lt;code&gt;console.count()&lt;/code&gt; before. &lt;code&gt;console.timeStamp()&lt;/code&gt; should be handy in profiling, too.&lt;/p&gt;
&lt;h3&gt;Building Complex UI with State Machines by Erik Rasmussen&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://x.com/erikras&quot;&gt;&lt;strong&gt;@erikras&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://github.com/erikras/search-state-machine&quot;&gt;code&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Erik, who is most famous for &lt;a href=&quot;https://github.com/redux-form/redux-form&quot;&gt;redux-form&lt;/a&gt; and &lt;a href=&quot;https://github.com/final-form/final-form&quot;&gt;final-form&lt;/a&gt;, walked us through building a state machine for a search form using &lt;a href=&quot;https://github.com/statelyai/xstate&quot;&gt;XState&lt;/a&gt;. In his unique style, he made me, my teammates and probably the whole audience fall in love with XState.&lt;/p&gt;
&lt;h3&gt;Astro Studio - All Secrets Reveiled by Elian Van Cutsem&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;http://x.com/eliancodes&quot;&gt;&lt;strong&gt;@eliancodes&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://github.com/ElianCodes/astro-ama-demo&quot;&gt;code&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;An overview of all the latest Astro features: &lt;a href=&quot;https://astro.build/blog/goodbye-astro-studio/&quot;&gt;Astro Studio sunset and Astro DB&lt;/a&gt;, &lt;a href=&quot;https://astro.build/blog/astro-4120/#experimental-server-islands&quot;&gt;server islands&lt;/a&gt; and &lt;a href=&quot;https://astro.build/blog/astro-490/#react-19-support&quot;&gt;actions&lt;/a&gt;, &lt;a href=&quot;https://starlight.astro.build/&quot;&gt;Astro Starlight&lt;/a&gt;, &lt;a href=&quot;https://astro.build/blog/community-loaders/&quot;&gt;community loaders&lt;/a&gt;, and I likely forgot something. Astro 5 is in beta, but the only missing bit is stable Vite 6 release.&lt;/p&gt;
&lt;h3&gt;The A1lyboros (maximizing code accessibility with Copilot) by Alena Nikolaeva &amp;amp; David Jensenius&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/alenanik11&quot;&gt;&lt;strong&gt;@alenanik11&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://pitch.com/v/maximizing-code-accessibility-with-ai-assistants-c444mr&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;The only way to ensure accessibility is through thorough manual testing. The speakers, who both work on Copilot at Github, raised the problem of bias in large language models. AI code generators don’t guarantee accessibility, but they still can be helpful for exploring the topic. Get started with this prompt shared by the speakers:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;I need to learn about accessibility and need to write code that conforms with the WCAG 2.1 level A and AA&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;success criteria defined at https://www.w3.org/TR/WCAG21/. I want you to be my accessibility coach, a&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;subject-matter expert that makes me think and account for all accessibility requirements and usability&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;enhancements. When you answer questions about accessibility please use reputable sources such as w3.org,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;webaim.org, developer.mozilla.org, and https://www.ibm.com/able/. When possible, please provide links and&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;references for additional learning. When you suggest code please use semantic HTML, ensure it is operable&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;using the keyboard, follow WCAG 2.1 sufficient techniques, and follow the ARIA Authoring Practices Guide&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;and related design patterns. Do you understand these instructions?&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Enhancing your Static Sites with React Server Components by Akash Hamirwasia&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/blenderskool&quot;&gt;&lt;strong&gt;@blenderskool&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Every static site eventually needs more dynamic data fetching, and it’s historically been a pain. On a simple example, Akash demonstrates how RSC dramatically simplify the process and render previous tricks like &lt;code&gt;useStaticQuery&lt;/code&gt; from Gatsby or &lt;code&gt;getStaticProps&lt;/code&gt; from Next.js obsolete. An earlier version of this talk is available in &lt;a href=&quot;https://akashhamirwasia.com/talks/enhancing-static-sites-with-react-server-components-react-nexus/&quot;&gt;the author’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Making your own tRPC-like library by Gabriel Grubba&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/gab_grubba&quot;&gt;&lt;strong&gt;@gabrielgr&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;With end-to-end type safety provided by tools like tRPC, you can “dot your way into it” without ever leaving your IDE. But how does tRPC work? Gabriel suggests implementing one yourself to understand the magic. The constraints of a lightning talk, unfortunately, didn’t allow me to catch the details.&lt;/p&gt;
&lt;h3&gt;Diagrams you need to know by Jenny Truong&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/jen_ayy_&quot;&gt;&lt;strong&gt;@jen_ayy_&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://noti.st/jennytru/fIkAen/diagrams-you-need-to-know&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Non-technical lightning talk from a stately team member with tons of links to diagram drawing services. I only managed to capture &lt;a href=&quot;https://dbdiagram.io/&quot;&gt;https://dbdiagram.io/&lt;/a&gt; and &lt;a href=&quot;https://www.tldraw.com/&quot;&gt;https://www.tldraw.com/&lt;/a&gt;. Checkout the slides for more!&lt;/p&gt;
&lt;h3&gt;Using events and modern state management tools to clean up local-first logic by Wojciech Ogrodowczyk&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/sharnik&quot;&gt;&lt;strong&gt;@sharnik&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://pitch.com/v/react-alicante-wojciech-p7utf2&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;What makes some products really great? They solve a hard problem for their users, often employing a non-obvious technical approach, like event sourcing for an imaginary TODO app. As another example, Wojciech references &lt;a href=&quot;https://www.youtube.com/watch?v=VLgmjzERT08&quot;&gt;a talk from Liner about local-first approach&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Dude where is my password? by Miquel Company&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/solilokiam&quot;&gt;&lt;strong&gt;@solilokiam&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://whereismypassword.vercel.app/&quot;&gt;demo&lt;/a&gt; / &lt;a href=&quot;https://github.com/solilokiam/whereismypassword&quot;&gt;repo&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Miquel explained how passkeys work by building an app with &lt;a href=&quot;https://github.com/MasterKale/SimpleWebAuthn&quot;&gt;SimpleWebAuthn&lt;/a&gt; and Next.js. While passwordless approach is much more secure, Miquel admitted that after years of memorizing passwords, users don’t feel confident in getting rid of them. Popularization talks like his are a great way to spread the word.&lt;/p&gt;
&lt;h3&gt;Let’s build everything! The chaos of pet projects by Mikhail Korolev&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/mkrl__&quot;&gt;&lt;strong&gt;@mkrl__&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://docs.google.com/presentation/d/1AeJ0uVkwnVYmFt6eKRcsoDangpwZbqS3ixks8d1ZwrU/edit?usp=sharing&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;A mix of art and technology from someone who broke two arms in an bicycle accident just before the conference. Misha is the king of pet projects and shared how he manages his projects from the initial idea to the finish line. Talks like this make in-person conferences special, and it’s impossible to fully capture their vibe in text or video.&lt;/p&gt;
&lt;h3&gt;How to make cheap e2e tests by Anastasiia Dragich&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/nastia_dragich&quot;&gt;&lt;strong&gt;@nastia_dragich&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Playwright won, and we all run hours of end-to-end tests in our CI pipelines. Nastia shared how she makes them much faster by mocking backend APIs. She calls this type of tests “isolated integration tests”. I also learned that Playwright has &lt;code&gt;webServer&lt;/code&gt; config to start background processes before running tests.&lt;/p&gt;
&lt;h3&gt;3D Models on the Web with React Three Fiber by Thomas Derflinger&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Web:&lt;/strong&gt; &lt;a href=&quot;https://tderflinger.com/&quot;&gt;https://tderflinger.com/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An interactive intro into React Three Fiber for rendering 3D models in the browser. Thomas also has &lt;a href=&quot;https://tderflinger.com/en/react-three-fiber-displaying-gltf-model&quot;&gt;a blog post&lt;/a&gt; on the same topic.&lt;/p&gt;
&lt;h3&gt;A Schema is all you need! by Mattia Manzati&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/MattiaManzati&quot;&gt;&lt;strong&gt;@MattiaManzati&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://mattiamanzati.github.io/schema-is-all-you-need/1&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Yes, TypeScript is great, but it doesn’t help in the good old JavaScript runtime. Solutions like &lt;a href=&quot;https://zod.dev/&quot;&gt;zod&lt;/a&gt; improve the situation, but don’t fully solve it. Mattia demos the power of &lt;a href=&quot;https://effect.website/docs/guides/schema/introduction&quot;&gt;&lt;code&gt;@effect/schema&lt;/code&gt;&lt;/a&gt; by building an encoder and decoder for a simple Todo item schema. I also learned about property-based testing with &lt;a href=&quot;https://fast-check.dev/&quot;&gt;fast-check&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Signals: What, How, and Why! by Atila Fassina&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/atilafassina&quot;&gt;&lt;strong&gt;@atilafassina&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Atila stepped up on short notice to replace a cancelled talk and delivered a high-quality deep dive into signals in SolidJS and beyond. I learned about lazy vs eager signals, performance optimizations in Solid and upcoming &lt;a href=&quot;https://hack.solidjs.com/&quot;&gt;SolidHack&lt;/a&gt; event.&lt;/p&gt;
&lt;h3&gt;One App Fits All: Building Responsive Experiences in React by Kateryna Porshnieva&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/krambertech&quot;&gt;&lt;strong&gt;@krambertech&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kateryna reminded us that we may not need JS at all with the power of modern CSS. She built a responsive app interface using &lt;a href=&quot;https://utopia.fyi/&quot;&gt;Utopia&lt;/a&gt; fluid design approach, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/clamp&quot;&gt;clamp()&lt;/a&gt; CSS function, CSS grid, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_containment/Container_queries&quot;&gt;container queries&lt;/a&gt;, &lt;a href=&quot;https://caniuse.com/ch-unit&quot;&gt;ch units&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media/hover&quot;&gt;hover&lt;/a&gt;, &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media/pointer&quot;&gt;pointer&lt;/a&gt;, and &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/CSS/@media/prefers-reduced-motion&quot;&gt;prefers-reduced-motion&lt;/a&gt; media queries. As an example of UI that does require JS, Kateryna built a fully fluid navigation bar using &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver&quot;&gt;ResizeObserver&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Sessions - Day 2&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Another 17 talks on React 19, TypeScript, React Native, soft skills and more&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;useWat by David Khourshid&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/DavidKPiano&quot;&gt;&lt;strong&gt;@DavidKPiano&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;React library (or framework?) is far from being perfect. With humor and kindness, the author of &lt;a href=&quot;https://github.com/statelyai/xstate&quot;&gt;XState&lt;/a&gt; walked us through some of the weirdest React parts that we learned to accept as a norm. In all this mess, it’s best to stop worrying about the latest React features and instead focus on building great products for our users.&lt;/p&gt;
&lt;h3&gt;From Chaos to Clarity: Design Patterns for Scalable Software by Joana Santos&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/joanamcsa&quot;&gt;&lt;strong&gt;@joanamcsa&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nobody expected a design patterns talk to include YMCA dance and life advice on how to be yourself. Joana definitely knows how to keep the audience engaged.&lt;/p&gt;
&lt;h3&gt;Type-Safe React with OCaml: A Practical Guide by Dillon Mulroy&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/dillon_mulroy&quot;&gt;&lt;strong&gt;@dillon_mulroy&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dillon shared his passion for OCaml and walked us through a simple OCaml code example. OCaml ecosystem is rapidly evolving and becomes more approachable thanks to the tools like &lt;a href=&quot;https://github.com/dmmulroy/create-melange-app&quot;&gt;create-melange-app&lt;/a&gt; created by Dillon.&lt;/p&gt;
&lt;h3&gt;Full Stack Form Validation with React Server Actions by Evyatar Alush&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/evyataral&quot;&gt;&lt;strong&gt;@evyataral&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The author of a very interesting form validation framework &lt;a href=&quot;https://github.com/ealush/vest&quot;&gt;Vest&lt;/a&gt; gave us a live demo of how to get started with it. Server actions supported!&lt;/p&gt;
&lt;h3&gt;Continuous Improvements of The Code Review Process by Keren Kenzi&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Blog:&lt;/strong&gt; &lt;a href=&quot;https://medium.com/@KerenKenzi&quot;&gt;https://medium.com/@KerenKenzi&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An overview of code review practices, also available in &lt;a href=&quot;https://medium.com/@KerenKenzi/continuous-improvements-of-the-code-review-process-b776893aba4a&quot;&gt;Keren’s blog&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Chaos Mode - Finding &amp;amp; Fixing Race Conditions by Forbes Lindesay&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/ForbesLindesay&quot;&gt;&lt;strong&gt;@ForbesLindesay&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://www.slideshare.net/slideshow/chaos-mode-finding-fixing-race-conditions/271996157&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Forbes provided a great visual explanation of a race condition bug using a search-as-you-type widget as an example. He suggested a method to catch race conditions by introducing random fetch delays, which he calls “Chaos Mode”. Then, he showed the wrong, the right and the fast ways to fix the issue. State machines are mentioned again!&lt;/p&gt;
&lt;h3&gt;React is turning 19! by Nikhil Sharma&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/niksharma1997&quot;&gt;&lt;strong&gt;@niksharma1997&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An overview of all the latest React 19 features including React Compiler (which is not part of React 19, technically speaking).&lt;/p&gt;
&lt;h3&gt;From mentee to mentor: the art of asking questions that accelerate careers by Kate Marshalkina&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/kalabro&quot;&gt;&lt;strong&gt;@kalabro&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://youtu.be/bZoji7jCSU8?si=1iHKnIBFaG12umjO&quot;&gt;video&lt;/a&gt;, &lt;a href=&quot;./slides/from%20mentee%20to%20mentor%20-%20Kate%20Marshalkina%20-%202024.pdf&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;I had the pleasure of giving a lightning talk, which can be summarized as: “Don’t give advice, ask more questions.” More on my speaker experience at the end of the post.&lt;/p&gt;
&lt;h3&gt;Covid fairytale: Building a React Native App to find a toilet roll during pandemic by Aris Markogiannakis&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/arismarko&quot;&gt;&lt;strong&gt;@arismarko&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://www.canva.com/design/DAD6TaBCdys/CihHkJErEGIy4Ls7U5B9Uw/view?utm_content=DAD6TaBCdys&amp;amp;utm_campaign=designshare&amp;amp;utm_medium=link&amp;amp;utm_source=viewer&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;A story of building a fun React Native app as React developer including some details on Prisma and Expo.&lt;/p&gt;
&lt;h3&gt;Speed at Scale: Optimizing The Largest CX Platform Out There by Matheus Albuquerque&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/ythecombinator&quot;&gt;&lt;strong&gt;@ythecombinator&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://speakerdeck.com/ythecombinator/react-alicante-2024&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;While conferences focus on bright new things, at work we often deal with legacy codebases, outdated tools, and slow applications. Matheus shared an in-depth case study on optimizing the performance of a large legacy app (React 15, Webpack 1, Node 10). The content was too extensive for a lightning talk, but fortunately, the slides contain all the references. Highly recommended!&lt;/p&gt;
&lt;h3&gt;The easy way to Full Stack by Dani Coll&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dani-coll&quot;&gt;&lt;strong&gt;@dani-coll&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Dani sets the stage by sharing dozens of full stack job postings in companies of all sizes. Despite common view, companies do hire full stack engineers. It can be an interesting and fulfilling career path but how to get there? By following our interests and picking small tasks at work beyond our common responsibilities.&lt;/p&gt;
&lt;h3&gt;Sweet, savory, and fresh! Accessible design system Storybook tests by Kathleen McMahon&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/resource11&quot;&gt;&lt;strong&gt;@resource11&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kathleen made us all smile even though &lt;a href=&quot;https://webaim.org/projects/million/&quot;&gt;the stats&lt;/a&gt; she shared were not so fun: the more aria labels developers add to webpages, the more accessibility issues they introduce. One way to improve accessibility of React components is to use Storybook built-in tools. They can’t replace manual testing, but at least it’s a good start.&lt;/p&gt;
&lt;h3&gt;Types, TypeScript and the JIT by Daniel Minor&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/dminor&quot;&gt;&lt;strong&gt;@dminor&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://docs.google.com/presentation/d/1ij_oHImk6UgWpW_vYIQB9wDYeCsbI63MdtfmaFhTRls/mobilepresent#slide=id.g2fe5656cdaa_0_0&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Daniel works on SpiderMonkey, a JavaScript engine that powers Firefox. In his lightning talk, he touched on the theory of types, soundness vs completeness, and how a JavaScript engine executes our code.&lt;/p&gt;
&lt;h3&gt;The Shape of Frameworks to Come by Daniel Afonso&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/danieljcafonso&quot;&gt;&lt;strong&gt;@danieljcafonso&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An intro to SolidStart, a meta-framework for SolidJS. In contrast to some other frameworks, it aims to mitigate the vendor lock-in issue by using a composable architecture, where each piece can be replaced with a different implementation.&lt;/p&gt;
&lt;h3&gt;How you can Server-Render without Rendering on the Server by Eric Vicenti&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://x.com/EricVicenti&quot;&gt;&lt;strong&gt;@EricVicenti&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Eric presented &lt;a href=&quot;https://rise.tools/&quot;&gt;Rise Tools&lt;/a&gt;, a framework for building mobile apps that are heavily controlled by the server. With a live coding demo, we all saw in action how a mobile app can be updated in real time. Very cool! If Rise Tools takes off, we will have a new way to quickly build and test our mobile app ideas.&lt;/p&gt;
&lt;h3&gt;Evolving Game Development with Genetic Algorithms by Kevin Maes&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://twitter.com/kvmaes&quot;&gt;&lt;strong&gt;@kvmaes&lt;/strong&gt;&lt;/a&gt; (&lt;a href=&quot;https://noti.st/kvmaes/cLmMPq/evolving-game-development-with-genetic-algorithms&quot;&gt;slides&lt;/a&gt;)&lt;/p&gt;
&lt;p&gt;Kevin shared how he built a game using genetic algorithms to evolve the complexity of game levels. It was fun to listen to his story full of interesting learnings, little details, and funny episodes. I’m impressed by the amount of work required to build a game from scratch. All code is available on &lt;a href=&quot;https://github.com/kevinmaes/eggdrop&quot;&gt;Github&lt;/a&gt;. Of couse, powered by XState!&lt;/p&gt;
&lt;h3&gt;The Illusion of Success: When Delivering on Time is not Everything by Paulina Chojnowska&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://www.slideshare.net/slideshow/the-illusion-of-success-when-delivering-on-time-is-not-everything/272020020&quot;&gt;&lt;strong&gt;Slides&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A lot of wisdom about software development processes delivered through a set of funny stories. As a community, we all agree on the importance of work-life balance, the dangers of tech debt, the power of prioritization, and the synergies of teamwork. Yet, things often go wrong. Paulina’s talk was a great reminder that our jobs are not only about code. That’s why we probably won’t be replaced by AI anytime soon.&lt;/p&gt;
&lt;h2&gt;My summary&lt;/h2&gt;
&lt;p&gt;React Alicante is known for its smooth organization, international speakers, and a long list of diverse talks. This year, the conference hosted 18 full talks, 16 lightning talks, and 12 workshops—a massive volume of content! Many speakers, sponsors and attendees return year after year, which is a sign of a great community. For me, it was the second React Alicante in a row, and this time I returned with a lightning talk!&lt;/p&gt;
&lt;h4&gt;Speaker experience &lt;span&gt;📣&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;I’m extremely greatful to the conference organizers for the opportunity to speak. It was interesting and challenging to prepare a 10 min non-technical session on a topic that I could talk about for hours. Inspired by several other talks (&lt;a href=&quot;https://www.youtube.com/watch?v=KCQ7FAsZCHM&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=Kl0rmx7aa0w&quot;&gt;2&lt;/a&gt;), I decided to build my presentation around one simple idea: ask more questions. This way I could keep it focused and hopefully useful even for people who were not interested in mentorship.&lt;/p&gt;
&lt;p&gt;If you want to learn more about my mentorship experience, please check out my article &lt;a href=&quot;https://kalabro.tech/where-to-find-mentor-2023/&quot;&gt;“Where to find a mentor”&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Technical issues &lt;span&gt;☠️&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;This year, I paid more attention to technical issues because I was concerned about them as a speaker. It turned out that a tiny technical issue can ruin a talk. As a speaker, it’s easy to start panicking and lose the vibe. The audience quickly picks up on this and becomes disengaged. Experienced speakers had video recordings of their live coding pieces in case something went wrong.&lt;/p&gt;
&lt;h4&gt;Popular topics &lt;span&gt;📊&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;Unlike last year, &lt;strong&gt;React Server Components&lt;/strong&gt; were mentioned in every other talk, sometimes with a fair dose of skepticism due to the Next.js situation. &lt;strong&gt;TypeScript&lt;/strong&gt; without any doubt became a first-class citizen in the React ecosystem. &lt;strong&gt;XState&lt;/strong&gt; was a very popular topic too.&lt;/p&gt;
&lt;p&gt;AI was present, but mostly in the form of jokes. Irrelevant Copilot suggestions during live coding demos made people smile.&lt;/p&gt;
&lt;h4&gt;Videos &lt;span&gt;🎥&lt;/span&gt;&lt;/h4&gt;
&lt;p&gt;All sessions were recorded and will be available on YouTube. While waiting, please feel free to check out &lt;a href=&quot;https://www.youtube.com/watch?v=35u6CMh5IJM&amp;amp;list=PLd7nkr8mN0sVkr3aRy-TZjh8jbjdUENrA&quot;&gt;videos&lt;/a&gt; and &lt;a href=&quot;https://kalabro.tech/react-alicante-2023/&quot;&gt;my report&lt;/a&gt; from 2023.&lt;/p&gt;</content:encoded></item><item><title>Tidy first? (book review)</title><link>https://kalabro.tech/tidy-first/</link><guid isPermaLink="true">https://kalabro.tech/tidy-first/</guid><description>My highlights from the first in the series of books on software design by Kent Beck</description><pubDate>Sun, 21 Jan 2024 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://www.goodreads.com/book/show/171691901-tidy-first&quot;&gt;Tidy First?&lt;/a&gt; sets a new standard for software design books. The author, Kent Beck, proves that it’s possible to write about software design in a concise and practical style. Reading it was a pure joy, and I’m looking forward to the next parts.&lt;/p&gt;
&lt;p&gt;Below are a few highlights from my reading. For a more comprehensive review and three full chapters from the book, check out &lt;a href=&quot;https://newsletter.pragmaticengineer.com/p/dead-code-getting-untangled-and-coupling&quot;&gt;this article by Gergely Orosz&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Human-centred&lt;/h2&gt;
&lt;p&gt;Throughout the book, Kent offers several definitions of software design, with the following being reiterated a few times:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software design is an exercise in human relationships.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The first book in the series focuses on the programmer’s relationship with themself. We all can afford 30 min for tidying up between the tasks to make our own coding experience more pleasant.&lt;/p&gt;
&lt;p&gt;Start with yourself.&lt;/p&gt;
&lt;p&gt;Leave the code a little better than you found it.&lt;/p&gt;
&lt;p&gt;The book presents 15 types of tidyings and explains how these can be integrated into a programmer’s day-to-day without much hassle.&lt;/p&gt;
&lt;p&gt;The next books in the series promise an even stronger emphasis on human relationships as Kent plans to zoom out to team-level and organization-level software design activities.&lt;/p&gt;
&lt;p&gt;“All problems are interpersonal relationship problems” from “&lt;a href=&quot;https://www.goodreads.com/book/show/43306206-the-courage-to-be-disliked&quot;&gt;The Courage to Be Disliked&lt;/a&gt;” applies to software too.&lt;/p&gt;
&lt;h2&gt;A Philosophy of Software Design&lt;/h2&gt;
&lt;p&gt;It has become a tradition to mention &lt;a href=&quot;https://www.goodreads.com/book/show/39996759-a-philosophy-of-software-design&quot;&gt;John Ousterhout’s book&lt;/a&gt; in every software design article on this blog. Below is an excerpt I found in the annotated reading list at the end of “Tidy First?”:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Ousterhout, John, A Philosophy of Software Design, Palo Alto: Yakmyam Press, 2018&lt;/p&gt;
&lt;p&gt;This is the book that got me off my butt writing. John’s points are well taken about making design better, but they are presented dogmatically — always keep your code as clean as you possibly can. The question mark in Tidy first? is a direct response.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In a way, “A Philosophy of Software Design” is more beginner-friendly precisely because of its dogmatic approach.&lt;/p&gt;
&lt;p&gt;“Tidy First?” reminds me of a teacher’s textbook. It provides a basic foundation for an imaginary software design class, leaving it up to the “teacher” to expand on the book’s ideas. In practice, senior and staff engineers often play roles of teachers and mentors. For them, “Tidy First?” could serve as an excellent inspiration.&lt;/p&gt;
&lt;h2&gt;Economics of options&lt;/h2&gt;
&lt;p&gt;In the final part of the book, Kent Beck draws an interesting analogy between the economics of options and the ever-changing nature of software:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“What behavior can I implement next?” has value all on its own, even before I implement it. This surprised me. I thought I was getting paid for what I had done. I wasn’t. I was mostly getting paid for what I could do next.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As Kent explains, software design has to reconcile the economic imperatives of “earn sooner/spend later” and “create options, not things”. On one hand, we want to sell more now, on the other hand, we want to prepare for future change, i.e. create more options.&lt;/p&gt;
&lt;p&gt;As money directly affects how we build software, clarifying the relationship between money and software design is a wise idea.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;Kent Beck, who is famous for inventing Extreme Programming and (re)inventing Test-Driven-Development, has authored a beautiful little book on the daily practice of software design.&lt;/p&gt;
&lt;p&gt;The book didn’t waste a single minute of my time. Even the introductory sections were packed with useful ideas. For instance, the intro to the Theory part explained how the theory might be actually useful in practice.
&lt;img alt=&quot;Kate reads Tidy First? book on a train&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;1000&quot; src=&quot;/_astro/og-image.D5aUgqoZ_Z1ARD95.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Last but not least, it has a beautiful cover. Highly recommended!&lt;/p&gt;</content:encoded></item><item><title>My tech year in review (2023)</title><link>https://kalabro.tech/my-tech-year-in-review-2023/</link><guid isPermaLink="true">https://kalabro.tech/my-tech-year-in-review-2023/</guid><description>Reflecting on 2023, my best tech year to date</description><pubDate>Mon, 25 Dec 2023 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;This type of post is more useful for the author than the reader, so feel free to skip to the comments. Whether you are my reader, teammate, mentee or mentor - I’ll be super happy to receive a comment or a thumbs up from you.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Happy holidays, and see you next year!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Below are some highlights from my year in tech:&lt;/p&gt;
&lt;h3&gt;Mentorship&lt;/h3&gt;
&lt;p&gt;This year, I’ve delivered 1000+ mentorship minutes on &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;ADPList&lt;/a&gt;, plus a couple of paid sessions on &lt;a href=&quot;https://www.codementor.io/@kalabro&quot;&gt;codementor&lt;/a&gt; and &lt;a href=&quot;https://topmate.io/kalabro&quot;&gt;topmate&lt;/a&gt;. At the same time, I was lucky to find a great long-term mentor for myself. Highly recommend a longer commitment over a one-off chat!&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;1000 mentorship minutes certification from ADPList&quot; loading=&quot;lazy&quot; width=&quot;1838&quot; height=&quot;930&quot; src=&quot;/_astro/adplist.D3CqnMRR_ZiufMj.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;The most common topics discussed in my sessions were job hunting and breaking into tech. While we expect more layoffs and hiring freezes in 2024, I’m optimistic about long-term opportunities in our field. Mentorship is one of the tools to spark and maintain the positivity and self-confidence necessary for overcoming the challenges of 2024.&lt;/p&gt;
&lt;p&gt;Finally, I recommend the &lt;a href=&quot;https://www.goodreads.com/book/show/29342515-the-coaching-habit&quot;&gt;Coaching Habit book&lt;/a&gt; to everyone who wants to better support and empower others.&lt;/p&gt;
&lt;h3&gt;Coding&lt;/h3&gt;
&lt;p&gt;In 2023, I doubled the volume of my code contributions. Solving problems with code is something that brings me pure joy.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Comparison of my Github activity 2022 vs 2023&quot; loading=&quot;lazy&quot; width=&quot;921&quot; height=&quot;472&quot; src=&quot;/_astro/github-2022-2023.DBQIH7jw_2gUMWv.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;This year, I had a chance to work on frontend and backend, from microservices to microfrontends, with classic databases and asynchronous messaging mechanisms. I discovered my natural ability to navigate foreign codebases and pick up new tools quickly. I’m an okay coder, but with much more practice (and Copilot), I made great progress this year.&lt;/p&gt;
&lt;p&gt;After reading that last line, you may think that I’m being humble. Yes and no. I somehow have never needed to be very good at programming, but at the same time it’s part of my job that I admire the most.&lt;/p&gt;
&lt;h3&gt;Writing&lt;/h3&gt;
&lt;p&gt;It’s been a good year for this blog. Below are all the articles I published in 2023:&lt;/p&gt;
&lt;h4&gt;On soft skills:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/where-to-find-mentor-2023/&quot;&gt;Where to find a mentor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/focus-mode-three-tricks/&quot;&gt;Three tricks to get in focus mode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/communication-budget/&quot;&gt;Budgeting my communication capacity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/onboarding-yourself/&quot;&gt;Onboarding yourself as a Senior Software Engineer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/learning-at-work/&quot;&gt;Learning at work: common obstacles and how to overcome them&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;On software design:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;“Learning Domain-Driven Design” - the software architecture &lt;span&gt;🐒&lt;/span&gt; book that makes sense&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/road-to-software-architecture-frontend-edition/&quot;&gt;The road to Software Architecture (frontend edition)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/thinking-architecturally/&quot;&gt;Thinking Architecturally (book review)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;On tools:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/flutter-for-react-developers/&quot;&gt;Flutter guide for React developers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/fast-by-default-nextjs/&quot;&gt;Fast by default with Next.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/it-depends-renovate/&quot;&gt;It depends! Exploring my favourite Renovate features for dependency updates&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;On events:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/react-alicante-2023/&quot;&gt;React Alicante 2023&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://kalabro.tech/advent-of-frontend-architecture-2023/&quot;&gt;Advent of Frontend Architecture - supporting materials&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you had a chance to read some of them, which was your favourite?&lt;/p&gt;
&lt;h3&gt;New job&lt;/h3&gt;
&lt;p&gt;After joining New Work as a Senior Frontend Engineer (technical interviews are easier for specialists &lt;span&gt;🤷‍♀️&lt;/span&gt;) I immediately transformed myself back to Full Stack and received the highest rating in my recent performance review.&lt;/p&gt;
&lt;p&gt;I approached my new job as a giant learning class and took every opportunity to test my skills. The list of tools I touched is enormous. My favourites are Turborepo, MSW, Nest.js, GraphQL Mesh, Datadog and ArgoCD.&lt;/p&gt;
&lt;p&gt;My least favourites are all Microsoft products. Luckily, not all my communication happens in Microsoft Teams. I enjoy going to the office from time to time, having a long lunch with teammates, or giving a talk for a local meetup.&lt;/p&gt;
&lt;p&gt;I also realised that my style and energy may have disturbed a few colleagues, and I hope they will forgive me. Working in a large company has helped me understand that every developer is different, with different strengths, motivations and life situations.&lt;/p&gt;
&lt;h3&gt;Tools&lt;/h3&gt;
&lt;p&gt;In 2019, I had a &lt;a href=&quot;https://kalabro.tech/my-tech-year-in-review-2019/&quot;&gt;similar post&lt;/a&gt; listing my main tools at work. Surprisingly, they haven’t changed much:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Macbook Pro M1 (14”/16”)&lt;/li&gt;
&lt;li&gt;Firefox and Chrome (but I try to avoid Chrome)&lt;/li&gt;
&lt;li&gt;BetterTouchTool&lt;/li&gt;
&lt;li&gt;VS Code&lt;/li&gt;
&lt;li&gt;ChatCPT &amp;amp; Copilot (new)&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;iTerm (&lt;a href=&quot;https://kalabro.tech/no-geek-command-line/&quot;&gt;my approach to the command line&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;PhpStorm (still using for some tasks)&lt;/li&gt;
&lt;li&gt;Evernote&lt;/li&gt;
&lt;li&gt;1Password&lt;/li&gt;
&lt;li&gt;Remarkable (new)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;What’s next&lt;/h3&gt;
&lt;p&gt;2023 has been one of my best years in tech. I re-discovered the joy of web development, met many like-minded people and laid a foundation for the next steps.&lt;/p&gt;
&lt;p&gt;Speaking in DDD terms, I aim to work more on the “core” subdomains, i.e. complex business problems. Opening a hundred pull requests is easy, making a real organisational impact is harder.&lt;/p&gt;
&lt;p&gt;One way to make my work more impactful is to increase scope, e.g. zoom out to the architectural level. For that, I’ll continue exploring software design practices and common system design patterns.&lt;/p&gt;
&lt;p&gt;On the other hand, I want to explore less safe ways to do things, e.g. bringing new ideas, experimenting, and questioning the status quo. For that, I wish myself, and all of us, a lot of courage, creativity and self-confidence in 2024.&lt;/p&gt;
&lt;p&gt;Let’s have a fantastic new year! &lt;span&gt;🎄&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>Advent of Frontend Architecture - supporting materials</title><link>https://kalabro.tech/advent-of-frontend-architecture-2023/</link><guid isPermaLink="true">https://kalabro.tech/advent-of-frontend-architecture-2023/</guid><description>Supporting materials for my &apos;Advent of Frontend Architecture&apos; talk at BarcelonaJS</description><pubDate>Wed, 20 Dec 2023 17:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Below you will find supporting materials for my lightning talk, “Advent of Frontend Architecture”, at the BarcelonaJS meetup.&lt;/p&gt;
&lt;h2&gt;Patterns&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.patterns.dev/&quot;&gt;Patterns.dev&lt;/a&gt; - frontend-friendly book on design patterns&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://addyosmani.com/learning-jsdp/&quot;&gt;Learning JavaScript Design Patterns&lt;/a&gt; - supporting materials for the second edition of the book by Addy Osmani&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://feature-sliced.design/&quot;&gt;Feature-Sliced Design&lt;/a&gt; - opinionated folder structure for bigger frontend projects (alternative to Clean Architecture)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Practices&lt;/h2&gt;
&lt;h3&gt;&lt;span&gt;🥂&lt;/span&gt; Pair tech concept&lt;/h3&gt;
&lt;p&gt;Two developers are brainstorming an implementation plan on a call. A good alternative to pair programming in fully remote environments.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🍻&lt;/span&gt; Design it twice&lt;/h3&gt;
&lt;p&gt;Fully spec out first version of your implementation plan. Put it aside and try to spec out an alternative version. Compare the two to come up with the final version.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🎊&lt;/span&gt; Throw away&lt;/h3&gt;
&lt;p&gt;Without any thorough planning, go ahead and implement the first quick &amp;amp; dirty version. Throw it away. Spec out a proper implementation plan based on your learnings.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🪐&lt;/span&gt; Don’t change jobs&lt;/h3&gt;
&lt;p&gt;Stay on the same project until your own decisions come back to you in the form of poor, unmaintainable code.&lt;/p&gt;
&lt;h2&gt;Books&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.goodreads.com/en/book/show/39996759&quot;&gt;A Philosophy of Software Design&lt;/a&gt; - my favourite software engineering book&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.goodreads.com/book/show/57573212-learning-domain-driven-design&quot;&gt;Learning Domain-Driven Design&lt;/a&gt; - good introduction to DDD (&lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;my review&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://tanzu.vmware.com/content/ebooks/thinking-architecturally&quot;&gt;Thinking Architecturally&lt;/a&gt; (&lt;a href=&quot;https://kalabro.tech/thinking-architecturally/&quot;&gt;my review&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Back story&lt;/h2&gt;
&lt;p&gt;This talk is based on &lt;a href=&quot;https://kalabro.tech/road-to-software-architecture-frontend-edition/&quot;&gt;“The road to Software Architecture (frontend edition)”&lt;/a&gt; article and is inspired by &lt;a href=&quot;https://csschristmascalendar.com/&quot;&gt;CSS Christmas Calendar&lt;/a&gt; website.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;A little promotion:&lt;/strong&gt; If you need a hand on your journey, I’m offering both &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;free&lt;/a&gt; and &lt;a href=&quot;https://topmate.io/kalabro&quot;&gt;paid&lt;/a&gt; mentorship sessions.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>Learning at work: common obstacles and how to overcome them</title><link>https://kalabro.tech/learning-at-work/</link><guid isPermaLink="true">https://kalabro.tech/learning-at-work/</guid><description>It took me years to find the right mindset for learning at work. In this article, I share my experience and hope it will help you grow as a developer.</description><pubDate>Fri, 20 Oct 2023 08:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Every developer I’ve met during my mentorship sessions was striving to learn. Yet, many felt stuck in their careers. When debugging growth obstacles with them, I always start by exploring “learning at work” opportunities.&lt;/p&gt;
&lt;p&gt;It’s common to treat learning and working as two separate activities. First, a developer invests time in acquiring missing knowledge. Then they go and happily complete their task at work. Ideally, others only witness the latter part and perceive them as an expert.&lt;/p&gt;
&lt;p&gt;Reality is different, though, and I often hear developers complain they can’t learn at work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;“I don’t have time to learn at work”&lt;/li&gt;
&lt;li&gt;“I work on a legacy project”&lt;/li&gt;
&lt;li&gt;“My company doesn’t use technology I want to learn”&lt;/li&gt;
&lt;li&gt;“We don’t have a learning culture”&lt;/li&gt;
&lt;li&gt;“I’m the only frontend developer in the team / I have nobody to learn from”&lt;/li&gt;
&lt;li&gt;“I don’t have a side project”&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These are all common circumstances for many of us. I have experienced all of them myself, and will address each later in this article. But first, let me name a few benefits of learning at work:&lt;/p&gt;
&lt;h3&gt;Benefit 1: Focus&lt;/h3&gt;
&lt;p&gt;For over two years, I was learning TypeScript in background while still writing production code in JavaScript. Then, I threw myself in a 100% TypeScript project at work and mastered it within a couple of weeks. My work environment helped me radically focus on what I wanted to learn.&lt;/p&gt;
&lt;h3&gt;Benefit 2: Real-world problem&lt;/h3&gt;
&lt;p&gt;Back to my TypeScript example, I had practical problems to solve, and they served as real-world exercises to test my new skills.&lt;/p&gt;
&lt;h3&gt;Benefit 3: Deadline&lt;/h3&gt;
&lt;p&gt;Working in short sprints introduced internal deadlines that forced me:&lt;br /&gt;
a) to be realistic about what I can achieve&lt;br /&gt;
b) to finish at least one task per sprint&lt;/p&gt;
&lt;h3&gt;Benefit 4: Supporting network&lt;/h3&gt;
&lt;p&gt;When I got stuck, I could ask more experienced developers for help and fast-track my learning (or learn together if my question puzzled them too).&lt;/p&gt;
&lt;h3&gt;Benefit 5: Healthy dose of discomfort&lt;/h3&gt;
&lt;p&gt;Not knowing where to start felt shitty. I was willing to go the extra mile to overcome this discomfort. The term “hardworking” is out of fashion these days, but that’s often required to learn topics deeply.&lt;/p&gt;
&lt;h3&gt;Benefit 6: Time&lt;/h3&gt;
&lt;p&gt;I spend 8 hours every day at work, 40 hours per week. With a bit of effort, I can balance productivity vs challenge in my workload and keep learning organically.&lt;/p&gt;
&lt;p&gt;Many employed developers can access all those benefits at their jobs. I learned to appreciate and use them to my advantage.&lt;/p&gt;
&lt;p&gt;Now, let me go back to the list of common obstacles and share how I think about them now:&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;⏰&lt;/span&gt; Obstacle 1: I don’t have time to learn at work&lt;/h3&gt;
&lt;p&gt;For me, developer efficiency is not about working faster. It’s about &lt;strong&gt;doing repetitive chores and basic tasks faster&lt;/strong&gt; so that we can spend &lt;em&gt;more&lt;/em&gt; time on difficult ones.&lt;/p&gt;
&lt;p&gt;Everyone’s favourite example is unnecessary meetings. But it can also be a buggy dev environment that slows down every code change, broken communication between dependant teams, or gaps in business domain knowledge. If basics are broken, everything becomes more difficult.&lt;/p&gt;
&lt;p&gt;Another source of time is &lt;strong&gt;personal budget&lt;/strong&gt;. I don’t mind borrowing a little if I’m passionate about a task at hand. I never regretted late evenings debugging an intriguing issue or polishing documentation for a new feature. I have only warm memories of those occasional spikes of energy and dedication. I wouldn’t necessarily recommend this approach to everyone, but it feels necessary to mention it in this article.&lt;/p&gt;
&lt;p&gt;But my primary source of time for learning is hidden in this quote:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Software Engineering is a learning process, working code is a side effect (Alberto Brandolini)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As software engineers, &lt;strong&gt;we learn 100% of the time at work&lt;/strong&gt;. You may be learning 40 hours/week without even realising it. It’s a good idea to regularly reflect on your past experiences and uncover any hidden learnings. In practice, deep work on any engineering task brings me new insights.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;💩&lt;/span&gt; Obstacle 2: I work on a legacy project&lt;/h3&gt;
&lt;p&gt;Due to frequent job changes, developers often depart from a company before their code becomes an unmaintainable ball of mud. Instead, they join a new company where they have to deal with someone’s else ball of mud.&lt;/p&gt;
&lt;p&gt;When I think of my past struggles with legacy projects, two issues stand out:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Slow&lt;/strong&gt;. They all were very slow to run, to build, to test. Such projects tend to have hours-long testing pipelines; otherwise, it’s too risky to implement any changes. As a result, even a minor modification can take days to release. I believe it’s never too late to optimise performance, particularly if you plan to support the project for awhile.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Complex&lt;/strong&gt;. Legacy projects encapsulate tons of undocumented business logic. Developers often have to start making changes before familiarising themselves with all project features. Sometimes, it’s just too much to fit in one man’s head. Other times, people with knowledge may have already left the company. Either way, I’d spend more time watching how others use the project, reviewing git history, and asking around about the most confusing features. Nobody will be excited to talk about a legacy system. At the very least, I try to keep the conversation tone neutral.&lt;/p&gt;
&lt;p&gt;Other common issues with legacy projects are spaghetti code, outdated technology, poor UX, lack of structure, low test coverage, inconsistent documentation. Finding your way through all these issues is a great software engineering lesson. It’s extra effective (and painful) if you were the one creating the mess several years ago.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;⚛️&lt;/span&gt; Obstacle 3: My company doesn’t use technology I want to learn&lt;/h3&gt;
&lt;p&gt;First of all, your tech stack of preference must intersect with the one of your employer.
It’s heartbreaking to see JavaScript developers fighting with PHP (and vice versa). If you find yourself constantly battling against the tech stack, I recommend switching jobs.&lt;/p&gt;
&lt;p&gt;Now, let’s consider a less extreme example. Imagine that I want to learn Clojure. It’s a respected language with a high developer satisfaction rating. I have a friend who happily transitioned from PHP to Go to Clojure, and I believe I can too! As a Full Stack developer, I’m easily attracted by this kind of thing! However, to be honest, I don’t have a lot of tasks at work that would be a good fit for Clojure.&lt;/p&gt;
&lt;p&gt;In such a situation, I would question why I want to learn Clojure when several other opportunities are available at my current company. Depending on the answer, I might decide to explore Clojure in my spare time or choose another language to feed my curiosity.&lt;/p&gt;
&lt;p&gt;As a side note, I’ve never experienced disgust towards any particular technology. Clojure is cool, and PHP is cool, too.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;👺&lt;/span&gt; Obstacle 4: We don’t have a learning culture&lt;/h3&gt;
&lt;p&gt;The mindset I describe in this article doesn’t require any specific culture. Thinking in such bold terms can create unnecessary frustration. Instead, I would begin by adjusting my own approach to learning at work, and see if others want to join me. It’s perfectly okay if they choose not to; it shouldn’t change my plans.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🐺&lt;/span&gt; Obstacle 5: I’m the only developer in the team / I have nobody to learn from&lt;/h3&gt;
&lt;p&gt;Junior developers often find themselves in smaller companies with just a few other developers.
In a similar situation, I doubled down on learning from a local web community. It was different from working in a strong dev team, but still very fruitful. Many autonomous full stack developers have grown up in such environments.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🧶&lt;/span&gt; Obstacle 6: I don’t have a side project&lt;/h3&gt;
&lt;p&gt;I don’t have one, either. I’ve made several attempts but quickly abandoned them. I genuinely admire developers who build side projects, commercial or open source, practical or crazy. I’m not one of them, and that’s fine.&lt;/p&gt;
&lt;p&gt;I’m more driven by the idea of contributing back to the web community. Nowadays, I write articles and provide &lt;a href=&quot;https://topmate.io/kalabro&quot;&gt;mentorship&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Go discover what works for you; it doesn’t necessarily have to be a side project.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;If you are willing to find learning opportunities, you will find them in almost any company. Working environments create perfect conditions for learning:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;span&gt;🎯&lt;/span&gt; focus&lt;/li&gt;
&lt;li&gt;&lt;span&gt;📊&lt;/span&gt; real-world problems&lt;/li&gt;
&lt;li&gt;&lt;span&gt;⌛️&lt;/span&gt; deadlines&lt;/li&gt;
&lt;li&gt;&lt;span&gt;🤝&lt;/span&gt; supporting network&lt;/li&gt;
&lt;li&gt;&lt;span&gt;🤪&lt;/span&gt; a healthy dose of discomfort&lt;/li&gt;
&lt;li&gt;&lt;span&gt;⏰&lt;/span&gt; time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With the right attitude towards common learning obstacles, we can continue growing without side projects, frequent job changes, or expensive training sessions.&lt;/p&gt;
&lt;p&gt;I will conclude with one of my favourite quotes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Software Engineering is a learning process, working code a side effect.” (Alberto Brandolini)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I hope you enjoy &lt;a href=&quot;https://kalabro.tech/mental-health-full-stack-developers/&quot;&gt;the never ending learning curve&lt;/a&gt; and get the maximum out of it!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A little promotion:&lt;/strong&gt; If you need a hand on your journey, I’m offering both &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;free&lt;/a&gt; and &lt;a href=&quot;https://topmate.io/kalabro&quot;&gt;paid&lt;/a&gt; mentorship sessions.&lt;/p&gt;</content:encoded></item><item><title>React Alicante 2023</title><link>https://kalabro.tech/react-alicante-2023/</link><guid isPermaLink="true">https://kalabro.tech/react-alicante-2023/</guid><description>My takeaways and useful links from the conference.</description><pubDate>Sun, 01 Oct 2023 20:00:00 GMT</pubDate><content:encoded>&lt;p&gt;On this page, you can find a full list of all React Alicante 2023 talks with my short comments. If you want a longer opinionated summary, it’s at the very bottom.&lt;/p&gt;
&lt;p&gt;Enjoy and feel free to reuse it if you need a summary for your team or employer.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-1&quot;&gt;Sessions - Day 1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#sessions---day-2&quot;&gt;Sessions - Day 2&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#my-summary&quot;&gt;My summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Sessions - Day 1&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;16 high quality talks on performance, accessibility, resumability, types, SolidJS, Playwright, Canvas, CDN &amp;amp; Edge, tRPC, React Native, codemods, MSW, React Query, and more. Great atmosphere, friendly people, and a lot of complaints about useEffect!&lt;/em&gt; &lt;span&gt;😄&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;React—The Good Parts by Tejas Kumar&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/TejasKumar_&quot;&gt;@TejasKumar_&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A response to React haters (who were not really in that room &lt;span&gt;🤷‍♀️&lt;/span&gt;) full of cool “implement it yourself” demos from basic counter app to server components.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🌟&lt;/span&gt; SolidJS for React Developers by Erik Rasmussen &lt;span&gt;🌟&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/erikras&quot;&gt;@erikras&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://speakerdeck.com/erikras/solid-for-react-developers&quot;&gt;https://speakerdeck.com/erikras/solid-for-react-developers&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As I’ve been using react-final-form from Erik for a while, I trust his opinion on &lt;a href=&quot;https://www.solidjs.com/&quot;&gt;Solid&lt;/a&gt;.
He managed to get the audience up to speed with Solid in 30 minutes, comparing Solid and React side by side and highlighting some non-obvious things. Apparently, the syntax is almost the same but the devil is in details.&lt;/p&gt;
&lt;h3&gt;Playing your tests wright by Debbie O’Brien&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/debs_obrien&quot;&gt;@debs_obrien&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another reminder that the testing pyramid is in the past. End-to-end tests are the most reliable way to ensure your app &lt;em&gt;really&lt;/em&gt; works, and the tooling is there to make it happen. I agree with the general message, but I may not be as attached to Playwright as Debbie.&lt;/p&gt;
&lt;h3&gt;Type safety from the database to the frontend by Forbes Lindesay&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/ForbesLindesay&quot;&gt;@ForbesLindesay&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Code-heavy talk on getting your types right in different parts of the stack from &lt;a href=&quot;https://www.atdatabases.org/&quot;&gt;databases&lt;/a&gt; to &lt;a href=&quot;https://github.com/ForbesLindesay/funtypes&quot;&gt;untyped external APIs&lt;/a&gt; and everything in between. We even looked at some Rust code. As a bonus, I learned that I can write numbers with underscore symbol in JavaScript:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;const&lt;/span&gt;&lt;span&gt; oneMillion&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; 1_000_000&lt;/span&gt;&lt;span&gt;;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Building Text Containers in Canvas by Aakansha Doshi&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/aakansha1216&quot;&gt;@aakansha1216&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://docs.google.com/presentation/d/1INBB7oE0tI3SFGK5t65ThWXc0lO3hQ_utVBntKyUyog/edit#slide=id.g24789271ec1_0_0&quot;&gt;https://docs.google.com/presentation/d/1INBB7oE0tI3SFGK5t65ThWXc0lO3hQ_utVBntKyUyog/edit#slide=id.g24789271ec1_0_0&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A deep dive into canvas from &lt;a href=&quot;https://excalidraw.com/&quot;&gt;Excalidraw&lt;/a&gt; developer. I appreciated the level of detail and how Aakansha broke down the problem into smaller, understandable pieces. Canvas API reminded me of programmatic PDF manipulation from my past PHP experience. I’m glad I don’t have to deal with it anymore &lt;span&gt;😄&lt;/span&gt;&lt;/p&gt;
&lt;h3&gt;Pushing boundaries to the edge by Facundo Giuliani&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/facundozurdo&quot;&gt;@facundozurdo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An intro into origin vs CDN vs edge for frontend developers. As I was already familiar with the topic, it was less interesting for me. Edge computing is more challenging in practice than it may
sound in the intros. Still, I met quite a few attendees who enjoyed this overview from Facundo. Indeed, if you are on Vercel, it should be rather easy to start with edge.&lt;/p&gt;
&lt;h3&gt;tRPC - Better than REST/GraphQL? by Devlin Duldulao&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/DevlinDuldulao&quot;&gt;@DevlinDuldulao&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Lightweight intro into tRPC. The talk wasn’t actually diminishing REST or GraphQL as it may look from the title.&lt;/p&gt;
&lt;h3&gt;Common Pitfalls in React Native Apps and How to fix them by Dan Neciu&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/neciudan&quot;&gt;@neciudan&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://drive.google.com/file/d/1Tw4ojP3iNFe2UdT_xzYvvIWxtcNQOwkt/view&quot;&gt;https://drive.google.com/file/d/1Tw4ojP3iNFe2UdT_xzYvvIWxtcNQOwkt/view&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A couple of gotchas from Dan’s experience with React Native, such as lack of localStorage, how to correctly import fonts and render HTML, etc. It was interesting to compare it with my &lt;a href=&quot;https://kalabro.tech/flutter-for-react-developers/&quot;&gt;Flutter experience as a React developer&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Maximizing React Performance with DevTools: Profiler and Components by Jelena Maravic&lt;/h3&gt;
&lt;p&gt;LinkedIn: &lt;a href=&quot;https://www.linkedin.com/in/jelena-maravic&quot;&gt;Jelena Maravic&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://www.canva.com/design/DAFnrN1Ls5g/view&quot;&gt;https://www.canva.com/design/DAFnrN1Ls5g/view&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This short talk was packed with React performance tips and tricks. In practice, developers often fear profiling tools, and I would love to see more presentations popularizing them.&lt;/p&gt;
&lt;h3&gt;Codemods - how to support your users with breaking changes delivery by Łukasz Nowak&lt;/h3&gt;
&lt;p&gt;GitHub: &lt;a href=&quot;https://github.com/lukasznowakpl&quot;&gt;@lukasznowakpl&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://github.com/LukaszNowakPL/codemods/blob/main/%5BEN%5D%202023-09-29%20-%20React%20Alicante%20-%20Codemods.pdf&quot;&gt;https://github.com/LukaszNowakPL/codemods/blob/main/%5BEN%5D%202023-09-29%20-%20React%20Alicante%20-%20Codemods.pdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A hands-on example of using codemods to help users overcome breaking changes in your library. Apparently, tools like &lt;a href=&quot;https://github.com/facebook/jscodeshift&quot;&gt;jscodeshift&lt;/a&gt; make it, if not easy, then at least doable.&lt;/p&gt;
&lt;h3&gt;Seek, and you shall find your way to fun! by Kevin Maes&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/kvmaes&quot;&gt;@kvmaes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kevin presented his side project, which he built just for fun (and also to learn some fancy graph algorithms that we wouldn’t usually use in our React apps). You can find the code &lt;a href=&quot;https://github.com/kevinmaes/maze&quot;&gt;here on GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;Crafting Accessible Components for Component Libraries by Mathilde Buenerd&lt;/h3&gt;
&lt;p&gt;GitHub: &lt;a href=&quot;https://github.com/mathildebuenerd&quot;&gt;@mathildebuenerd&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mathilde opened a series of accessibility talks at React Alicante with React-specific tips on accessibility, such as React.forwardRef for overcoming focus issues, or React.AriaAttributes to enable aria-* attributes on library components.&lt;/p&gt;
&lt;h3&gt;The State of GraphQL Clients in 2023 by Roy Derks&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/gethackteam&quot;&gt;@gethackteam&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A short and practical overview of GraphQL clients’ space, with special attention to Relay. As I’m relatively new to GraphQL, I found this talk informative.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🌟&lt;/span&gt; Hydration, Islands, Streaming, Resumability… Me, Oh My! by Matheus Albuquerque &lt;span&gt;🌟&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/ythecombinator&quot;&gt;@ythecombinator&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://speakerdeck.com/ythecombinator/react-alicante-2023&quot;&gt;https://speakerdeck.com/ythecombinator/react-alicante-2023&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A thorough walk-through with tons of historical references and technical details. I bookmarked the slides to review the links later. Given how hot this space is right now, I appreciate the balanced, non-biased tone of this talk.&lt;/p&gt;
&lt;h3&gt;All you need is a contract… by Daniel Afonso&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/danieljcafonso&quot;&gt;@danieljcafonso&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Daniel is clearly a big fan of Mock Service Worker and React Query! I believe they are both defacto standards anyway. MSW received special attention as an amazing dev tool not only
for running tests but also for parallelising backend and frontend development.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🌟&lt;/span&gt; Practical guide to building accessible forms in React by Kateryna Porshnieva &lt;span&gt;🌟&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/krambertech&quot;&gt;@krambertech&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://krambertech.notion.site/krambertech/Practical-Guide-to-building-accessible-forms-in-React-daba42af8f894223bbc8e184e532ed64&quot;&gt;https://krambertech.notion.site/krambertech/Practical-Guide-to-building-accessible-forms-in-React-daba42af8f894223bbc8e184e532ed64&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The best talk of the day and probably the best talk I’ve seen in a while. Kateryna is a pro at explaining complex topics in a simple, engaging way. Absolutely recommended.&lt;/p&gt;
&lt;h2&gt;Sessions - Day 2&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;Another 16 talks on AI, Solid, Astro, Qwik, ReasonML, state machines and more.&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;Why I Still Choose React by Chance Strickland&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;http://twitter.com/chancethedev&quot;&gt;@chancethedev&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An overview of React past and present with funny 200-line useEffect examples from
a seasoned React developer involved in Remix, React Training, Reach UI and other famous projects. SolidJS is mentioned again, but it’s clear that the audience still
chooses React.&lt;br /&gt;
Chance rightly points out that if signals were a silver bullet, React would adopt them already. React’s main advantage is its mental (rendering) model, and there should be other ways to fix useEffect without sacrificing the beauty of the &lt;code&gt;UI = fn(state)&lt;/code&gt; formulae.&lt;/p&gt;
&lt;h3&gt;Processes, StateCharts and WorkFlows by Mattia Manzati&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/mattiamanzati&quot;&gt;@mattiamanzati&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://mattiamanzati.github.io/long-running-process/1&quot;&gt;https://mattiamanzati.github.io/long-running-process/1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A side track into the world of sagas, eventual consistency and state machines.
I could make sense of the material thanks to Mattia’s creative analogies and &lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;my prior DDD knowledge&lt;/a&gt;. It may feel too advanced, but in fact, we all deal with more complex problems at work than the famous counter app.&lt;/p&gt;
&lt;h3&gt;Resumability in the next generation frontend framework With O(1) loading time by Ruby Jane&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/rubyjane88&quot;&gt;@rubyjane88&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A rather boring intro into resumability and its frontman Qwik. What impressed me, though, is how the React community is open to alternative voices and ideas in the space.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🌟&lt;/span&gt; Server-side rendering React natively with Reason by David Sancho &lt;span&gt;🌟&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/davesnx&quot;&gt;@davesnx&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://docs.google.com/presentation/d/150JjwU4HdtdWN_iT5MkvaKrQv3Dnj3OJCey-cRi3V9U/edit#slide=id.g7207e88d15_0_121&quot;&gt;https://docs.google.com/presentation/d/150JjwU4HdtdWN_iT5MkvaKrQv3Dnj3OJCey-cRi3V9U/edit#slide=id.g7207e88d15_0_121&lt;/a&gt;&lt;br /&gt;
Blog post: &lt;a href=&quot;https://sancho.dev/blog/server-side-rendering-react-in-ocaml&quot;&gt;https://sancho.dev/blog/server-side-rendering-react-in-ocaml&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An active contributor to Reason/OCaml ecosystem explains the basics of ReasonML and
shares a story of building &lt;a href=&quot;https://github.com/ml-in-barcelona/server-reason-react&quot;&gt;server-reason-react&lt;/a&gt;. I wish there were more talks from active open source contributors who deserved their round of applause!&lt;/p&gt;
&lt;h3&gt;Bye-bye, weeds! Digital Gardening with Astro &amp;amp; MDX by Kathleen McMahon&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/resource11&quot;&gt;@resource11&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://noti.st/resource11/cegRnq/bye-bye-weeds-digital-gardening-with-astro-mdx&quot;&gt;https://noti.st/resource11/cegRnq/bye-bye-weeds-digital-gardening-with-astro-mdx&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A story of upgrading a personal blog from Gatsby 2.3 to Astro. Funny enough, this very blog
runs on Gatsby 2.4. I feel Kathleen’s pain, but maybe a dedicated talk at React Alicante is a bit too much for this topic. Anyway, I shortlisted Astro if I ever need to migrate from Gatsby.&lt;/p&gt;
&lt;h3&gt;Rendering Dilemma: Reacting to State Change by Atila Fassina&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/atilafassina&quot;&gt;@AtilaFassina&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;At this point, speakers started repeating each other with Solid comparisons, counter demos and &lt;code&gt;UI = fn(state)&lt;/code&gt; slides. Nevertheless, Atila’s talk was well prepared, and I learned about React Forget compiler efforts (auto-memoisation) and &lt;a href=&quot;https://svelte.dev/blog/runes&quot;&gt;Svelte Runes&lt;/a&gt; (signals in Svelte).&lt;/p&gt;
&lt;h3&gt;A comparison of Microfrontends composition techniques Module Federation (webpack, vite vs turborepo) by Aris Markogiannakis&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/arismarko&quot;&gt;@arismarko&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://www.canva.com/design/DAFqwlKyZ5o/rn_f4K5wT41jbsR0e3XpYA/view&quot;&gt;https://www.canva.com/design/DAFqwlKyZ5o/rn_f4K5wT41jbsR0e3XpYA/view&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As it was a lightning talk, it only gave a quick overview of &lt;a href=&quot;https://micro-frontends.org/&quot;&gt;microfrontends&lt;/a&gt; concept. Aris
compared Next.js multi-zones solution with Webpack Module Federation (which now has Vite support), and the latter won (no surprise).&lt;br /&gt;
Apparently, I missed a whole conference dedicated
to microfrontends, but luckily &lt;a href=&quot;https://youtube.com/@smapiot?si=4-pJATHPowA6rR2Y&quot;&gt;videos are available on YouTube&lt;/a&gt;!&lt;/p&gt;
&lt;h3&gt;Accelerating Your Career: Becoming a 10x Junior Engineer by Joana Santos&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/joanamcsa&quot;&gt;@joanamcsa&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An exceptionally well-prepared lighting talk! I’m extra happy that Joana pointed
out the importance of mentorship in tech.&lt;/p&gt;
&lt;h3&gt;Supercharging React Performance with SolidJS Signal by Subham Bhattacharjee&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/subhaminion&quot;&gt;@subhaminion&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Unfortunately, the talk repeated 99% of what previous speakers had already covered.&lt;/p&gt;
&lt;h3&gt;Patterns for Making Accessible Components by Chris Cormier&lt;/h3&gt;
&lt;p&gt;GitHub: &lt;a href=&quot;LeviathanTheGreat&quot;&gt;@LeviathanTheGreat&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An organic continuation of the accessibility topic started on day 1. Chris took a couple of practical examples and walked us through making them accessible. Accessibility
speakers coordinated well to avoid repeated content and at the end of the day
I had a coherent understanding of the topic. Well done!&lt;/p&gt;
&lt;h3&gt;How To Build a Chrome Extension Using React by Adina Stoica&lt;/h3&gt;
&lt;p&gt;Twitter &lt;a href=&quot;https://twitter.com/adinutzyc21&quot;&gt;@adinutzyc21&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A shorter version of Adina’s talk missed the React part but was still informative if you plan
to build a Chrome extension.&lt;/p&gt;
&lt;h3&gt;You are not becoming rich with a mobile app by Stefano Solinas&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/obsidianart&quot;&gt;@obsidianart&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Stefano shared the news from indiehackers space. Most side gigs fail, but even when
they succeed in the first place, like Stefano’s Imagzle app, it’s a tough ride.&lt;/p&gt;
&lt;h3&gt;Reviewing code review - duty, fun or… revenge? by Paulina Chojnowska&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/AntariaPaulina&quot;&gt;@AntariaPaulina&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://www.slideshare.net/Paulina218683/reactalicante2023paulinachojnowskapdf&quot;&gt;https://www.slideshare.net/Paulina218683/reactalicante2023paulinachojnowskapdf&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another perfect lightning talk on the challenges of a good old code review. Paulina nails it down to two questions: Does the code work? Do you like it?&lt;br /&gt;
A bonus:
&lt;a href=&quot;https://slides.pixelschubser.ch/conventional-comments-for-codereviews.html#/&quot;&gt;slides from Smashing Conference on Conventional Comments&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🌟&lt;/span&gt; Making state management intelligent by David Khourshid &lt;span&gt;🌟&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/davidkpiano&quot;&gt;@davidkpiano&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An impressive yet easy-to-follow demo by David using &lt;a href=&quot;https://www.npmjs.com/package/xstate&quot;&gt;xstate&lt;/a&gt;, ChatGPT and React. This talk was very much needed after so many counter demos!&lt;/p&gt;
&lt;h3&gt;Building Machine Learning Models on Edge with React by Shivay Lamba&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/HowDevelop&quot;&gt;@HowDevelop&lt;/a&gt;&lt;br /&gt;
Slides: &lt;a href=&quot;https://docs.google.com/presentation/d/1Eg4mdpc9-kvmk_yXUU0_mCkyzXs_jvHMqj5FR4URhKE/edit#slide=id.g2863585916f_0_1&quot;&gt;https://docs.google.com/presentation/d/1Eg4mdpc9-kvmk_yXUU0_mCkyzXs_jvHMqj5FR4URhKE/edit#slide=id.g2863585916f_0_1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A comprehensive overview of AI tools in the web ecosystem. Check the slides for tons of links from TensorFlow.js to Langchain to AI.JSX. I will definitely do as it will likely be part of my
day-to-day job very soon.&lt;/p&gt;
&lt;h3&gt;Imperative vs Declarative: Weathering the storm by Kyle Simpson&lt;/h3&gt;
&lt;p&gt;Twitter: &lt;a href=&quot;https://twitter.com/getifyX&quot;&gt;@getifyX&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Kyle welcomed us to reconsider what we understand as imperative and declarative programming.
He emphasised the importance of optimising code for reading, not for compiling. Unfortunately, he lost me in the second part of his talk as I was clearly overreacted.&lt;/p&gt;
&lt;h2&gt;My summary&lt;/h2&gt;
&lt;p&gt;It was my first conference entirely dedicated to React, and I enjoyed it a lot, even if my
talk reviews may sound a bit picky. Sorry about that - I’m a demanding attendee!&lt;/p&gt;
&lt;p&gt;In fact, I liked it so much that I put together this page to
share useful ideas with my friends and colleagues. Here are they:&lt;/p&gt;
&lt;h3&gt;Sessions diversity and distribution &lt;span&gt;👩🏼‍💻&lt;/span&gt;&lt;span&gt;👨🏾‍💻&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;All talks can be separated into inspirational speeches aka keynotes (1), overviews/getting-started guides (2), and specialised deep dives (3). To me, we had too many keynote-style sessions (1) and not enough advanced React-specific content (3).&lt;/p&gt;
&lt;p&gt;The average quality of talks was very high. Speakers from various locations and with diverse backgrounds were presented.&lt;/p&gt;
&lt;h3&gt;Beyond React &lt;span&gt;💐&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;It was clear to me and everyone whom I met in Alicante that React will be around for a long time. The ecosystem is healthy, and there is no need to switch to another framework.
Still, the React Alicante lineup responded enthusiastically to the rise of alternative frameworks. I’m returning to Barcelona knowing much more about Solid than I knew before.&lt;/p&gt;
&lt;h3&gt;Popular choices &lt;span&gt;📊&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;Based on a few conversations I had: Next.js, Typescript, React Query, Cypress, GraphQL (no surprises here)&lt;/p&gt;
&lt;h3&gt;Unpopular topics &lt;span&gt;🔻&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;State management, code structure / architecture, styling &amp;amp; UI libraries, forms - these topics were on hold as solved.&lt;/p&gt;
&lt;p&gt;React Server Components were purely covered, even though performance was a hot topic. RSC adoption is low, too (again, only based on my conversations)&lt;/p&gt;
&lt;h3&gt;Organisation &lt;span&gt;👏&lt;/span&gt;&lt;/h3&gt;
&lt;p&gt;By the end of day 2 it became a tradition to clap to the organisers at the beginning
of every talk. Indeed, the organisation was high class. I’m definitely returning next year!&lt;br /&gt;
Maybe with a lightning talk? &lt;span&gt;😄&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>Onboarding yourself as a Senior Software Engineer</title><link>https://kalabro.tech/onboarding-yourself/</link><guid isPermaLink="true">https://kalabro.tech/onboarding-yourself/</guid><description>In this article, I share onboarding tips that I&apos;ve learned from my experiences on both sides of the process.</description><pubDate>Sat, 15 Jul 2023 18:30:00 GMT</pubDate><content:encoded>&lt;p&gt;The success of the onboarding process depends equally on both parties. There is plenty of advice for the hiring side. I used it myself when onboarding developers of various levels as a Tech Lead. Today, I want to share some tips from another side of the table. I recently onboarded myself at a new job using my learning from onboarding other developers. It worked out very well, with feedback like, “It’s the fastest onboarding I’ve ever seen”, “Your onboarding has been spectacular”, and “Don’t be such an asshole”. I’m also trying to get better at the “Two truths, one lie” icebreaker.&lt;/p&gt;
&lt;p&gt;I attribute a lot of my success to a great team in charge of my onboarding. On my side, I did a few things well, too. In this article, I share the less obvious ones.&lt;/p&gt;
&lt;h2&gt;Get access&lt;/h2&gt;
&lt;p&gt;As dumb as it sounds, giving you access to critical tools and services needs to be done as soon as possible. Onboarding checklists usually cover access to tools like Jira or Toggl, and that’s okay. But what you really need is access to all the technical tools, from git and Jenkins to Figma and analytics. Chasing some accesses can be non-trivial due to special SSH key requirements or a gatekeeper person being on sick leave.&lt;/p&gt;
&lt;p&gt;It’s crucial to get access to all possible observability tools. You can learn so much about your project from Datadog if you only have access and a willingness to explore.&lt;/p&gt;
&lt;h2&gt;Enable Sponge Mode&lt;/h2&gt;
&lt;p&gt;I had to consciously enable “Sponge Mode” for my first month in a new company. “Sponge Mode” means that you absorb new information without challenging the status quo. It’s important to note down inconsistencies, ideas for improvements, flaws in processes, etc. Later, you will be able to raise them with the team. But first, you need to understand how the current system works by observing it with curiosity. “Interesting” should be your number one reaction to awkward things. Also, start using the language of the org as soon as possible. If people call the staging environment “preview”, call it “preview” too.&lt;/p&gt;
&lt;h2&gt;Meet people&lt;/h2&gt;
&lt;p&gt;Go to the office, share a personal story, play “Two truths, one lie”, have a beer, and be yourself throughout the process. Building relationships and gaining trust takes time. It’s a good idea to show others that you are interested in building relationships. And you are, because software development is a team sport.&lt;/p&gt;
&lt;h2&gt;Ask different people the same question&lt;/h2&gt;
&lt;p&gt;During the first weeks, you have the privilege to ask stupid questions and get detailed answers. Try to build a multi-dimensional model of your new workspace by asking different people the same question. For example, ask a fellow developer, Product Manager, and UX designer what they think your team is building. You’ll likely receive three different answers, all correct in their own context.&lt;/p&gt;
&lt;h2&gt;Read source code&lt;/h2&gt;
&lt;p&gt;Often, code onboarding is delayed in favour of process onboarding. It’s an unfortunate obstacle that you must proactively overcome. Even when my first week was fully booked with meetings and bureaucracy, I dedicated an hour every day to reading source code. Sometimes I had to read code on a train from my mobile. It allowed me to build my own opinion on the codebase and collect my questions for more productive onboarding discussions.&lt;/p&gt;
&lt;p&gt;Ultimately, it enabled me to start coding sooner and steadily increase the complexity of my tasks until I felt at home in my new project.&lt;/p&gt;
&lt;h2&gt;Setup tooling&lt;/h2&gt;
&lt;p&gt;You probably have your preferred IDE, clipboard manager, grammar checker, terminal, shortcuts, etc. It’s best to configure these little comfy things before you start coding. Be open to changing habits too. Pairing on a task is easier when the whole team uses the same editor.&lt;/p&gt;
&lt;h2&gt;Be useful&lt;/h2&gt;
&lt;p&gt;Usually, a newbie gets maximum attention in the first week or two, and then, slowly, everyone becomes busy again.
It’s expected that Senior Developers will take responsibility for their onboarding and complete it themselves. My main advice here is to try to be useful. I couldn’t take on larger tasks at first, but I could review and test some completed tasks, update the repo’s documentation, configure Renovate, etc. There are always multiple ways to help your team, and the sooner you start being useful, the sooner you become part of the team.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;The first three months in a new company are very intense for a new employee. I encourage developers to embrace all that intensity and proactively onboard themselves using my tips above or other tested techniques. For me, they worked very well. Compared to my interviewing experience, the onboarding was a breeze.
I’m looking forward to what’s next!&lt;/p&gt;</content:encoded></item><item><title>It depends! Exploring my favourite Renovate features for dependency updates</title><link>https://kalabro.tech/it-depends-renovate/</link><guid isPermaLink="true">https://kalabro.tech/it-depends-renovate/</guid><description>My top 5 features of Renovate, an open source tool for automated dependency updates.</description><pubDate>Sun, 18 Jun 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I learned about &lt;a href=&quot;https://docs.renovatebot.com/&quot;&gt;Renovate&lt;/a&gt; a couple of years ago when I was trying to group automated updates in Dependabot. It’s 2023, and Dependabot is &lt;a href=&quot;https://github.com/dependabot/dependabot-core/issues/1190&quot;&gt;still figuring out&lt;/a&gt; how to implement grouping. Not blaming them; dependency updates are challenging. Regardless of the approach you take, a fair amount of work is required to set up tools and processes for dependency management. In this post, I have collected a few of my favourite features and tricks when working with Renovate. Have I missed anything? Of course! Renovate is highly configurable (and well-documented), so if you need the full guide, please consult the official docs.&lt;/p&gt;
&lt;h2&gt;How Renovate works&lt;/h2&gt;
&lt;p&gt;Before delving into the details, let’s ask ChatGPT for a quick summary of how Renovate works:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Renovate is an open-source tool designed to automate the process of updating dependencies in a project. It works by identifying relevant package files within a codebase (including monorepos), then generating and scheduling pull requests to update those dependencies and their associated lock files. Users have the ability to customise the behaviour of the Renovate bot through configuration files and share configurations using ESLint-like presets.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The easiest way to get started with Renovate is to install it in your repo as a &lt;a href=&quot;https://github.com/apps/renovate&quot;&gt;GitHub App&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Install Renovate via GitHub App&quot; loading=&quot;lazy&quot; width=&quot;1186&quot; height=&quot;1504&quot; src=&quot;/_astro/install-on-github.BhD9VZ1U_QIQAR.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Renovate will automatically open a &lt;a href=&quot;https://github.com/kalabro/kalabro.tech/pull/42&quot;&gt;“Configure Renovate” PR&lt;/a&gt; with meaningful defaults. Once the config file is merged, Renovate will start opening regular pull requests with dependency updates. In theory, that’s it. In practice, you’ll likely want to tweak the configuration and fine-tune it to suit your specific needs and preferences.&lt;/p&gt;
&lt;h2&gt;Feature 1: config presets&lt;/h2&gt;
&lt;p&gt;Renovate supports hundreds of configuration options, or at least it feels that way. The resulting configuration file, even for a simple app, can end up being huge and cryptic. Fortunately, Renovate provides config presets that allow you to abstract away the details and share config pieces across multiple projects.&lt;/p&gt;
&lt;p&gt;One crucial config preset to be aware of is &lt;a href=&quot;https://docs.renovatebot.com/presets-config/#configbase&quot;&gt;config:base&lt;/a&gt;. It enables core Renovate features such as the Dependency Dashboard and monorepo grouping (more on this later in the article). It’s a good idea to base your configuration on &lt;code&gt;config:base&lt;/code&gt; or, in the case of JavaScript projects, on the &lt;code&gt;config:js-app&lt;/code&gt; or &lt;code&gt;config:js-lib&lt;/code&gt; presets.&lt;/p&gt;
&lt;p&gt;Here is an example configuration for my personal blog powered by Gatsby:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;$schema&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;https://docs.renovatebot.com/renovate-schema.json&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // up to date schema with all supported properties&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;extends&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;config:js-app&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // base on the recommended config for JS applications&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;schedule:monthly&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // can be schedule:weekly, schedule:weekends, etc&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;npm:unpublishSafe&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // the release must be at least 3 days old&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;:approveMajorUpdates&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // require explicit update approval on the dashboard before opening PR&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;:maintainLockFilesWeekly&quot;&lt;/span&gt;&lt;span&gt; // regenerates lock file to update all indirect deps&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;transitiveRemediation&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; true&lt;/span&gt;&lt;span&gt; // apply security updates for indirect (transitive) NPM dependencies&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As it’s a JavaScript project, I used the &lt;code&gt;config:js-app&lt;/code&gt; preset. I configured the update schedule, enabled the minimum release days restriction, disabled automatic PRs for major updates, and enabled weekly lock file maintenance. All using the default config presets. Thanks to JSON5 support, I can add comments to my config!&lt;/p&gt;
&lt;p&gt;If I have multiple projects similar to this one, I can convert my new configuration into a preset and refer to it in the config of the other projects:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;$schema&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;https://docs.renovatebot.com/renovate-schema.json&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;extends&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;github&amp;gt;kalabro/kalabro.tech//renovate/js-app&quot;&lt;/span&gt;&lt;span&gt; // loads my base config from another repo&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // Further extending config for this specific project&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;postUpdateOptions&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;yarnDedupeHighest&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It assumes that my &lt;a href=&quot;https://docs.renovatebot.com/config-presets/&quot;&gt;shareable config&lt;/a&gt; is available at &lt;code&gt;https://github.com/kalabro/kalabro.tech/renovate/js-app.json&lt;/code&gt;. As you probably guessed, you can keep customising the final config using other presets or configuration options. For example, you may need to group (or exclude) certain dependencies to reduce update noise.&lt;/p&gt;
&lt;h2&gt;Feature 2: grouping related updates&lt;/h2&gt;
&lt;p&gt;My blog has 20 Gatsby-related dependencies (what a mess, but it’s a topic for another blog post &lt;span&gt;😄&lt;/span&gt;). Updating them one by one is distracting and also likely to cause issues. What if we could ask Renovate to group all gatsby-* dependencies in one PR? No problem at all:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;packageRules&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;matchPackagePatterns&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&quot;^gatsby&quot;&lt;/span&gt;&lt;span&gt;]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;groupName&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;Gatsby packages&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.renovatebot.com/configuration-options/#packagerules&quot;&gt;packageRules&lt;/a&gt; is a cool and flexible config option for grouping Renovate updates. However, in my case, it’s not even necessary! My default config already has built-in knowledge on how to group &lt;a href=&quot;https://docs.renovatebot.com/presets-monorepo/#monorepogatsby&quot;&gt;Gatsby dependencies&lt;/a&gt;, thanks to Renovate’s base preset. It encompasses a wide range of curated package rules, especially for the Javascript ecosystem. Whether it’s Angular, Vue, or anything in between, Renovate has you covered.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Renovate groups all Gatsby updates in one PR&quot; loading=&quot;lazy&quot; width=&quot;1878&quot; height=&quot;1186&quot; src=&quot;/_astro/gatsby-monorepo-pr.DqPw2JLm_F2O3l.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;A few typical use cases for the packageRules configuration:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Separating dependencies and devDependencies. The latter is easier to automerge.&lt;/li&gt;
&lt;li&gt;Modifying the update schedule for specific types or groups of updates.&lt;/li&gt;
&lt;li&gt;Restricting updates for certain packages.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A word of caution. Although it may seem counterintuitive, I have found that smaller and more frequent updates tend to be more effective than large grouped PRs.&lt;/p&gt;
&lt;h2&gt;Feature 3: lock file updates&lt;/h2&gt;
&lt;p&gt;Renovate performs update checks for your direct dependencies, which are the ones listed in the package.json file. These direct dependencies can themselves have their own dependencies, which are known as indirect or transitive dependencies. Typical web projects often have much more transitive dependencies than direct ones. The easiest way to keep these dependencies up to date is by regularly refreshing the lock file. When you combine this approach with &lt;a href=&quot;https://docs.renovatebot.com/dependency-pinning/&quot;&gt;dependency pinning&lt;/a&gt;, lock file updates can be safely automerged.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  $&lt;/span&gt;&lt;span&gt;schema&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;https://docs.renovatebot.com/renovate-schema.json&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  extends&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;config:js-app&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // pins dependencies in package.json file&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;:maintainLockFilesWeekly&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; // regenerates lock file to update all transitive deps&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ]&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you prefer ranges (&lt;code&gt;&quot;^1.2.3&quot;&lt;/code&gt;) to pinning (&lt;code&gt;&quot;1.2.3&quot;&lt;/code&gt;), lock file maintenance &lt;strong&gt;will update everything&lt;/strong&gt; according to the ranges specified in your package.json. If this is what you are looking for, take a look at &lt;a href=&quot;https://docs.renovatebot.com/presets-config/#configsemverallmonthly&quot;&gt;&lt;code&gt;config:semverAllMonthly&lt;/code&gt;&lt;/a&gt; preset for inspiration.&lt;/p&gt;
&lt;h2&gt;Feature 4: Dependabot integration&lt;/h2&gt;
&lt;p&gt;Wait, what?&lt;br /&gt;
Yes, Renovate delegates vulnerability checks to Dependabot. When running on GitHub, Renovate checks Dependabot security alerts and immediately triggers the corresponding updates. To utilise this feature, you need to enable Dependabot alerts in your project settings.&lt;/p&gt;
&lt;p&gt;A vulnerability remediation PR may appear as follows:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Vulnerability remediation PR&quot; loading=&quot;lazy&quot; width=&quot;1904&quot; height=&quot;1394&quot; src=&quot;/_astro/security-pr.BYOBh_RU_Zfc70a.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Of course, this feature is configurable via the &lt;a href=&quot;https://docs.renovatebot.com/configuration-options/#vulnerabilityalerts&quot;&gt;vulnerabilityAlerts&lt;/a&gt; setting.&lt;br /&gt;
You can also override the &lt;a href=&quot;https://docs.renovatebot.com/configuration-options/#prbodytemplate&quot;&gt;&lt;code&gt;prBodyTemplate&lt;/code&gt;&lt;/a&gt; setting to remove the Renovate banner at the top.&lt;/p&gt;
&lt;h2&gt;Feature 5: Dependency Dashboard&lt;/h2&gt;
&lt;p&gt;For quite a while, I thought Renovate was a typical CI tool without UI. Luckily, I was mistaken. Renovate comes with a Dependency Dashboard where you can find a summary of all opened and pending updates, as well as any configuration issues. Below is a screenshot of the &lt;a href=&quot;https://github.com/kalabro/kalabro.tech/issues/43&quot;&gt;Dependency Dashboard&lt;/a&gt; for this blog (don’t worry about all the security issues, it’s a static website):&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Dependency Dashboard&quot; loading=&quot;lazy&quot; width=&quot;1884&quot; height=&quot;1178&quot; src=&quot;/_astro/dashboard-issue.DX1QMdCw_Z1j9ltb.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Instead of jumping back and forth between different PRs and Renovate app logs, I can view and manage everything from one place. It’s even more helpful when you’re maintaining multiple repositories.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;If you’re seeking an automated dependency management tool, I can confidently recommend Renovate. It’s well-designed, flexible, and open source. After using it for over a year, I particularly enjoy some of its features, such as shareable configs and the Dependency Dashboard. However, be aware that the initial learning curve can be steep, especially if you can’t use the preconfigured GitHub app.&lt;/p&gt;
&lt;p&gt;Are you using Renovate or any other dependency management tool? I’d love to know about your experience in the comments &lt;a href=&quot;https://dev.to/kalabro/it-depends-exploring-my-favourite-renovate-features-for-dependency-updates-3j5a&quot;&gt;on DEV&lt;/a&gt;!&lt;/p&gt;</content:encoded></item><item><title>Budgeting my communication capacity</title><link>https://kalabro.tech/communication-budget/</link><guid isPermaLink="true">https://kalabro.tech/communication-budget/</guid><description>As an introvert, I have a limited communication capacity that I refer to as my &quot;extravert budget&quot;. In this post, I will share how I learned to spend it more wisely in order to stay in sync with the IT reality.</description><pubDate>Sat, 03 Jun 2023 20:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Spring 2023 was fun. After 7 years in one company, I started a new role in a very different type of business, with a very different tech stack. Bold move for me! The entire process from interviewing to signing an offer to opening my first PR in a new team took almost a year. Landing a job in tech is hard. “The system is broken” is a common phrase to hear when engineers of all seniority levels share their hiring experiences. Funny enough, my new job is to build products for recruiters. Let’s see if I can help to “fix the system.” I’ll start by sharing some learnings from my recent job change project. And the first one is all about networking.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I’m an introvert. I enjoy the comfort and solitude of remote work with async communication. When I’m in the flow, I can solve a wide range of technical problems from backend to frontend, from planning to shipping, from enterprise to greenfield. Out of 100%, 80% of my capacity is technical, and the remaining 20% is communication skills. However, those 20% were barely enough to support all of my technical work, especially when I started taking on more management responsibilities. I had ambition, and growing often meant management.&lt;/p&gt;
&lt;p&gt;Introverts on the other side of the screen will understand that once you’ve spent all your communication budget, it’s a hard stop. I had been working like this for years, not leaving any of my “extrovert” budget for the outer IT space.&lt;/p&gt;
&lt;p&gt;As a result, when it was time to move on, I had very few useful connections and an outdated understanding of the IT recruitment market. I had to go through cold interviews with their live coding sessions, algorithmic problems, personality tests, and other humiliating experiences. Not fun at all.&lt;/p&gt;
&lt;p&gt;The most popular advice I received during that period was to keep interviewing. I was told to schedule as many interviews as possible until I became comfortable with them. I was advised to stretch my 20% even further.&lt;/p&gt;
&lt;p&gt;Today, I have a better advice for myself: budget your communication capacity to stay in sync with the IT reality.
This means reserving 5% of my extravert capacity for external activities and spending that 5% wisely. Booking every morning for yet another interview call is not wise at all.&lt;/p&gt;
&lt;p&gt;While 5% may seem like a small number, there are many activities in IT that bring a lot of value with just a bit of communication effort. Let me share some concrete examples that have worked for me:&lt;/p&gt;
&lt;h2&gt;Meetups and conferences&lt;/h2&gt;
&lt;p&gt;I found my current employer on meetup.com. I have also built strong connections with people I met at meetups and conferences. For me, the best way to network at a conference is to give a talk. This way, people come to me with specific questions, and I don’t need to worry about how to start a conversation. I can also build good relationships with other speakers by giving feedback and asking follow-up questions. Even if I don’t create any meaningful connections, I go home inspired and motivated. Good enough for me.&lt;/p&gt;
&lt;h2&gt;Mentorship and coaching&lt;/h2&gt;
&lt;p&gt;I feel much more comfortable in deeper 1:1 conversations than in group activities with strangers. Mentorship sessions were the main source of energy for me in 2022. I spoke to engineers and leaders from various organisations, and everyone was very helpful and supportive. Today, I have a couple of trusted mentors, and offer engineering mentorships myself on &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;ADPList&lt;/a&gt;. If you are new to mentorship read my post &lt;a href=&quot;https://kalabro.tech/where-to-find-mentor-2023/&quot;&gt;“Where to find a mentor”&lt;/a&gt; to get started.&lt;/p&gt;
&lt;h2&gt;Blogging&lt;/h2&gt;
&lt;p&gt;I created this little blog five years ago when I was playing with Gatsby during Christmas. Even with my occasional writing, it has become a great foundation for my public profile. As a bonus, it makes a positive first impression on recruiters. Writing skills are important in tech, as a lot of communication and knowledge sharing happens asynchronously.&lt;/p&gt;
&lt;h2&gt;Reading&lt;/h2&gt;
&lt;p&gt;Surprisingly, reading can be a decent networking tool. Writing a book review, giving a recommendation or participating in a book club - all of these activities can bring interesting people and ideas into my life. My &lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;“Learning Domain-Driven Design” book review&lt;/a&gt; is the most popular post on this blog to date.&lt;/p&gt;
&lt;h2&gt;Working from the office&lt;/h2&gt;
&lt;p&gt;To reserve some communication capacity for the activities mentioned above, I left behind my Tech Lead role and started as an individual contributor. However, as a Senior Engineer, I still have a lot of meetings to plan the work, pair on implementation, and stay up to date with the business in general. I was surprised to find out that all those activities drain me much less when I work from the office. Also, drawing on the whiteboard is a lot of fun!&lt;/p&gt;
&lt;h2&gt;Things that didn’t work for me&lt;/h2&gt;
&lt;p&gt;I’m not the first to discover the difficulties with networking for less outgoing engineers, and I know there are many other ways to show up in the global IT community. Some of them didn’t work for me (but they may work for you):&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Dale Carnegie tricks&lt;/strong&gt;&lt;br /&gt;
Not my thing, but I agree that learning some “tricks” can help in common situations, like starting a conversation with a stranger or having an argument with a colleague.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Online communities&lt;/strong&gt;&lt;br /&gt;
There are many topic-specific channels in Slack, Reddit, Discord, Twitch, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Open Source contributions&lt;/strong&gt;&lt;br /&gt;
Early in my career, I was lucky to meet great people from the Drupal open-source community. They influenced my career more than anyone else. Participating in open source requires time and effort, and at some point I disengaged in favor of client work.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Freelance gigs&lt;/strong&gt;&lt;br /&gt;
I know some very well-connected freelancers, but I’m not sure if my 5% communication budget will be enough to satisfy any client.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Building side projects&lt;/strong&gt;&lt;br /&gt;
Building something public can be a great starting point for building connections with very interesting, well-connected people. Pretty much every indie developer I met was a very interesting person with multiple talents.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;As an introvert, I have a limited communication capacity that I refer to as my “extravert budget”. In the past, I used to spend all of it at work, leaving nothing for other activities. My recent job change experience has made it clear to me that I need to budget my communication capacity wisely. Otherwise, I’m at risk of alienating from the global IT community.&lt;/p&gt;
&lt;p&gt;Firstly, I gave up some of my management responsibilities and made it a habit to come to the office twice a week. Surprisingly, in-person meetings drain me much less compared to Zoom calls. Additionally, I began working with a mentor to enhance the efficiency of my communication.&lt;/p&gt;
&lt;p&gt;By making these changes, I am now able to engage more with the global IT community and naturally expand my professional network. I have found several activities that work well for me, such as meetups, mentorship, and blogging.&lt;/p&gt;
&lt;p&gt;I’d love to know what works for you, especially if you consider yourself a less outgoing person. Please, share your experience in comments on &lt;a href=&quot;https://dev.to/kalabro/budgeting-my-communication-capacity-pb5&quot;&gt;DEV.to&lt;/a&gt; or contact me directly. Let’s connect! &lt;span&gt;😄&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>Thinking Architecturally (book review)</title><link>https://kalabro.tech/thinking-architecturally/</link><guid isPermaLink="true">https://kalabro.tech/thinking-architecturally/</guid><description>Thinking Architecturally by Nate Schutta is a short practical book for developers who want to stay current and grow in the rapidly changing tech industry. My favourite part is about “ilities”. Read on to learn more.</description><pubDate>Tue, 28 Feb 2023 10:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Today I want to share a short ebook by software architect and author &lt;a href=&quot;https://twitter.com/ntschutta&quot;&gt;Nate Schutta&lt;/a&gt;. Thinking Architecturally is available for free &lt;a href=&quot;https://tanzu.vmware.com/content/ebooks/thinking-architecturally&quot;&gt;on the VMWare website&lt;/a&gt; (author’s employer at the time of writing).&lt;/p&gt;
&lt;p&gt;Thinking Architecturally is a perfect read for mid-level &amp;amp; senior developers who want to focus on the right things in our noisy industry. Unlike many other architecture books, it stays away from technical jargon and philosophical abstractions. It’s practical and easy to read, even if you know nothing about software architecture. Each chapter ends with exercises (katas) that welcome you to think architecturally.&lt;/p&gt;
&lt;p&gt;If you trust my taste, go ahead and download the book. If you want a sneak peek, below you can find a few of my favourite quotes.&lt;/p&gt;
&lt;h2&gt;Technology Changes&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Technology will change and frankly that is what attracts many people to this industry. Learning new things keeps things fresh! But more than a few of us are guilty of practicing resume-driven design, of choosing a technology not for fitness to purpose, but to be able to add it to our CV.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the first chapter, Nate shows that technology repeats itself, and we can avoid unnecessary mistakes by learning from the past.&lt;/p&gt;
&lt;h2&gt;Thinking Strategically&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Hope is not a strategy. As a senior technologist, you need to keep up with changes in your industry.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The author talks about information hygiene, a T-shaped skillset as a better replacement for “Full-Stack”, Tech Radar and other strategic approaches to stay current in our industry. Most of his recommendations are not new. They are available for us now and for free. The book does a great job promoting good old practices like local meetups and book clubs.&lt;/p&gt;
&lt;h2&gt;Evaluating and Choosing Technologies&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Risks cannot be eliminated completely, but they can be managed. Consider each risk [of a new technology] and how you can mitigate it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you have ever wondered how to choose between multiple technologies or tools, chapters 3 &amp;amp; 4 of Thinking Architecturally are the answer. I usually follow my own &lt;a href=&quot;https://kalabro.tech/tech-lead-investigate/&quot;&gt;“How to investigate technical solutions”&lt;/a&gt; to evaluate new tools, but I have to admit that Nate’s version is much more thorough.&lt;/p&gt;
&lt;p&gt;Funny enough, the book includes an example of an evaluation of Angular and React (at the time when Angular was slightly more popular), and React wins it.&lt;/p&gt;
&lt;h2&gt;Introducing Technologies&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;As a senior technologist, your ability to communicate will dictate outcomes. Don’t be afraid to take that internal workshop on presentations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I noticed that most architects compare their work with marketing and sales. It’s not something we usually learn as software engineers. Throughout the book, Thinking Architecturally emphasises the importance of networking, (over)communication, and learning initiatives such as meetups, book clubs and hackathons.&lt;/p&gt;
&lt;p&gt;These “soft” activities are strategic tools for architects to cultivate the right architectural principles across the organisation.&lt;/p&gt;
&lt;h2&gt;Maintaining Technologies (“ilities”)&lt;/h2&gt;
&lt;p&gt;I met Nate, the author of Thinking Architecturally, at &lt;a href=&quot;https://gsas.io/&quot;&gt;GSAS Barcelona&lt;/a&gt;, where he ran a workshop with the same title. At the workshop, we worked in groups on a random &lt;a href=&quot;http://fundamentalsofsoftwarearchitecture.com/katas/&quot;&gt;Architectural Kata&lt;/a&gt; (another great resource available for free). This is when I learned about “ilities” - software quality attributes that often end with “ility” (Scalability, Usability, Maintainability, etc).&lt;/p&gt;
&lt;p&gt;If you’ve been recently preparing for the systems design interview, you may recognise “nonfunctional requirements”.&lt;/p&gt;
&lt;p&gt;Below is what Nate says (and I very much agree):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For much of my career, I referred to the ilities as the nonfunctional requirements. And that term is still appropriate! However, a colleague convinced me there was a better phrase. We were walking through the architecturally significant requirements on an application when he made a great point. Most customers hear the “nonfunctional” part of the term and decide immediately that they only want functional requirements, stopping the conversation. But we have to convince them of the importance of something they can’t readily see. Framing the quality goals as something nonfunctional implies they aren’t required for the system to work.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Chapter 6 of the book gives clear guidance on how to identify, rank and measure quality attributes. It helped me to structure my intuitive approach to day-to-day software design. It helped me to think architecturally!&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://tanzu.vmware.com/content/ebooks/thinking-architecturally&quot;&gt;Thinking Architecturally&lt;/a&gt; is my first recommendation for software engineers looking for ways to stay current and grow in the rapidly changing tech industry. This short ebook has already affected how I mentor senior developers on &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;ADPList&lt;/a&gt; and how I approach my own learning.&lt;/p&gt;
&lt;p&gt;If you are interested in software architecture topic, you may also like my article &lt;a href=&quot;https://kalabro.tech/road-to-software-architecture-frontend-edition/&quot;&gt;The road to Software Architecture (frontend edition)&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Fast by default with Next.js</title><link>https://kalabro.tech/fast-by-default-nextjs/</link><guid isPermaLink="true">https://kalabro.tech/fast-by-default-nextjs/</guid><description>Next.js is a great example of a “fast by default” mindset. It popularises web performance best practices by making them easy to use. In this article I share my favourite performance features of Next.js framework.</description><pubDate>Mon, 20 Feb 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;There is a famous quote from Donald Knuth that premature performance optimisation is the root of all evil. As usually happens with quotes, it was often taken out of context and amplified.&lt;/p&gt;
&lt;p&gt;It’s 2023, and despite all the efforts, the web remains slow. Developers tend to blame frameworks, programming languages, browsers, and even customers who constantly change requirements. Every new library or tool states that it’s blazing fast, yet we keep building slow sites with it.&lt;/p&gt;
&lt;p&gt;If we compare React bundle size throughout the years, it hasn’t significantly grown. What has grown is the amount of our own code written on top of React. It has grown so much that React itself started shifting its parts to the server (Server Components), which sounds insane for a frontend library!&lt;/p&gt;
&lt;p&gt;In this article, we will see how the Next.js framework encourages performance-first development by offering or even enforcing several web optimisations out of the box. None of them are specific to Next.js. We can (and should) implement them using any other web development tools.&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#javascript-code-splitting&quot;&gt;JavaScript Code Splitting&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#preload-javascript-on-link-visibility&quot;&gt;Preload JavaScript on link visibility&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#dynamic-import&quot;&gt;Dynamic import&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#third-party-scripts&quot;&gt;Third-party scripts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#fonts&quot;&gt;Fonts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#images&quot;&gt;Images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#static-optimisation&quot;&gt;Static optimisation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#edge-middleware&quot;&gt;Edge Middleware&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#react-server-components-and-streaming-ssr&quot;&gt;React Server Components and streaming SSR&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#to-summarise&quot;&gt;To summarise&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;JavaScript Code Splitting&lt;/h2&gt;
&lt;p&gt;From the very beginning, Next.js provided a page-based routing system. To make your app available at example.com/about you had to create &lt;code&gt;pages/about.js&lt;/code&gt; file in Next.js. Many developers found this structure intuitive and easy to use.&lt;/p&gt;
&lt;p&gt;Under the hood, it allowed Next.js to implement &lt;a href=&quot;https://www.patterns.dev/posts/route-based/&quot;&gt;Route-based Splitting&lt;/a&gt;, which was further optimised in &lt;a href=&quot;https://nextjs.org/blog/next-9-2#improved-code-splitting-strategy&quot;&gt;version 9.2&lt;/a&gt; to benefit from HTTP/2.&lt;/p&gt;
&lt;h2&gt;Preload JavaScript on link visibility&lt;/h2&gt;
&lt;p&gt;Once we break our JS into multiple chunks, we must ensure they are loaded at the right time. Link component form Next.js prefetches corresponding page code using &lt;a href=&quot;https://www.patterns.dev/posts/import-on-visibility/&quot;&gt;Import on Visibility&lt;/a&gt; or &lt;a href=&quot;https://www.patterns.dev/posts/import-on-interaction/&quot;&gt;Import On Interaction&lt;/a&gt; patterns.&lt;/p&gt;
&lt;p&gt;As you scroll down the notion.so website, you can notice some extra scripts are being loaded. If you then decide to go to another page, all necessary JavaScript will be already in place.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;By the time I scrolled to the footer, 29 page bundles have been loaded&quot; loading=&quot;lazy&quot; width=&quot;3248&quot; height=&quot;2112&quot; src=&quot;/_astro/prefetched-pages.BGeFnlXo_Z18gyX7.webp&quot; /&gt;&lt;/p&gt;
&lt;h2&gt;Dynamic import&lt;/h2&gt;
&lt;p&gt;Heavy code that is only used under certain circumstances can be lazy-loaded using Dynamic Import. This technique requires developers first to identify candidates for lazy loading and then implement a smooth loading experience for the user.&lt;/p&gt;
&lt;p&gt;For many years, Next.js has been offering &lt;a href=&quot;https://nextjs.org/docs/advanced-features/dynamic-import&quot;&gt;&lt;code&gt;next/dynamic&lt;/code&gt;&lt;/a&gt; function for this purpose. Under the hood, it’s just a wrapper around &lt;code&gt;React.lazy&lt;/code&gt; and &lt;code&gt;Suspense&lt;/code&gt; that you can use in any React project.&lt;/p&gt;
&lt;h2&gt;Third-party scripts&lt;/h2&gt;
&lt;p&gt;As you may know, &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag behaviour is very complex. An external script can completely ruin your Web Vitals regardless of how well you optimise your code. Below is a quote from a brilliant tutorial by the Google team &lt;a href=&quot;https://www.patterns.dev/posts/loading-sequence/&quot;&gt;“Optimise your loading sequence”&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Scripts get different priorities based on where they are in the document and whether they are async, defer, or blocking. Blocking scripts requested before the first image ( or an image early in the document) are given higher priority over blocking scripts requested after the first image is fetched. Async/defer/injected scripts, regardless of where they are in the document, have the lowest priority. Thus we can prioritise different scripts by using the appropriate attributes for async and defer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The main takeaway is that there is no one right way to include scripts on the site. We need to consider the entire loading sequence, versions of frameworks and browsers, the target audience of the site and a handful of other factors.&lt;/p&gt;
&lt;p&gt;Back to Next.js, its &lt;a href=&quot;https://nextjs.org/docs/basic-features/script&quot;&gt;&lt;code&gt;&amp;lt;Script&amp;gt;&lt;/code&gt;&lt;/a&gt; component provides a simplified interface for HTML &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Script&lt;/span&gt;&lt;span&gt; src&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;https://example.com/script.js&quot;&lt;/span&gt;&lt;span&gt; /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This code can be put anywhere in the app, and Next.js will load it at the most appropriate time (after the page becomes interactive). It’s best for most scripts, such as Google Tag Manager or Google Analytics.&lt;/p&gt;
&lt;p&gt;If you need to load the script much earlier (or much later), you can use the &lt;code&gt;strategy&lt;/code&gt; property.&lt;/p&gt;
&lt;h2&gt;Fonts&lt;/h2&gt;
&lt;p&gt;The easiest way to optimise Largest Contentful Paint (LCP) metric is to place a large text block at the top of your page. For example, Next.js homepage uses &lt;code&gt;&amp;lt;h1&amp;gt;&lt;/code&gt; as LCP element:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;nextjs.org LCP in PageSpeed Insights report&quot; loading=&quot;lazy&quot; width=&quot;1404&quot; height=&quot;908&quot; src=&quot;/_astro/nextjs-lcp.kKy84VM-_Z8GEoS.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Commonly, web designs are based on non-standard fonts aka &lt;em&gt;web fonts&lt;/em&gt;. Loading them from Google Fonts or similar services takes precious time and creates other issues like Cumulative Layout Shift (CLS).&lt;/p&gt;
&lt;p&gt;Next.js team has been working on fonts optimisation since version 10. They started with inlining font CSS and adding &lt;code&gt;&amp;lt;link preconnect&amp;gt;&lt;/code&gt; hint for the browsers and by &lt;a href=&quot;https://nextjs.org/blog/next-13#nextfont&quot;&gt;version 13&lt;/a&gt; ended up with built-in self-hosting and optimisation for any font file.&lt;/p&gt;
&lt;p&gt;Font optimisation is hard, and I’m incredibly grateful to the Next.js team for handling it for me.&lt;/p&gt;
&lt;h2&gt;Images&lt;/h2&gt;
&lt;p&gt;On many websites, the main contributor to performance issues is media. When I work on performance, I always start with images. They are usually easy to fix and bring an immediate, noticeable boost.&lt;/p&gt;
&lt;p&gt;Thanks to WebP and AVIF, lazy loading and aspect-ratio, srcset and picture tag, we can deliver the most appropriate images to our users. Next.js offers a smart wrapper around &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt; tag that utilises all mentioned techniques (and probably more) to reduce the amount of development work required to render an image in 2023.&lt;/p&gt;
&lt;p&gt;Below is a screenshot with the resulting markup generated by Next.js Image component from &lt;a href=&quot;https://github.com/vercel/next.js/tree/canary/examples/image-component&quot;&gt;this example&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;The resulting markup generated by Next.js Image component&quot; loading=&quot;lazy&quot; width=&quot;3024&quot; height=&quot;1458&quot; src=&quot;/_astro/nextjs-image.BnuH0qsz_ZGEwGE.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;As with any opinionated solution, &lt;code&gt;next/image&lt;/code&gt; has its limitations, but it’s a great starting point that sets the bar high.&lt;/p&gt;
&lt;h2&gt;Static optimisation&lt;/h2&gt;
&lt;p&gt;A few years ago, the industry became obsessed with Static Site Generation (SSG). Good old static HTML was back under a fancy name. This very site was built using an early GatsbyJS version.&lt;/p&gt;
&lt;p&gt;Indeed, static sites are more secure, faster, and cheaper. In 2020, &lt;a href=&quot;https://nextjs.org/blog/next-9-3#next-gen-static-site-generation-ssg-support&quot;&gt;Next.js announced&lt;/a&gt; Automatic Static Optimisation: a simple API that uses SSG for static parts of the app while serving the rest of the app dynamically.&lt;/p&gt;
&lt;p&gt;Most dynamic sites couldn’t benefit from SSG at that time. First of all, it would require a massive rewrite. But the main problem was to trigger rebuilds every time you needed to update your static pages. We at SystemSeed overcame this issue by using Cloudflare CDN cache. You can learn more about this approach in my article &lt;a href=&quot;https://kalabro.tech/serve-like-static/&quot;&gt;“Let Cloudflare CDN speed up your classic website like it’s static”&lt;/a&gt;. Guillermo Rauch, Vercel’s CEO, later contacted me about that article:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Guillermo Rauch, Vercel’s CEO, later contacted me about my article “Let Cloudflare CDN speed up your classic website like it’s static”&quot; loading=&quot;lazy&quot; width=&quot;1650&quot; height=&quot;662&quot; src=&quot;/_astro/guillermo-rauch-cloudflare-cache.Dhu42c21_ZPm9vg.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Messages like this are the greatest reward for the author! &lt;span&gt;💚&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;These days Next.js provides a built-in way to regenerate static pages. It’s called &lt;a href=&quot;https://nextjs.org/docs/basic-features/data-fetching/incremental-static-regeneration&quot;&gt;Incremental Static Regeneration (ISR)&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Edge Middleware&lt;/h2&gt;
&lt;p&gt;Next.js is funded by Vercel, a hosting platform that’s primary focus is speed. While most Next.js performance features are hosting-neutral, some are harder to self-host. &lt;a href=&quot;https://vercel.com/docs/concepts/functions/edge-middleware&quot;&gt;Edge Middleware&lt;/a&gt; is a good example. It’s inspired by (and based on) Cloudflare Workers. If you are a Vercel customer, you can immediately benefit from blazing-fast edge computing without leaving your favourite framework codebase. Amazing!&lt;/p&gt;
&lt;p&gt;But even if we are not on Vercel, their setup inspires us to build something similar with the tools available to us.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vercel deploys the middleware code to edge functions, which are invoked before the request reaches the CDN. This allows static pages can be cached, as the middleware is called before the CDN sends back a cached response&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The quote above is from the &lt;a href=&quot;https://github.com/serverless-stack/open-next&quot;&gt;OpenNext&lt;/a&gt; project, which aims to port Vercel setup to other serverless platforms.&lt;/p&gt;
&lt;h2&gt;React Server Components and streaming SSR&lt;/h2&gt;
&lt;p&gt;From React 18 release notes:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In React 18, you can start using Suspense for data fetching in opinionated frameworks like Relay, Next.js, Hydrogen, or Remix. Ad hoc data fetching with Suspense is technically possible, but still not recommended as a general strategy.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;React is getting more complicated. It took several years to release Suspense, and it will take another few years to adopt it. Given the level of complexity, it’s wise to delegate implementation details to experienced frameworks’ maintainers.&lt;/p&gt;
&lt;p&gt;Next.js 13, the latest release to date, introduces a new routing system that supports streaming SSR, Server Components, and Suspense for data fetching. By pushing more code to the server, we can reduce the client-side JavaScript and speed up hydration.&lt;/p&gt;
&lt;p&gt;If you are new to React Server Components, I recommend to start with &lt;a href=&quot;https://beta.nextjs.org/docs/rendering/fundamentals&quot;&gt;Rendering Fundamentals&lt;/a&gt; documentation. Welcome to the new Next.js!&lt;/p&gt;
&lt;p&gt;I’m sure the old pages routing will keep working for a while, but the new things will all go to the &lt;code&gt;app&lt;/code&gt; directory.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;I welcome you to rethink Knuth’s words about premature performance optimisation and embrace the “Fast by default” mindset when building websites. Not all optimisations are evil. Some of them have become common sense and should be applied &lt;em&gt;by default&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Next.js is an excellent example of the “fast by default” mindset. It popularises web performance best practices by making them easy to use (or even enforcing on ESLint level). I like this approach and apply it to other tools.&lt;/p&gt;
&lt;p&gt;Similar to mobile-first or security-first development cultures, it takes time to establish “fast by default” mindset, and I’m grateful to Next.js for helping me with it.&lt;/p&gt;</content:encoded></item><item><title>Three tricks to get in focus mode</title><link>https://kalabro.tech/focus-mode-three-tricks/</link><guid isPermaLink="true">https://kalabro.tech/focus-mode-three-tricks/</guid><description>In modern working conditions, software engineers often struggle with focus. I discovered a few tricks that I share in this article.</description><pubDate>Sun, 05 Feb 2023 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I find myself very lucky to be a software engineer. I enjoy solving problems with code, and it usually doesn’t require any effort to go into “focus mode”. Quite the opposite - it’s sometimes hard to stop thinking about that tricky bug and close my laptop.&lt;/p&gt;
&lt;p&gt;Still, there are situations when distractions and multitasking prevent me from achieving what I want. I have a few tricks in my toolkit to restore focus and attack the problem, even if it’s a tough one.&lt;/p&gt;
&lt;h2&gt;What is the focus mode&lt;/h2&gt;
&lt;p&gt;Focus mode is a tool to handle certain types of work. Like a hammer or a needle, it’s helpful in some situations and harmful in others. &lt;strong&gt;Focus mode is never the end goal.&lt;/strong&gt; Before trying to focus, I need to figure out what and why I want to achieve with its help.&lt;/p&gt;
&lt;p&gt;To focus means to keep our full attention on one thing for a long enough period of time. I haven’t met any person who doesn’t know how to do it. We all constantly go in and out of focus, naturally guided by our interests and curiosity.&lt;/p&gt;
&lt;p&gt;Beyond focus, we can sometimes fall into the flow state, a highly intense and rewarding experience of full immersion in a particular activity. Mihaly Csikszentmihalyi studied the flow state his whole life and wrote &lt;a href=&quot;https://www.goodreads.com/book/show/66354.Flow&quot;&gt;a comprehensive book&lt;/a&gt; on the subject. What’s crucial for this article is that &lt;strong&gt;the flow state usually requires focus as a prerequisite&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://upload.wikimedia.org/wikipedia/commons/thumb/f/f6/Challenge_vs_skill.svg/480px-Challenge_vs_skill.svg.png&quot; alt=&quot;Mental state in terms of challenge level and skill level, according to Csikszentmihalyi&apos;s flow model, Wikipedia&quot; /&gt;&lt;/p&gt;
&lt;p&gt;_Mental state in terms of challenge level and skill level, according to Csikszentmihalyi’s flow model, &lt;a href=&quot;https://en.wikipedia.org/wiki/Flow_(psychology)&quot;&gt;Wikipedia&lt;/a&gt;_&lt;/p&gt;
&lt;p&gt;Below I share three tricks that help me get into focus mode, but it’s important to remember that they are merely techniques for occasional use. If I regularly experience difficulties with focus, I know it’s time to revisit my plans. Are they aligned with my north star? Are they achievable?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This post was inspired by a question from one of my mentorship sessions at &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;ADPList&lt;/a&gt;. Mentorship is a great way to explore deeper reasons behind the lack of focus. Read &lt;a href=&quot;https://kalabro.tech/where-to-find-mentor-2023/&quot;&gt;“Where to find a mentor”&lt;/a&gt; if you are interested in this route.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;Trick 1: “Is it technically possible?”&lt;/h2&gt;
&lt;p&gt;6 am. My alarm throws me into a dark and cold Monday morning. Even my cat, who is supposed to be a nocturnal animal, is against this idea. Before I even notice it, I start looking for reasons to stay in bed.&lt;/p&gt;
&lt;p&gt;In such moments I ask myself: is it technically possible?
Can someone like me get up at 6 am? Is it doable for a woman who went to bed at 10 pm and has scheduled some writing work before her regular working hours?&lt;/p&gt;
&lt;p&gt;In 99% of situations, the answer is yes. It’s not that cold in the kitchen for me to freeze. And if it’s dark, I can turn on the lights &lt;span&gt;💡&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;Trick 2: Microtask&lt;/h2&gt;
&lt;p&gt;It’s common practice to break work into small achievable chunks of work. Yet, even a well-scoped task can be hard to start. In this situation, I create &lt;strong&gt;a microtask - the first ridiculously small step&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;For example, if I need to build a new project, a microtask can be “initialise git repository” or “print hello world on the screen”. It helps to write the microtask down even if typing it will take longer than actually doing it!&lt;/p&gt;
&lt;p&gt;If it’s impossible to extract a meaningful microtask, I use the &lt;strong&gt;“Do X for 30 min”&lt;/strong&gt; template.
Let’s say I want to get better at solving algorithms problems, but I don’t know where to start. I put the microtask “Work on leetcode for 30 min” in the &lt;a href=&quot;https://www.centered.app/&quot;&gt;Centered&lt;/a&gt; app and stare at the screen for 30 min. Half an hour later, I will understand my current level much better and can create more meaningful microtasks.&lt;/p&gt;
&lt;p&gt;Microtask is similar to micromanagement. Only apply it to your own tasks when you are stuck.&lt;/p&gt;
&lt;h2&gt;Trick 3: Add flavour&lt;/h2&gt;
&lt;p&gt;If I don’t have control over what I do, I can at least control how I do it. I call it flavour. Example:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What:&lt;/strong&gt; review and update legacy documentation&lt;br /&gt;
&lt;strong&gt;How (adds interest flavour):&lt;/strong&gt; generate images from your documentation using AI tool&lt;br /&gt;
&lt;strong&gt;How (adds challenge flavour):&lt;/strong&gt; make resulting documentation shorter, not longer&lt;br /&gt;
&lt;strong&gt;How (adds value flavour):&lt;/strong&gt; pair on it with a more junior developer&lt;br /&gt;
&lt;strong&gt;How (adds fun flavour):&lt;/strong&gt; work on it from your favourite café&lt;/p&gt;
&lt;p&gt;Deciding how I will do my work sparks motivation and increases self-accountability even when I don’t feel deeply connected to the end goal of the task.&lt;/p&gt;
&lt;h2&gt;And many more&lt;/h2&gt;
&lt;p&gt;While writing this post, I discovered a good list of things that help me focus. Most of them are common sense rather than tricks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Early mornings&lt;/li&gt;
&lt;li&gt;Sticking to schedule&lt;/li&gt;
&lt;li&gt;Working in solitude&lt;/li&gt;
&lt;li&gt;Keeping mind clear (journaling, meditation, exercises)&lt;/li&gt;
&lt;li&gt;External deadline / commitment&lt;/li&gt;
&lt;li&gt;Involving other people&lt;/li&gt;
&lt;li&gt;Music for concentration&lt;/li&gt;
&lt;li&gt;Embracing a healthy dose of discomfort&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;We often find ourselves fully focused and dedicated when we work on interesting and challenging problems. It feels great, and we want more of that flow state.&lt;/p&gt;
&lt;p&gt;Over the years, I learned a few tricks to restore my focus. I’m sure you have your own tricks, too. Please share in the comments &lt;a href=&quot;https://dev.to/kalabro/three-tricks-to-get-in-focus-mode-332#comments&quot;&gt;on DEV.to&lt;/a&gt;. I’d love to learn from you!&lt;/p&gt;</content:encoded></item><item><title>The road to Software Architecture (frontend edition)</title><link>https://kalabro.tech/road-to-software-architecture-frontend-edition/</link><guid isPermaLink="true">https://kalabro.tech/road-to-software-architecture-frontend-edition/</guid><description>According to the State of JS report, the “Code Architecture” problem is the main pain point in frontend development. This post is an attempt to connect the Software Architecture discipline with the modern frontend.</description><pubDate>Tue, 31 Jan 2023 09:00:00 GMT</pubDate><content:encoded>&lt;p&gt;According to the &lt;a href=&quot;https://2022.stateofjs.com/en-US/opinions/#top_js_pain_points&quot;&gt;State of JS report&lt;/a&gt;, the “Code Architecture” problem was the main pain point for JavaScript developers in 2022.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;JavaScript Pain Points from the State of JS report&quot; loading=&quot;lazy&quot; width=&quot;1914&quot; height=&quot;1100&quot; src=&quot;/_astro/state-of-js.BCi4b9Tx_2raS0M.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In this post, I argue that folders are better than microservices, disagree with Uncle Bob, and cite Martin Fowler’s advice against the Gang Of Four book. This is my road to Software Architecture. Let’s go!&lt;/p&gt;
&lt;h2&gt;My background&lt;/h2&gt;
&lt;p&gt;As a Full-Stack Developer, I’ve been involved in the software design process since very early in my career.&lt;/p&gt;
&lt;p&gt;Even before I realised it, I started making everyday architectural decisions such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;where to put my code&lt;/li&gt;
&lt;li&gt;what &amp;amp; how to test&lt;/li&gt;
&lt;li&gt;which framework to use&lt;/li&gt;
&lt;li&gt;how to spread the work between multiple developers, and so on&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It turned out these little decisions matter in the long run. Some pieces of PHP code that I wrote eight years ago are still in use in production.&lt;/p&gt;
&lt;p&gt;The oldest React app that is currently in use was started by my team at SystemSeed in 2017 from the Create React App template. We’ve managed to stay on un-ejected CRA all these years and recently upgraded the codebase to React 18.&lt;/p&gt;
&lt;p&gt;Another long-living project was built with &lt;a href=&quot;https://vercel.com/blog/next2&quot;&gt;Next.js 2&lt;/a&gt;. Today it runs on top of Next.js 13 and serves thousands of users around the globe.&lt;/p&gt;
&lt;p&gt;Working on such projects brings a lot of problems that I can classify as “Code Architecture” from the State of JS report. Let me elaborate on what I understand by that.&lt;/p&gt;
&lt;h2&gt;Software Architecture (as I understand it)&lt;/h2&gt;
&lt;p&gt;There are many clever definitions of software architecture. In this article, I lean towards the term “software architecture” to avoid any confusion between “software design” and “UI design”.&lt;/p&gt;
&lt;p&gt;Philosophically speaking, &lt;strong&gt;software architecture work is about finding optimal answers to questions that don’t have one correct answer&lt;/strong&gt;. I mean those questions with zero answers on StackOverflow (apart from the famous “It depends”).&lt;/p&gt;
&lt;p&gt;Architectural problems often appear at the worst possible moment, disturbing our coding flow and making us feel annoyed and uncertain. That’s why software architecture can feel like a pain point, but in fact, it’s an essential part of our jobs, and Copilots can’t do it yet!&lt;/p&gt;
&lt;p&gt;Traditionally, software architecture decisions have been part of more senior roles’ responsibilities. Some companies even have a dedicated Software Architect role. That person, though, wouldn’t be able to decide on every little detail. They likely came from the backend background to oversee the systems on a very high level. So in practice, &lt;strong&gt;developers who actually implement frontend applications are the main contributors to the resulting code architecture&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;That’s suddenly a lot of pressure on us! Let’s see how we can reduce our anxiety around code architecture and become better at it.&lt;/p&gt;
&lt;h2&gt;Learn your tools&lt;/h2&gt;
&lt;p&gt;“Clean Architecture”, the famous book by Uncle Bob, states that we should design framework-agnostic architectures:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Good architectures are centered on use cases so that architects can safely describe the structures that support those use cases without committing to frameworks, tools, and environments.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Really? Well, I’m hired as a framework specialist; how can I put it aside?&lt;/p&gt;
&lt;p&gt;The answer turned out to be simple. Before you can put the frameworks aside, you need to learn a few of them on a very good level. Once you become fluent in a couple of frameworks, you start to see patterns and trade-offs. At that point, recommendations from Uncle Bob will start to make sense.&lt;/p&gt;
&lt;p&gt;For example, these days, I focus on improving my React skills. For me, learning advanced React patterns is a valuable time investment and a good step towards understanding modern frontend in general.&lt;/p&gt;
&lt;p&gt;My decision to focus on one established technology means &lt;strong&gt;saying no to many other tools and frameworks&lt;/strong&gt; highlighted in the State of JS report. It’s uncomfortable to feel “left behind,” but I am confident that it will pay off.&lt;/p&gt;
&lt;p&gt;As Nathaniel Schutta says in &lt;a href=&quot;https://tanzu.vmware.com/content/ebooks/thinking-architecturally&quot;&gt;“Thinking Architecturally”&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I thought I’d “missed the wave” of some technology or another. What I didn’t appreciate at the time is that new technologies are a lot like buses — one comes every 15 minutes or so.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once I understand the tool &lt;strong&gt;deeply&lt;/strong&gt;, I start making more informed architectural decisions.&lt;/p&gt;
&lt;h2&gt;Embrace folders&lt;/h2&gt;
&lt;p&gt;Many of us jumped into microservices way too soon. There is a much safer (and cheaper) option — folders!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Folders are logical boundaries&lt;/strong&gt; of our modules, features, components, etc. Well-organised file structure makes project architecture readable and extendable.&lt;/p&gt;
&lt;p&gt;React community has a couple of suggestions to start with (&lt;a href=&quot;https://reactjs.org/docs/faq-structure.html&quot;&gt;1&lt;/a&gt;, &lt;a href=&quot;https://github.com/alan2207/bulletproof-react&quot;&gt;2&lt;/a&gt;). The official site says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you’re just starting a project, don’t spend more than five minutes on choosing a file structure.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s not because file structure is not important. It’s because it should change as your project evolves. Let’s say you had to touch files from ten different folders to ship a new feature. It’s a sign that you need to review your folder structure (and your logical boundaries).&lt;/p&gt;
&lt;h2&gt;Testable code&lt;/h2&gt;
&lt;p&gt;Most people write tests because they want to be confident that the app works as expected after code changes. As a nice bonus, &lt;strong&gt;testable code results in better code architecture&lt;/strong&gt;!&lt;/p&gt;
&lt;p&gt;For a long time, I was only using end-to-end tests that treated the resulting app as a black box. It allowed me to write mediocre code with spaghetti from dependencies, inconsistencies and workarounds. Everything changed when I started to imagine how I would write other types of tests for my code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Visual regression test&lt;/strong&gt; (e.g. component look &amp;amp; feel with dummy content)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unit test&lt;/strong&gt; (e.g. how the utility function calculates the fee based on ordered products)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Integration test&lt;/strong&gt; (e.g. how the Basket component responds to user interactions such as hover and click)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;End-to-end test&lt;/strong&gt; (finally, how the entire shopping flow works in the browser)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Even if I don’t write all these types of tests, thinking about them helps me structure my code better.&lt;/p&gt;
&lt;h2&gt;What about design patterns?&lt;/h2&gt;
&lt;p&gt;Design patterns in software are similar to the chords in music. Someone discovered them many years ago, but people keep combining the chords in many different ways to compose new songs.&lt;/p&gt;
&lt;p&gt;Just like learning chords by the book may be difficult at the beginning, classic design patterns books may not make any sense for a frontend developer.&lt;/p&gt;
&lt;p&gt;A quote from Martin Fowler’s review of the famous Design Patterns book:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Despite my praise, this is not an easy book to read. I don’t recommend it until you’re pretty comfortable with the basic principles of OO design. Even then it takes a fair investment of effort to really appreciate the book. Unlike most books, however, it amply pays that investment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Luckily, we can &lt;strong&gt;learn about modern JavaScript and React design patterns from a free book &lt;a href=&quot;https://www.patterns.dev/&quot;&gt;Patterns.dev&lt;/a&gt;&lt;/strong&gt;. It describes all common patterns in a frontend-friendly language with practical examples and animations.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://www.patterns.dev/posts/observer-pattern/&quot;&gt;Observer Pattern&lt;/a&gt; animation from patterns.dev (video)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.patterns.dev/resources/&quot;&gt;The Community Patterns&lt;/a&gt; section lists some framework-specific resources to dig deeper.&lt;/p&gt;
&lt;h2&gt;Business logic&lt;/h2&gt;
&lt;p&gt;The pieces of UI logic we write for the frontend may be trivial, but their large volume and constant changes become a challenge as the projects grow. The most coherent approach to business logic that I have found so far is Domain-Driven Design (DDD).&lt;/p&gt;
&lt;p&gt;DDD places a strong emphasis on building a shared understanding of the problem domain and focuses team efforts on the most important parts (“Core” subdomain).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Domain-Driven Design is about letting your business domain drive your design decisions.&lt;br /&gt;
Vlad Knononov, &lt;a href=&quot;https://a.co/d/ez4dQLr&quot;&gt;“Learning Domain-Driven Design”&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In other words, development teams should understand and stay focused on the problem the business is trying to solve for its users.&lt;/p&gt;
&lt;p&gt;If it sounds too abstract, I recommend the “Learning Domain-Driven Design” book (&lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;read my review here&lt;/a&gt;).
I’m currently exploring ways to apply DDD principles to frontend architecture problems. Stay tuned for more articles on the topic.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;Some questions about software development don’t have one correct answer apart from “It depends”. We face them every day, and our answers contribute to the architecture of the projects we work on.&lt;/p&gt;
&lt;p&gt;Developers who know their tools and cover their code with tests tend to make better architectural decisions. That’s why I suggest starting by mastering essential frontend tooling.&lt;/p&gt;
&lt;p&gt;Once we feel comfortable with the tooling, we can zoom out and think in terms of design patterns and business problems. It’s a whole new world! I made several attempts to enter it, and I found the following resources most helpful so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.patterns.dev/&quot;&gt;Patterns.dev&lt;/a&gt; - frontend-friendly book on design patterns&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.goodreads.com/en/book/show/39996759&quot;&gt;“A Philosophy of Software Design”&lt;/a&gt; - my favourite software engineering book&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.amazon.com/dp/B09J2CMJZY?ref_=cm_sw_r_cp_ud_dp_WFMGPCPV66M1VA8P2CCS&quot;&gt;Learning Domain-Driven Design&lt;/a&gt; - good introduction to DDD (&lt;a href=&quot;https://kalabro.tech/learning-domain-driven-design-book/&quot;&gt;my review&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That’s how far I went on my road to Software Architecture.&lt;br /&gt;
Follow me on &lt;a href=&quot;https://twitter.com/kalabro&quot;&gt;Twitter&lt;/a&gt;, &lt;a href=&quot;https://hachyderm.io/@kalabro&quot;&gt;Mastodon&lt;/a&gt;, or &lt;a href=&quot;https://www.linkedin.com/in/kalabro/&quot;&gt;LinkedIn&lt;/a&gt; to stay updated on my next adventures.&lt;/p&gt;</content:encoded></item><item><title>Flutter guide for React developers</title><link>https://kalabro.tech/flutter-for-react-developers/</link><guid isPermaLink="true">https://kalabro.tech/flutter-for-react-developers/</guid><description>In this guide I map common Flutter concepts to their equivalents in web development. If you are a React developer interested in Flutter, it will help you find your fit on the new territory.</description><pubDate>Sun, 22 Jan 2023 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Flutter is a popular framework for building cross-platform mobile apps. I had a chance to play with Flutter and found quite a few similarities with React. In this guide, I map common Flutter concepts to their equivalents in web development. If you are a React developer interested in Flutter, it will help you find your fit in the new territory.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;This article doesn’t question whether you should use Flutter, React Native, PWA or a native app approach. There are good use cases for each of them. Today we will focus on Flutter for mobile app development. Let’s dive in!&lt;/p&gt;
&lt;h2&gt;Table Of Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#vs-code--vs-code&quot;&gt;VS Code → VS Code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#chrome-dev-tools--flutter-dev-tools&quot;&gt;Chrome Dev Tools → Flutter Dev tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#typescript--dart&quot;&gt;TypeScript → Dart&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#eslint--dart-lint&quot;&gt;ESlint → Dart lint&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#div--widget&quot;&gt;div → Widget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#css--widget&quot;&gt;CSS → Widget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#accessibility--widget-again&quot;&gt;Accessibility → Widget (again!)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#mui--material-components-mdc&quot;&gt;@mui → Material Components (MDC)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#render--build&quot;&gt;Render → Build&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#state--state&quot;&gt;State → State&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#npm--pubdev&quot;&gt;npm → pub.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#redux--react-query--riverpod&quot;&gt;Redux + React Query → Riverpod&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#react-router--go-router&quot;&gt;React Router → Go Router&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#backend--firebase&quot;&gt;Backend → Firebase&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#react-testing-library--flutter_test&quot;&gt;React Testing Library → flutter_test&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#react-docs--docsflutterdev&quot;&gt;React Docs → docs.flutter.dev&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#whats-next&quot;&gt;What’s next&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;VS Code → VS Code&lt;/h2&gt;
&lt;p&gt;Most Flutter developers write code with the same tools as web developers.
&lt;a href=&quot;https://docs.flutter.dev/development/tools/vs-code&quot;&gt;VS Code with Flutter extension&lt;/a&gt; is the most popular option.&lt;/p&gt;
&lt;p&gt;Android Studio has first-class Flutter support if you are more comfortable with IntelliJ IDEA. I picked this option and was quite happy with it.&lt;/p&gt;
&lt;p&gt;Like any other mobile dev setup, it takes time to prepare everything for cross-platform development. To help developers troubleshoot their local setup, Flutter comes with a handy utility &lt;code&gt;flutter doctor&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/flutter-doctor.C7G1YcoR_7L5Po.webp&quot; alt=&quot;Flutter Doctor utility&quot; loading=&quot;lazy&quot; width=&quot;1064&quot; height=&quot;650&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with the local development environment:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Carefully follow &lt;a href=&quot;https://docs.flutter.dev/get-started/install&quot;&gt;official installation instructions&lt;/a&gt;. Don’t skip steps!&lt;/li&gt;
&lt;li&gt;If you are not ready to install Flutter locally, you can also use &lt;a href=&quot;https://dartpad.dev/&quot;&gt;DartPad&lt;/a&gt;, an online Dart &amp;amp; Flutter playground&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I personally found the initial installation process more straightforward than for React Native.&lt;/p&gt;
&lt;h2&gt;Chrome Dev Tools → Flutter Dev tools&lt;/h2&gt;
&lt;p&gt;It’s hard to imagine web development without the powerful dev tools we have in our browsers.&lt;/p&gt;
&lt;p&gt;Surprisingly, Flutter isn’t far behind. I started using Flutter widget inspector from day 1 to debug my widgets styling issues. Just like in Chrome, Flutter Inspector has multiple tabs, from Networking to Performance. It was interesting to explore my app from different angles there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/slow-animations.B4Y5Jl2v_BoHs.webp&quot; alt=&quot;Debugging slow animations with Flutter Dev Tools&quot; loading=&quot;lazy&quot; width=&quot;1057&quot; height=&quot;800&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Last, you can debug Flutter code from your IDE using breakpoints. For some reason, I still prefer &lt;code&gt;console.log()&lt;/code&gt; in JavaScript!&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Flutter Dev tools:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.flutter.dev/development/tools/devtools/overview&quot;&gt;DevTools&lt;/a&gt; - official documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;TypeScript → Dart&lt;/h2&gt;
&lt;p&gt;Flutter uses the Dart programming language. Dart is similar to JavaScript but with types and some nice syntax sugar on top of it.
For example, Dart has an async functionality, but &lt;code&gt;Promises&lt;/code&gt; are called &lt;code&gt;Futures&lt;/code&gt; there.&lt;/p&gt;
&lt;p&gt;If we need an array in the JavaScript sense, in Dart, we use a List:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;var&lt;/span&gt;&lt;span&gt; nav &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; [&lt;/span&gt;&lt;span&gt;&apos;Home&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;Furniture&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;&apos;Plants&apos;&lt;/span&gt;&lt;span&gt;, &lt;/span&gt;&lt;span&gt;if&lt;/span&gt;&lt;span&gt; (promoActive) &lt;/span&gt;&lt;span&gt;&apos;Outlet&apos;&lt;/span&gt;&lt;span&gt;];&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The example above is a List of Strings. The last item is only added if &lt;code&gt;promoActive&lt;/code&gt; is true. Neat!&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Dart:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://dart.dev/guides/language/coming-from/js-to-dart&quot;&gt;Learning Dart as a JavaScript developer&lt;/a&gt; - half an hour, and you are ready to go!&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My experience with Dart was only positive so far. You don’t need to spend time configuring TypeScript or Webpack. With Dart, everything is built-in and ready to use.&lt;/p&gt;
&lt;h2&gt;ESlint → Dart lint&lt;/h2&gt;
&lt;p&gt;Dart &amp;amp; Flutter have built-in code analysing and formatting tools. It makes it easy to learn framework best practices. I was happy with the default linters setup, but it’s possible to customise it too.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with linters:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;When you start a new Flutter project, the linters should be preconfigured for you&lt;/li&gt;
&lt;li&gt;For customisation check &lt;a href=&quot;https://dart.dev/tools/linter-rules&quot;&gt;Dart linter rules&lt;/a&gt; and &lt;a href=&quot;https://pub.dev/packages/flutter_lints&quot;&gt;Flutter linter rules&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;div → Widget&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Everything in Flutter is a widget.&lt;/strong&gt;
If you compare them to HTML tags, Flutter widgets are usually much more specialised.&lt;/p&gt;
&lt;p&gt;For example, “to center a div” in Flutter, you use the specialised Center widget:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Center&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; Text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;I’m centered!&quot;&lt;/span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It takes time to get familiar with all built-in Flutter widgets. I don’t think I explored even half of them.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Widgets:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Scan through &lt;a href=&quot;https://docs.flutter.dev/development/ui/widgets&quot;&gt;the Widget catalog&lt;/a&gt; to learn what’s available&lt;/li&gt;
&lt;li&gt;Regularly watch short &lt;a href=&quot;https://docs.flutter.dev/development/ui/widgets#widget-of-the-week&quot;&gt;“Widget of the Week”&lt;/a&gt; videos from the official Flutter team.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I didn’t quite enjoy Flutter’s way of passing children as properties. Personally, I find JSX syntax easier to work with.&lt;/p&gt;
&lt;h2&gt;CSS → Widget&lt;/h2&gt;
&lt;p&gt;Everything is a widget, remember?
Flutter doesn’t support CSS. Instead, all styling is handled by widgets and their properties.&lt;/p&gt;
&lt;p&gt;Let’s say I want to add some padding to my Center widget. In Flutter, I need to wrap my widget with another one, specialised in padding, and pass my original widget via child property:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Padding&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   padding&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; EdgeInsets&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;16&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;   child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Center&lt;/span&gt;&lt;span&gt;(child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;I’m centered!&quot;&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;EdgeInsets.all(16)&lt;/strong&gt; means &lt;strong&gt;padding: 16px&lt;/strong&gt;.
Flutter operates in logical pixels and takes care of translating our values into physical pixels for each device and screen type.&lt;/p&gt;
&lt;p&gt;Now let’s add a black border with border radius around the previous widget:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;DecoratedBox&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      decoration&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; BoxDecoration&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        border&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Border&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          color&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Colors&lt;/span&gt;&lt;span&gt;.black,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          width&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 1&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        ),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        borderRadius&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; BorderRadius&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;circular&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;12&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      ),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; const&lt;/span&gt;&lt;span&gt; Padding&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        padding&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; EdgeInsets&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;all&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;16&lt;/span&gt;&lt;span&gt;),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Center&lt;/span&gt;&lt;span&gt;(child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;I’m centered!&quot;&lt;/span&gt;&lt;span&gt;)),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      ),&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In Flutter, all properties are granularly typed, and for each aspect of styling, you need to create a value of the appropriate type. Because of that, the resulting code is much more verbose.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Widgets:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Scan through &lt;a href=&quot;https://docs.flutter.dev/development/ui/widgets&quot;&gt;the Widget catalog&lt;/a&gt; to learn what’s available&lt;/li&gt;
&lt;li&gt;Regularly watch short &lt;a href=&quot;https://docs.flutter.dev/development/ui/widgets#widget-of-the-week&quot;&gt;“Widget of the Week”&lt;/a&gt; videos from the official Flutter team.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=GXIJJkq_H8g&amp;amp;feature=youtu.be&quot;&gt;How to choose which Flutter Animation Widget is right for you?&lt;/a&gt; - great overview of Flutter animations.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Accessibility → Widget (again!)&lt;/h2&gt;
&lt;p&gt;Accessibly is a first-class citizen in Flutter. For example, images and icons have the &lt;code&gt;semanticLabel&lt;/code&gt; property for screen readers. For more advanced cases, there is a special widget &lt;code&gt;Semantics&lt;/code&gt; which has more than 50 properties to describe the meaning of your widgets.&lt;/p&gt;
&lt;p&gt;The Flutter team made it easy for developers to debug accessibility by providing the &lt;code&gt;showSemanticsDebugger&lt;/code&gt; property. It replaces the original widgets with the corresponding semantic labels that the screen readers would read:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/accessibility.CNxXNLpm_Z1e4R89.webp&quot; alt=&quot;Accessibility&quot; loading=&quot;lazy&quot; width=&quot;1093&quot; height=&quot;822&quot; /&gt;&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with accessibility:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.flutter.dev/development/ui/widgets/accessibility&quot;&gt;Accessibility widgets&lt;/a&gt; - official documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;@mui → Material Components (MDC)&lt;/h2&gt;
&lt;p&gt;@mui is Material Design implementation for React. When using @mui as your component library, you first create a top-level theme, expose it via React Context, and then enjoy consistent styling across all your components.&lt;/p&gt;
&lt;p&gt;Below is how you would print a heading with @mui:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;&amp;lt;&lt;/span&gt;&lt;span&gt;Typography&lt;/span&gt;&lt;span&gt; variant&lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt;&quot;h4&quot;&lt;/span&gt;&lt;span&gt;&amp;gt;Heading 4&amp;lt;/&lt;/span&gt;&lt;span&gt;Typography&lt;/span&gt;&lt;span&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Flutter comes with Material Components (MDC) out of the box. Technically you can opt-out and go your own way, but I haven’t explored that route yet.&lt;/p&gt;
&lt;p&gt;Similar to React implementation, various aspects of the theme are first configured at the top level of the app and then reused in individual widgets like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;Text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &apos;Heading 4&apos;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    style&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Theme&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;span&gt;(context).textTheme.headline4,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Material:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.flutter.dev/codelabs&quot;&gt;MDC codelabs&lt;/a&gt; (small practical lessons) from the official Flutter team&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://m3.material.io/theme-builder#/custom&quot;&gt;Material Theme Builder&lt;/a&gt; supports export in Flutter&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/flutter/material-3-for-flutter-d417a8a65564&quot;&gt;Material 3 for Flutter&lt;/a&gt; by Eilidh Southren&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://rydmike.com/blog_theming_guide&quot;&gt;Flutter Theming Guide&lt;/a&gt; by Mike Rydstrom&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;/_astro/material-builder.CM6_vU7l_Z23VvTl.webp&quot; alt=&quot;Material Theme Builder supports export in Flutter&quot; loading=&quot;lazy&quot; width=&quot;3022&quot; height=&quot;1604&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Be prepared for a steep learning curve: hundreds of widgets and properties, sophisticated Material theme configuration, and of course, mobile device specifics that don’t exist on the web.&lt;/p&gt;
&lt;h2&gt;Render → Build&lt;/h2&gt;
&lt;p&gt;Flutter widgets are classes that must implement the build method. It’s similar to the render method in React class components.&lt;/p&gt;
&lt;p&gt;Let’s implement the build method for our “centered div” example from the beginning of this guide:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;class&lt;/span&gt;&lt;span&gt; CenteredText&lt;/span&gt;&lt;span&gt; extends&lt;/span&gt;&lt;span&gt; StatelessWidget&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  const&lt;/span&gt;&lt;span&gt; CenteredText&lt;/span&gt;&lt;span&gt;({super.key, &lt;/span&gt;&lt;span&gt;required&lt;/span&gt;&lt;span&gt; this.text});&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // Props are class members in Flutter.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  final&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt; text;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  // Widget must implement the build method.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  @override&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  Widget&lt;/span&gt;&lt;span&gt; build&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;BuildContext&lt;/span&gt;&lt;span&gt; context) {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    return&lt;/span&gt;&lt;span&gt; Center&lt;/span&gt;&lt;span&gt;(child&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Text&lt;/span&gt;&lt;span&gt;(text));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you had a negative experience with class components in React, put it aside for a moment. Flutter is based on Dart, and its class implementation is much more robust and well-thought than in JavaScript.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with building custom widgets:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=wE7khGHVkYY&amp;amp;feature=youtu.be&quot;&gt;How to Create Stateless Widgets&lt;/a&gt; from Flutter in Focus video series&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;State → State&lt;/h2&gt;
&lt;p&gt;Quote from Flutter documentation:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Flutter widgets are built using a modern framework &lt;strong&gt;that takes inspiration from React&lt;/strong&gt;. The central idea is that you build your UI out of widgets. Widgets describe what their view should look like given their current configuration and state. When a widget’s state changes, the widget rebuilds its description, which the framework diffs against the previous description in order to determine the minimal changes needed in the underlying render tree to transition from one state to the next.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The actual implementation of stateful widgets differs from how we build stateful components in React. Instead of adding one line of code with the &lt;code&gt;useState&lt;/code&gt; hook, you need to create two (!) separate objects: one for the stateful widget and another for its state. Wonder why? Check out the links below for details.&lt;/p&gt;
&lt;p&gt;Luckily, both VS Code and Android Studio have shortcuts to scaffold Flutter widgets. In practice, I can create Flutter widgets as fast as I create new React components.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with stateful widgets:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=AqCMFXEmf3w&amp;amp;feature=youtu.be&quot;&gt;How Stateful Widgets Are Used Best&lt;/a&gt; from Flutter in Focus video series&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://iiro.dev/set-state/&quot;&gt;Flutter’s setState() might not be what you think it is&lt;/a&gt; - Flutter is inspired by React, but under the hood, it works differently.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;npm → pub.dev&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://pub.dev/&quot;&gt;pub.dev&lt;/a&gt; is the official package repository for Dart and Flutter apps. I found it very clean and developer-friendly.
Pub.dev promotes high-quality packages via the &lt;a href=&quot;https://docs.flutter.dev/development/packages-and-plugins/favorites&quot;&gt;Flutter Favorite&lt;/a&gt; program and &lt;a href=&quot;https://www.youtube.com/playlist?list=PLjxrf2q8roU1quF6ny8oFHJ2gBdrYN_AK&quot;&gt;Package of the Week&lt;/a&gt; YouTube show.&lt;/p&gt;
&lt;p&gt;There are two files in the Flutter app directory that are related to pub.dev: pubspec.yaml and pubspec.lock (equivalents of package.json and package.lock).&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with pub.dev:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Head to &lt;a href=&quot;https://pub.dev/&quot;&gt;pub.dev&lt;/a&gt; and explore the packages&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Redux + React Query → Riverpod&lt;/h2&gt;
&lt;p&gt;Like with React, the Flutter ecosystem has born a dozen competing state managers.&lt;/p&gt;
&lt;a href=&quot;https://twitter.com/RydMike/status/1578462043593535488&quot;&gt;&lt;p&gt;&lt;img src=&quot;/_astro/top30-state-managers.BJNKDwQ__Z23OX6.webp&quot; alt=&quot;TOP 30 Flutter State packages by Mike Rydstrom&quot; loading=&quot;lazy&quot; width=&quot;3840&quot; height=&quot;2160&quot; /&gt;&lt;/p&gt;&lt;/a&gt;
&lt;p&gt;Some seasoned Flutter developers lean towards Riverpod (#5 in the chart above) when building real, complex applications. I trust their choice.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Riverpod:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codewithandrea.com/articles/flutter-state-management-riverpod/&quot;&gt;Flutter Riverpod 2.0: The Ultimate Guide&lt;/a&gt; by Andrea Bizzotto&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/bizz84/starter_architecture_flutter_firebase&quot;&gt;Time Tracking app with Flutter &amp;amp; Firebase&lt;/a&gt; - an example app by Andrea Bizzotto&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;React Router → Go Router&lt;/h2&gt;
&lt;p&gt;Mobile app navigation is quite different from the web. The built-in Flutter Navigation API is so complex that the Flutter team decided to build an official third-party package with a simpler API: Go Router.&lt;/p&gt;
&lt;p&gt;Similar to React Router, you declare your routes (and their sub-routes) and map them to the screens of your app.&lt;/p&gt;
&lt;p&gt;Get started with Go Router:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codewithandrea.com/articles/flutter-navigation-gorouter-go-vs-push/&quot;&gt;Flutter Navigation with GoRouter: Go vs Push&lt;/a&gt; by Andrea Bizzotto&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.flutter.dev/development/ui/navigation/deep-linking&quot;&gt;Deep linking&lt;/a&gt; - official Flutter documentation&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Backend → Firebase&lt;/h2&gt;
&lt;p&gt;Mobile/desktop apps are rarely static landing pages. Almost always they require some backend for authentication, data synchronisation, analytics and more. Yet most apps will never become popular, and developers don’t want to spend months building sophisticated backends. That’s why Firebase is so popular in mobile dev, Flutter included. It offers a set of APIs for all common features you may need as a mobile developer, all free until a certain threshold.&lt;/p&gt;
&lt;p&gt;Google supports both Flutter and Firebase so you can expect an excellent integration between the two. If you don’t want to store your data with Google, several open source alternatives provide similar developer experience.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started with Firebase:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://firebase.google.com/docs/flutter/setup&quot;&gt;Add Firebase to your Flutter app&lt;/a&gt; - official documentation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://dartpad.dev/?id=d57c6c898dabb8c6fb41018588b8cf73&quot;&gt;One-file Firebase chat app&lt;/a&gt; - official DartPad example&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=SXmYUalHyYk&amp;amp;feature=youtu.be&quot;&gt;I tried 5 Firebase alternatives&lt;/a&gt; - video by Jeff Delaney&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;React Testing Library → flutter_test&lt;/h2&gt;
&lt;p&gt;A robust testing ecosystem is another sign of a serious approach to the framework quality.&lt;/p&gt;
&lt;p&gt;Developers can test Flutter apps with the following types of tests:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Unit&lt;/strong&gt; — verifies the behaviour of a method or class&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Widget&lt;/strong&gt; — verifies the behaviour of Flutter widgets without running the app itself&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Golden&lt;/strong&gt; — verifies visual output of Flutter widgets without running the app itself&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UI integration&lt;/strong&gt; — verifies the full app UI works by running the app on a device (some network services can be mocked)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;End-to-end&lt;/strong&gt; — same as above, but without any mocking&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Example of a widget test:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;testWidgets&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Testing MyWidget&apos;&lt;/span&gt;&lt;span&gt;, (&lt;/span&gt;&lt;span&gt;WidgetTester&lt;/span&gt;&lt;span&gt; tester) &lt;/span&gt;&lt;span&gt;async&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  await&lt;/span&gt;&lt;span&gt; tester.&lt;/span&gt;&lt;span&gt;pumpWidget&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;MyWidget&lt;/span&gt;&lt;span&gt;());&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  await&lt;/span&gt;&lt;span&gt; tester.&lt;/span&gt;&lt;span&gt;tap&lt;/span&gt;&lt;span&gt;(find.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Save&apos;&lt;/span&gt;&lt;span&gt;));&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  await&lt;/span&gt;&lt;span&gt; tester.&lt;/span&gt;&lt;span&gt;pump&lt;/span&gt;&lt;span&gt;();&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  expect&lt;/span&gt;&lt;span&gt;(find.&lt;/span&gt;&lt;span&gt;text&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&apos;Success&apos;&lt;/span&gt;&lt;span&gt;), findsOneWidget);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;WidgetTester&lt;/code&gt; provides an API to manipulate widgets programmatically; for example, &lt;code&gt;tester.tap(find.text(&apos;Save&apos;))&lt;/code&gt; will simulate tapping on the “Save” button.&lt;/p&gt;
&lt;p&gt;It was pretty unexpected for me to find &lt;a href=&quot;https://api.flutter.dev/flutter/flutter_test/matchesGoldenFile.html&quot;&gt;visual regression testing tools&lt;/a&gt; (Golden image tests) in the standard testing library. In addition to the standard tools, there are several external packages that help to further advance Flutter testing.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;💡&lt;/span&gt; Get started:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.flutter.dev/testing&quot;&gt;Testing Flutter apps&lt;/a&gt; - official documentation&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://pub.dev/packages/golden_toolkit&quot;&gt;Golden Toolkit&lt;/a&gt; - UI regression tests on top of Flutter’s Golden test functionality&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;React Docs → docs.flutter.dev&lt;/h2&gt;
&lt;p&gt;Official Flutter and Dart documentation are exceptionally good. Apart from detailed written documentation, the Flutter team provides interactive examples, videos, and codelabs.&lt;/p&gt;
&lt;p&gt;You may not need any paid external resources &lt;em&gt;at all&lt;/em&gt; to become a Flutter dev.&lt;/p&gt;
&lt;h2&gt;What’s next&lt;/h2&gt;
&lt;p&gt;I hope this guide will help you navigate the Flutter world as a React developer. If you are at the very beginning, start with &lt;a href=&quot;https://docs.flutter.dev/codelabs&quot;&gt;“Your first Flutter app” codelab&lt;/a&gt;. Feel free to bookmark this guide and return to it as you progress through your journey!&lt;/p&gt;</content:encoded></item><item><title>Where to find a mentor</title><link>https://kalabro.tech/where-to-find-mentor-2023/</link><guid isPermaLink="true">https://kalabro.tech/where-to-find-mentor-2023/</guid><description>Last year I had several mentorship experiences, and the results impressed me. In this article, I reflect on what worked for me and suggest how to get started.</description><pubDate>Sun, 15 Jan 2023 11:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;Last year I had several mentorship/coaching experiences, and the results impressed me. In this article, I reflect on what worked for me and suggest how to get started.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The most popular question I received last year was “Where to find a mentor”. I used to respond with &lt;a href=&quot;https://blog.pragmaticengineer.com/developers-mentoring-other-developers/#places-to-find-mentors&quot;&gt;this blog post from Gergely Orosz&lt;/a&gt; with the list of engineering mentorship resources.&lt;/p&gt;
&lt;p&gt;Soon enough, I realised that by asking “Where to find a mentor”, people actually want to know if they need a mentor at all and how to get started.&lt;/p&gt;
&lt;p&gt;First of all, if it came to your mind that you need a mentor, then you probably need one. I suggest starting with the following steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose one question&lt;/li&gt;
&lt;li&gt;Answer your question yourself&lt;/li&gt;
&lt;li&gt;Scan your existing contact list for potential mentors&lt;/li&gt;
&lt;li&gt;Pick any available mentor from any mentorship service&lt;/li&gt;
&lt;li&gt;Don’t delay your first mentorship session&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Let’s go through the steps in detail.&lt;/p&gt;
&lt;h2&gt;Choose one question&lt;/h2&gt;
&lt;p&gt;In a nutshell, mentorship is about asking and answering questions.&lt;/p&gt;
&lt;p&gt;Preparing your questions in advance is good practice. However, I suggest going further and reducing the list of questions to just one.&lt;/p&gt;
&lt;p&gt;Your first session will be about getting to know each other and understanding the context. Having more than one problem can feel overwhelming for both parties.&lt;/p&gt;
&lt;p&gt;Of course, once you’ve established a good relationship with your mentor, you can “break the rules” if they are limiting. I personally stick to one question rule and finish the session earlier if I’m clear on the next steps.&lt;/p&gt;
&lt;h2&gt;Answer your question yourself&lt;/h2&gt;
&lt;p&gt;After choosing a question, I try to answer it myself. This self-coaching practice helps me validate my question.&lt;/p&gt;
&lt;p&gt;Let me give you an example. Imagine a person going to a pharmacy and saying, “I don’t feel well, give me some pills”. The pharmacist can’t feel your body for you, so they will ask lots of questions until they can help. If the person does a bit of introspection to identify what exactly hurts, they will come up with a much clearer request.&lt;/p&gt;
&lt;p&gt;Same with mentorship. The only person who knows all the context of your problem is you. Explore this context on your own so it’s fresh when the mentor asks questions like “What have you already tried?” or “What piece of information do you miss to make a decision?”&lt;/p&gt;
&lt;p&gt;Don’t worry if you can’t answer your question yet. It’s important that you try.&lt;/p&gt;
&lt;p&gt;The opposite can happen, too. You can find an obvious solution to your problem. In this case, you may want a mentor’s help to verify your solution and go through the next steps together.&lt;/p&gt;
&lt;h2&gt;Scan your existing contact list for potential mentors&lt;/h2&gt;
&lt;p&gt;The most expensive (and rewarding) part of mentorship is building a trusting relationship. You may already have a few great mentors in your immediate network.&lt;/p&gt;
&lt;p&gt;You don’t have to call it “mentorship” with them. This word can be interpreted as a serious commitment. Casual “I need your advice” works well for me.&lt;/p&gt;
&lt;h2&gt;Pick any available mentor from any mentorship service&lt;/h2&gt;
&lt;p&gt;Scan the services from &lt;a href=&quot;https://blog.pragmaticengineer.com/developers-mentoring-other-developers/#places-to-find-mentors&quot;&gt;Gergely Orosz’s list&lt;/a&gt; for mentors who are 3-5 years ahead of you career-wise. Book a session with someone who caught your attention and who has available time slots in the near future.&lt;/p&gt;
&lt;p&gt;One can argue that we should carefully review the mentor’s experience, reviews, ratings, social media, etc. In reality, people either match or don’t match, and you can’t predict it before meeting for your first session.&lt;/p&gt;
&lt;p&gt;I wouldn’t worry too much about wasting time with the “wrong” mentor. I’ve asked the same question to several different mentors and always learned something new.&lt;/p&gt;
&lt;h2&gt;Don’t delay your first mentorship session&lt;/h2&gt;
&lt;p&gt;Requesting your first mentorship session takes courage! Unfortunately, it took me a while to find that courage. I was using various excuses to delay taking action.&lt;/p&gt;
&lt;p&gt;&lt;img loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;1000&quot; src=&quot;/_astro/mentor-eye.CuZt6owP_ZVSsj.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Excuse 1: “I can take course A/read book B. New knowledge will resolve my questions.”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Books, tutorials, and courses offer general knowledge, while the mentorship experience gives us deeper, personalized understanding. Mentorship works because you, as a mentee, get all the attention and support from the other person you respect and trust. In some situations it’s exactly what we need to take the next step.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Excuse 2: “My problems are not new/not interesting. I will waste someone’s time.”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;As an aspiring mentor, I can confirm that mentors don’t look for new problems; they have enough of them at their jobs. As a mentor, I am excited to help someone find their way through a problem. If it’s something I faced myself in the past, then it is easier for me to guide the other person through it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Excuse 3: “I don’t want to spend money on something that doesn’t guarantee result”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I have heard about expensive coaches who sell and upsell every second they talk to you. I overcame this fear by choosing from free options. I also figured out that most experts are very approachable when you DM them with your sincere ask for advice. Because there is no financial commitment, they are much more relaxed and honest.
In the case of paid options, I will first book a short intro session to see if I’m comfortable with my choice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Excuse 4: “They don’t know my situation and won’t be able to help”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;It turns out that a mentor needs to know “just enough” to help me find the solution. As we discussed earlier, the answer may already be there, and all I need is trust and support. Kind words don’t cost us anything, but unfortunately, there is a huge lack of unconditional support in the world.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Excuse 5: “Mentorship is only for junior developers”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I think it’s time to clarify the terms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Teaching&lt;/strong&gt; - explaining in a very detailed way how to do things.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mentorship&lt;/strong&gt; - answering questions that require expertise/experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Coaching&lt;/strong&gt; - asking questions that help the other person to solve their problems themselves.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The word “mentorship” is often used as an umbrella term for all three activities. Good mentors know when to give a very specific piece of information (teaching), when to share an example from their experience (classic mentorship), and when to ask an open question that welcomes a mentee to explore their problem deeper (coaching).&lt;/p&gt;
&lt;p&gt;When I look at these definitions, I realise junior developers need more teaching: clear guidance and concrete steps. As they gain more experience, they require less teaching and more coaching, especially if they want to advance past certain career ladder levels.&lt;/p&gt;
&lt;h2&gt;Next steps&lt;/h2&gt;
&lt;p&gt;This article focuses on a formal mentorship that is supposed to last for a certain period to bring visible results.&lt;/p&gt;
&lt;p&gt;After talking to several experienced mentors, I learned they had seen most of their mentees only once. It is totally fine to have occasional one-off sessions when needed. On the other hand, it takes time to build a trusting relationship and to explore challenging topics deeply. If you have a long-term professional goal, I welcome you to consider regular mentorship sessions.&lt;/p&gt;
&lt;p&gt;Another important aspect not to forget is communication with your peers. From “The Mentorship Diamond” article:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You should have more contact with your peers than with mentors or mentees&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At some point, you will become a mentor yourself. Being a mentor helps us grow in so many ways. I recently started as a mentor on &lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;the ADPList platform&lt;/a&gt;, and I will write about my experience soon. Stay tuned!&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://adplist.org/mentors/kate-marshalkina&quot;&gt;&lt;img alt=&quot;ADPList mentor banner&quot; loading=&quot;lazy&quot; width=&quot;1280&quot; height=&quot;800&quot; src=&quot;/_astro/adplist-kalabro.BuJ_NJlm_2tTeIf.webp&quot; /&gt;&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>“Learning Domain-Driven Design” - the software architecture 🐒 book that makes sense</title><link>https://kalabro.tech/learning-domain-driven-design-book/</link><guid isPermaLink="true">https://kalabro.tech/learning-domain-driven-design-book/</guid><description>My review of “Learning Domain-Driven Design” book about DDD and how it maps to the common software architecture patterns.</description><pubDate>Sat, 07 Jan 2023 09:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;“Selling is hard, and personally, I hate selling. That said, if you think about it, designing software is selling. We are selling our ideas to the team, to management, or to customers.”&lt;br /&gt;
Vlad Knononov, &lt;a href=&quot;https://a.co/d/ez4dQLr&quot;&gt;“Learning Domain-Driven Design”&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It’s 2023, and ChatGPT will probably write a summary of any book much better than I can. Finally, being personal and opinionated becomes an advantage!&lt;/p&gt;
&lt;h2&gt;My story&lt;/h2&gt;
&lt;p&gt;When a while ago I was preparing an onboarding plan for a new team member, I realised how many project-specific concepts, terms, and acronyms I had in my head. I decided to start a glossary and asked the new team member to research the meanings of the listed terms and acronyms by reading documentation, talking to other team members, or asking the client directly. Without knowing it, I started creating a “ubiquitous language”, a key element of the Domain-Driven Design approach.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;First takeaway:&lt;/strong&gt; do what makes sense. You’ll probably figure out later on that someone invented a methodology around that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Many years later, I was lucky to catch Vlad Khononov at the GSAS conference in Barcelona and asked him how to become a better programmer. It’s a surprisingly difficult question, even for experienced developers. Take a moment to think of your own personal and opinionated answer.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Second takeaway:&lt;/strong&gt; ask people questions that you care about and be open to unexpected answers.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Vlad advised starting with “A Philosophy of Software Design”, my all-time favourite among software engineering books. As I had already read it, Vlad had to come up with another answer, and coincidentally, it was his own book “Learning Domain-Driven Design”.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Third takeaway:&lt;/strong&gt; read “A Philosophy of Software Design” by John Ousterhout if you haven’t yet&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Back then, I had zero knowledge of DDD. I was aware of a few popular architecture patterns, and that’s it. As a Full Stack web developer, my day-to-day job was glueing existing services and frameworks together rather than drawing sophisticated UML diagrams. Yet I was intrigued by conspiracy around software architecture topics. Take a look at this famous definition for example:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“Architecture is about the important stuff. Whatever that is.”&lt;br /&gt;
Ralph Johnson&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I read “Clean Architecture” by Uncle Bob several years ago, I didn’t quite understand the book’s core ideas behind all that SOLID jargon, primarily because I couldn’t map the proposed “clean” solutions to my day-to-day experiences. Three years later, I finally started building that understanding, thanks to the “Learning Domain-Driven Design” book.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Fourth takeaway:&lt;/strong&gt; keep exploring the topic that interests you until it clicks. It will eventually.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;How I understand Domain-Driven Design today&lt;/h2&gt;
&lt;p&gt;Quoting Vlad, “Domain-Driven Design is about letting your business &lt;em&gt;domain&lt;/em&gt; &lt;em&gt;drive&lt;/em&gt; your &lt;em&gt;design&lt;/em&gt; decisions.”&lt;/p&gt;
&lt;p&gt;In the era of copy-paste-driven design, DDD suggests pausing and thinking deeply about the problem we attempt to solve with our favourite tools and patterns. It encourages us to build a shared understanding of that problem by speaking to business and, more importantly, by speaking the same (ubiquitous) language with them.&lt;/p&gt;
&lt;p&gt;On a high level, DDD is about answering questions What? Why? How?&lt;/p&gt;
&lt;p&gt;As people on all levels tend to jump straight to “How?” DDD offers some tools to help answer these questions in the correct order and, as a result, to build an appropriate software solution. Most DDD tools just make sense, similar to my glossary example at the beginning of this article.&lt;/p&gt;
&lt;h2&gt;EDA, DIP, OHS, ACL, ETL, CQRS… What?&lt;/h2&gt;
&lt;p&gt;It gets interesting when DDD meets the reality of modern software development. 20 years ago, when Eric Evans first introduced DDD, I was writing my first CSS and HTML code. The amount of tech acronyms has only grown since. In “Learning Domain-Driven Design”, Vlad walks us through all the common patterns and principles in a way that makes sense.&lt;/p&gt;
&lt;p&gt;For example, I finally understood what Hexagonal architecture is and when to use it. On top of that, I’ve got an excellent overview of analytical data platforms. My favourite part of the book is Chapter 14: Microservices. I won’t attempt to summarise it here. Instead, I encourage you to read the book yourself if you are interested in a practical intro to the most common software architecture patterns such as Microservices, Event Driven Architecture, CQRS and more.&lt;/p&gt;
&lt;p&gt;As a Full Stack developer, I found this overview very handy. I may not need all described patterns immediately, but I need to know they exist.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;a textbook with handwritten notes about DDD&quot; loading=&quot;lazy&quot; width=&quot;1000&quot; height=&quot;1190&quot; src=&quot;/_astro/ddd-notes.CIW8atKB_19SVlY.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;I must warn a fellow reader that a quick flip-through will not be enough if you are relatively new to software architecture. I had to take notes and re-read certain parts of the book to understand certain concepts.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Fifth takeaway:&lt;/strong&gt; prepare for thorough reading to get the maximum from this book.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Design heuristics&lt;/h2&gt;
&lt;p&gt;After explaining the foundations for DDD, the book offers a good amount of advice on how to apply DDD in real life. In many cases, you can derive the appropriate implementation patterns after analysis of the business domain. If you picked the wrong implementation, no worries. The book suggests ways to migrate from one implementation pattern to another.&lt;/p&gt;
&lt;p&gt;Another insightful heuristic is around testing strategies. There are three popular approaches: testing pyramid, testing diamond, and inverted testing pyramid. Vlad argues that there is no one right testing strategy and explains when to use which. I was able to prove it myself when I looked at my tests. I take testing seriously, but I rarely write unit tests in my project and instead focus on end-to-end and integration tests. It reflects the fact that in web, we often work with simpler architecture patterns (e.g. “Transaction script” and “Active record” from the &lt;a href=&quot;https://martinfowler.com/eaaCatalog/index.html&quot;&gt;“Patterns of Enterprise Application Architecture” catalog&lt;/a&gt;) because they are more appropriate for the task.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Sixth takeaway:&lt;/strong&gt; DDD tackles software complexity, but it also tackles software simplicity, that is, how to not over-engineer our solutions just because we are excited by specific design patterns or technologies.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you are an individual contributor without enough power to install DDD on a company level, the book outlines some baby steps you can take to shift the whole company towards DDD.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Seventh takeaway:&lt;/strong&gt; you don’t need a software architect title to start using DDD in your daily work&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The book wraps up nicely with a case study of applying DDD in real life. The author shares some of the mistakes he has made while learning DDD and how his understanding of DDD was evolving throughout the years.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;“Learning Domain-Driven Design” explains the ideas behind DDD and maps them to popular design and implementation patterns. As a bonus, you get introduced to Microservices, Event-Driven Architecture, Data Mesh, and more.&lt;/p&gt;
&lt;p&gt;Some chapters are harder to read without the appropriate backend development experience. I treated it as a challenge and did my best to understand the CQRS pattern without ever seeing it in action. It is an opportunity for future writers to translate DDD ideas into examples tailored to specific audiences, e.g. Javascript developers. Back to the quote from the beginning of this article, we need to sell all these good ideas to developers who are very busy with tons of other stuff to learn.&lt;/p&gt;
&lt;p&gt;There is a lot of work to be done in order to make software design best practices easy to understand and apply in practice. Many of the problems we face today have actually been discussed and solved in the past, but this wisdom has been lost in the back corners of the internet. Vlad Khononov’s book “Learning Domain-Driven Design” brings this wisdom back to us and explains it in a way that makes sense.&lt;/p&gt;</content:encoded></item><item><title>My approach to the command line</title><link>https://kalabro.tech/no-geek-command-line/</link><guid isPermaLink="true">https://kalabro.tech/no-geek-command-line/</guid><description>Terminals can be very cool and fun! But you don&apos;t have to be a command line geek to be a successful developer.</description><pubDate>Mon, 10 May 2021 15:30:00 GMT</pubDate><content:encoded>&lt;p&gt;There is an idea that every developer should master tons of sophisticated tools and keyboard shortcuts to be truly professional and efficient.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Terminal window with man awk command typed&quot; loading=&quot;lazy&quot; width=&quot;1470&quot; height=&quot;844&quot; src=&quot;/_astro/no-geek-command-line.Cr28QYFX_Z2bAvBQ.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;My experience doesn’t confirm it. As an example, let me show you my command line setup. I’m not a sysadmin, but as a full stack developer with 10+ years of experience I use the terminal on a daily basis yet I’ve got a very basic setup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No tmux&lt;/li&gt;
&lt;li&gt;No aliases&lt;/li&gt;
&lt;li&gt;No special .dotfile configs&lt;/li&gt;
&lt;li&gt;No shell preference. I’m fine with zsh, bash, ksh, etc&lt;/li&gt;
&lt;li&gt;No jokes on how to quit vim &lt;span&gt;🔫&lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;My favourite terminal shortcuts:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Ctrl+R to explore the history&lt;/li&gt;
&lt;li&gt;Ctrl+C to cancel / cleanup current command&lt;/li&gt;
&lt;li&gt;Ctrl+L to clean the screen&lt;/li&gt;
&lt;li&gt;Ctrl+A / Ctrl+E to jump to the beginning / end of the command string&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;My top-used commands&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;j (&lt;a href=&quot;https://github.com/wting/autojump&quot;&gt;smart &lt;code&gt;cd&lt;/code&gt;&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;make&lt;/li&gt;
&lt;li&gt;ls&lt;/li&gt;
&lt;li&gt;rm&lt;/li&gt;
&lt;li&gt;cat&lt;/li&gt;
&lt;li&gt;grep&lt;/li&gt;
&lt;li&gt;vi&lt;/li&gt;
&lt;li&gt;yarn, npm, npx, composer, docker-compose and other project-specific CLI tools&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can grab your most used commands too: &lt;a href=&quot;https://superuser.com/questions/250227/how-do-i-see-what-my-most-used-linux-command-are&quot;&gt;How do I see what my most used linux command are?&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Why I stick to defaults&lt;/h2&gt;
&lt;p&gt;Apart from &lt;a href=&quot;https://github.com/wting/autojump&quot;&gt;autojump&lt;/a&gt;, everything else in my setup is quite basic. I try to stick to defaults as much as possible. This is why:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Common use cases are easy to google.&lt;/strong&gt;&lt;br /&gt;
StackOverflow is full of advice on how to do X, Y, Z in the terminal. In 99% of the cases the solution will use standard tools that are already available on my machine: &lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;rm&lt;/code&gt;, &lt;code&gt;cat&lt;/code&gt;, &lt;code&gt;find&lt;/code&gt;, &lt;code&gt;grep&lt;/code&gt;, &lt;code&gt;awk&lt;/code&gt;, &lt;code&gt;sort&lt;/code&gt;, &lt;code&gt;sed&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt;, &lt;code&gt;chmod&lt;/code&gt;, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Non-standard tools require installation.&lt;/strong&gt;&lt;br /&gt;
If I make &lt;a href=&quot;https://github.com/BurntSushi/ripgrep&quot;&gt;&lt;code&gt;rg&lt;/code&gt;&lt;/a&gt; or &lt;a href=&quot;https://github.com/ggreer/the_silver_searcher&quot;&gt;&lt;code&gt;ag&lt;/code&gt;&lt;/a&gt; my default search tool, I’ll have to install it on the remote servers, in the CI environments, in the cloud IDEs, on my colleagues’ machines. It’s not always possible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Customisation requires more learning and memorising.&lt;/strong&gt;&lt;br /&gt;
Now I need to learn how to use both the new tool (let’s say &lt;code&gt;ag&lt;/code&gt;) and the standard pre-installed tool (usually &lt;a href=&quot;https://linuxjourney.com/lesson/grep-command&quot;&gt;&lt;code&gt;grep&lt;/code&gt;&lt;/a&gt;). Otherwise, I won’t be able to work in remote environments, help a teammate (or receive help from them), debug a CI script, etc.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Updates and troubleshooting.&lt;/strong&gt;&lt;br /&gt;
Custom setup can become outdated, can introduce bugs or security issues. I can simply forget that I installed a tricky git helper a year ago and it will cost me a day of troubleshooting at some point.&lt;/p&gt;
&lt;h2&gt;Learn the basics and have fun!&lt;/h2&gt;
&lt;p&gt;Most of the modern development stacks assume basic command line knowledge. The keyword is &lt;em&gt;basic&lt;/em&gt;: you don’t need to make Vim your default text editor or master tmux to become a better developer. If you normally spend 30% of your time in, let’s say, Chrome DevTools and another 30% in VS Code, then you’d better master Chrome DevTools and VS Code first.&lt;/p&gt;
&lt;p&gt;As a developer and Tech Lead, I think of the terminal mastering as something extra that I’m free to do if I &lt;em&gt;want&lt;/em&gt;. After all, it can be a lot of fun! But I don’t have to be a command line geek, and you don’t have to either.&lt;/p&gt;
&lt;h2&gt;Question for you&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;What is your favourite CLI command or shortcut?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Mine is &lt;code&gt;Ctrl+R&lt;/code&gt; shortcut to search through my command line history. This is how it works:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Hit &lt;code&gt;Ctrl+R&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Start typing any part of the previous command you want to run again, e.g. &lt;code&gt;exec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;You command line will be prepopulated with the most recent command that contained &lt;code&gt;exec&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;If it’s not the right one, hit &lt;code&gt;Ctrl+R&lt;/code&gt; again to cycle through older commands.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr /&gt;
&lt;p&gt;&lt;a href=&quot;https://dev.to/kalabro/my-approach-to-the-command-line-1kfm&quot;&gt;Please join discussion on DEV to respond&lt;/a&gt; &lt;span&gt;👩‍💻&lt;/span&gt;&lt;span&gt;🧑‍💻&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>3 simple management tricks I learned as a Tech Lead</title><link>https://kalabro.tech/management-hacks-for-developers/</link><guid isPermaLink="true">https://kalabro.tech/management-hacks-for-developers/</guid><description>Developers often blame “bad management” when something goes wrong. I’ve been there too, I remember the pain. For me, it was useful to sit…</description><pubDate>Thu, 08 Apr 2021 09:30:00 GMT</pubDate><content:encoded>&lt;p&gt;Developers often blame “bad management” when something goes wrong. I’ve been there too, I remember the pain.&lt;/p&gt;
&lt;p&gt;For me, it was useful to sit on both chairs for a while acting as a Tech Lead. In this article, I share three dead simple tricks everyone can start using now to become better managers for themselves. No MBA required &lt;span&gt;🤓&lt;/span&gt;&lt;/p&gt;
&lt;h2&gt;1. Repeat (say it again)&lt;/h2&gt;
&lt;p&gt;Yes, the tricks will be very simple, even stupid, but they work! One of my favourites is repeating. It’s a very powerful yet underestimated technique.&lt;/p&gt;
&lt;p&gt;Finding the courage to say something once is hard, especially when the topic is important to you. But don’t stop there! People forget, deprioritise and misunderstand all the time.&lt;/p&gt;
&lt;p&gt;Internet is full of advice on how to say No, which implies that everything has to be said at least twice. Camille Fournier actually suggests you need to say it three times:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Finally, never underestimate how many times and how many ways something needs to be said before it sinks in. Communication in a large organization is hard. In my experience, most people need to hear something at least three times before it really sinks in.
&lt;a href=&quot;https://www.amazon.com/dp/B06XP3GJ7F/ref=cm_sw_em_r_mt_dp_MKXET9C33MXQ4TEVK3NG&quot;&gt;The Manager’s Path, Camille Fournier&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Some examples where repeating is useful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Remind about an ongoing problem if it was deprioritised.&lt;/li&gt;
&lt;li&gt;Talk to someone else if the first contacted person wasn’t helpful.&lt;/li&gt;
&lt;li&gt;Insist on prioritising some refactoring or housekeeping work.&lt;/li&gt;
&lt;li&gt;Rephrase technical concept in plain English.&lt;/li&gt;
&lt;li&gt;Keep pointing out the agreed coding practices until they are being followed.&lt;/li&gt;
&lt;li&gt;Thank teammates for their help, again and again, in different ways.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Some channels may overuse repetition (e.g. TV series or popular non-fiction). It annoys us and we may think that saying the same thing multiple times is rude or dull. From my experience, if you are respectful and creative, everyone will appreciate your persistence.&lt;/p&gt;
&lt;h2&gt;2. Write full sentences (overcommunicate)&lt;/h2&gt;
&lt;p&gt;Remote work involves a lot of written communication via email and chat apps. Make your written communication explicit and straight to the point so that people don’t have to read 50 chat messages and two different Jira tickets to understand your last “@channel” message in Slack.&lt;/p&gt;
&lt;p&gt;Two ways of saying “No update yet” about the hosting incident:&lt;/p&gt;
&lt;p&gt;&lt;span&gt;✅&lt;/span&gt;
&lt;em&gt;No update yet. I’m checking with Mike from DevOps team about the issue with &lt;a href=&quot;http://www.example.com&quot;&gt;www.example.com&lt;/a&gt; deployment. I will come back to you in 15 min.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;span&gt;❌&lt;/span&gt;
&lt;em&gt;No update yet. I’ll check with Mike about that issue.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;(Who is Mike? Which issue? When will you check? When will my site go up!?)&lt;/p&gt;
&lt;p&gt;Again, over-communication isn’t rude, it’s really the opposite. If something is obvious to you (e.g. there is an ongoing issue with &lt;a href=&quot;http://www.example.com&quot;&gt;www.example.com&lt;/a&gt; ), it doesn’t mean it’s obvious to everyone else. Give them the necessary context as part of your text message, and you’ll get meaningful responses faster.&lt;/p&gt;
&lt;h2&gt;3. Take care of yourself&lt;/h2&gt;
&lt;p&gt;If I would need to limit this article to only one piece of advice, I would keep this one.&lt;/p&gt;
&lt;p&gt;You know better than anyone else when you are stuck or bored or confused. It’s very normal and it happens to all of us from time to time. Take action to get yourself out of it. If we all as individuals will take care of ourselves, many problems will be resolved much quicker and easier. Uncommunicated problems create more problems.&lt;/p&gt;
&lt;p&gt;Your manager may catch some signals of your burnout when it’s too late. Help them and ask for a break sooner.&lt;/p&gt;
&lt;p&gt;Your boss may have no idea that you want to leave the company because you hate DevOps work. Help them and ask for more frontend work in the upcoming project.&lt;/p&gt;
&lt;p&gt;Your client has no idea that you are a morning person. Help them and ask to move late meetings earlier in the day. Repeat if it didn’t work from the first time &lt;span&gt;😃&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;There is no point in struggling at work. Happy people deliver better results, but what is more important, they make other people happier.&lt;/p&gt;
&lt;p&gt;Hopefully, these simple tricks will make you a bit happier at work too!&lt;/p&gt;</content:encoded></item><item><title>Let Cloudflare CDN speed up your classic website like it&apos;s static</title><link>https://kalabro.tech/serve-like-static/</link><guid isPermaLink="true">https://kalabro.tech/serve-like-static/</guid><description>Improve your website performance by caching dynamic pages in Cloudflare (or any other) CDN. No need to rewrite everything in Gatsby :)</description><pubDate>Sat, 08 Aug 2020 18:20:34 GMT</pubDate><content:encoded>&lt;p&gt;One obvious strength of static sites is their performance. The pages aren’t
generated by the server but instead pre-built into HTML &amp;amp; CSS files.&lt;/p&gt;
&lt;p&gt;Many of us developers have already played with the technology, built &lt;a href=&quot;https://www.staticgen.com/&quot;&gt;their own
static site generator&lt;/a&gt; and learned the pros &amp;amp; cons of this
approach. I won’t discuss all of that in this article. Instead, I will remind
ourselves of something else that’s been there for years — CDN.&lt;/p&gt;
&lt;p&gt;These days CDN setup should not necessarily be very complicated and enterprisy. In fact, I will be using
free Cloudflare tier in my examples. Other CDNs have the same or similar setup.&lt;/p&gt;
&lt;h2&gt;How it works&lt;/h2&gt;
&lt;p&gt;When your web server returns a page, let’s say “&lt;a href=&quot;https://www.mozilla.org/en-GB/&quot;&gt;https://www.mozilla.org/en-GB/&lt;/a&gt;”,
it also returns &lt;code&gt;Cache-Control&lt;/code&gt; header explaining to the external world how to
cache this specific page. For example, it can say “do not cache me at all” or “cache me for an hour”, please.&lt;/p&gt;
&lt;p&gt;Browsers and CDNs respect &lt;code&gt;Cache-Control&lt;/code&gt; header when they serve web pages. If the page can be cached,
they save it in their cache storage and next time serve cached version without ever touching your
web server. That’s how a dynamic WordPress site can behave like static for the entirety of anonymous users.&lt;/p&gt;
&lt;p&gt;Let’s have a look at &lt;code&gt;https://www.mozilla.org/en-GB/&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;A screenshot of mozilla.org page with developer tools opened&quot; loading=&quot;lazy&quot; width=&quot;1552&quot; height=&quot;989&quot; src=&quot;/_astro/cdn-mozilla.CDPQ2Var_hf5u1.webp&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;HTTP status of the page is 200 meaning that this page was not cached in user’s browser yet.&lt;/li&gt;
&lt;li&gt;Mozilla.org server returned &lt;code&gt;cache-control: max-age=600&lt;/code&gt;, which means “Hey, browsers and CDNs: cache this page for 10 min max.”&lt;/li&gt;
&lt;li&gt;Cloudflare CDN indeed has already cached this page (HIT)&lt;/li&gt;
&lt;li&gt;I’ve got a cached version which is 96 seconds old.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;If within those 96 seconds something has changed on that page, e.g. a typo has
been fixed, then I will still see the outdated version for the next 504 seconds.
To avoid the page with typo to be served from CDN cache, developers from Mozilla can either
flush CDN cache from Cloudflare admin UI or by using their API.&lt;/p&gt;
&lt;p&gt;Now let’s dig into the details.&lt;/p&gt;
&lt;h2&gt;Enabling cache beyond static files in Cloudflare&lt;/h2&gt;
&lt;p&gt;This step will vary for each CDN service. In Cloudflare, you need
to create so-called “Page Rule” that will enable “Cache Everything” mode for
specified page pattern. Example below:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Screenshot of Cloudflare rule configuration annotated with steps&quot; loading=&quot;lazy&quot; width=&quot;1634&quot; height=&quot;902&quot; src=&quot;/_astro/cdn-cloudflare-cache-everything-page-rule.Cq7P45_i_Z2lAig9.webp&quot; /&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Apply this rule to the entire domain&lt;/li&gt;
&lt;li&gt;(Optional) Switch off “Always Online” feature in favour of &lt;code&gt;stale-if-error&lt;/code&gt; (will be discussed below)&lt;/li&gt;
&lt;li&gt;Cache everything (as opposed to caching &lt;a href=&quot;https://support.cloudflare.com/hc/en-us/articles/200172516-Understanding-Cloudflare-s-CDN#h_a01982d4-d5b6-4744-bb9b-a71da62c160a&quot;&gt;only certain file extensions&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;(My favourite one) Respect “Cache-Control” header from my web server (also known as “Origin”).&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Note that I asked Cloudflare to follow &lt;code&gt;Cache-Control&lt;/code&gt; directives returned by my web server.
It gives me unlimited flexibility in configuring caching TTL for different pages.
In the following section, we will discuss it further. For now, I have to add that
in addition to item 4 you need to configure “Browser Cache TTL” setting in Cloudflare to
“Respect Existing Headers”.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Screenshot of Cloudflare &amp;quot;Browser Cache TTL&amp;quot; options&quot; loading=&quot;lazy&quot; width=&quot;1320&quot; height=&quot;934&quot; src=&quot;/_astro/cdn-cloudflare-respect-origin-cache-control.DfOOmjHN_Z2qPjiw.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;If you don’t want to mess with &lt;code&gt;Cache-Control&lt;/code&gt; in your codebase, you can ignore item 4 and “Browser Cache TTL” setting completely. Cloudflare will add &lt;code&gt;Cache-Control&lt;/code&gt; header for you anyway and you will be able to fine-tune it by “Page Rules”.&lt;/p&gt;
&lt;h2&gt;Adding Cache-Control header to your dynamic content&lt;/h2&gt;
&lt;p&gt;In my experience different site pages and query params may have different cacheability opportunities.
Think of it as if parts of your site are completely static and others are very dynamic.
With &lt;code&gt;Cache-Control&lt;/code&gt; you can achieve this behaviour.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;server&lt;/span&gt;&lt;span&gt;.get&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;*&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; (req&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; res) &lt;/span&gt;&lt;span&gt;=&amp;gt;&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  if&lt;/span&gt;&lt;span&gt; (&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    // Allow to bypass CDN cache by adding ?bypass=cdn to URL.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    req&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;query&lt;/span&gt;&lt;span&gt;.bypass &lt;/span&gt;&lt;span&gt;===&lt;/span&gt;&lt;span&gt; &quot;cdn&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  ) {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    res&lt;/span&gt;&lt;span&gt;.setHeader&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Cache-Control&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;no-store, must-revalidate&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  } &lt;/span&gt;&lt;span&gt;else&lt;/span&gt;&lt;span&gt; {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    res&lt;/span&gt;&lt;span&gt;.setHeader&lt;/span&gt;&lt;span&gt;(&lt;/span&gt;&lt;span&gt;&quot;Cache-Control&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; &quot;public, max-age=0, s-maxage=3600, stale-if-error=3600, stale-while-revalidate=30&quot;&lt;/span&gt;&lt;span&gt;);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  return&lt;/span&gt;&lt;span&gt; handler&lt;/span&gt;&lt;span&gt;(req&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; res&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;span&gt; app);&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;});&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The example above is a simplified Express handler to vary caching behaviour based on the incoming request.
You can achieve something similar in any popular web framework.&lt;/p&gt;
&lt;p&gt;Note that &lt;code&gt;Cache-Control&lt;/code&gt; directive is a bit more advanced in my example:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;max-age=0&lt;/code&gt; - do NOT cache on a browser level&lt;/li&gt;
&lt;li&gt;&lt;code&gt;s-maxage=3600&lt;/code&gt; - cache on CDN (shared cache) for an hour&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stale-if-error=3600&lt;/code&gt; - serve stale cached version for one hour more if the origin server is not available (supported by some CDNs)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;stale-while-revalidate=30&lt;/code&gt; - serve stale version while the new version is being fetched from the origin server (supported by some CDNs)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;You can build your version of &lt;code&gt;Cache-Control&lt;/code&gt; that will serve your needs.&lt;/p&gt;
&lt;h2&gt;Invalidating cache&lt;/h2&gt;
&lt;p&gt;In the case of a static site, you need to re-build and re-upload assets to your server.
Some services automate this process so that content editors don’t have to deal with it.&lt;/p&gt;
&lt;p&gt;We have a similar situation with CDN cache: if you want the newer version of the page
to become available to the rest of the world &lt;em&gt;right now&lt;/em&gt;, then you need to invalidate the existing cache.
Cloudflare users can do it either in admin UI or via API.&lt;/p&gt;
&lt;p&gt;If you use CMS e.g. &lt;a href=&quot;https://wordpress.org/plugins/cloudflare/&quot;&gt;Wordpress&lt;/a&gt; or &lt;a href=&quot;https://www.drupal.org/project/cloudflare&quot;&gt;Drupal&lt;/a&gt;, they may have plugins for automated cache invalidation.&lt;/p&gt;
&lt;p&gt;Otherwise, you can call Cloudflare API directly in the appropriate place of your codebase.
The most used API endpoint is &lt;a href=&quot;https://api.cloudflare.com/#zone-purge-files-by-url&quot;&gt;&lt;code&gt;POST zones/:identifier/purge_cache&lt;/code&gt;&lt;/a&gt; - purges cache for specific URLs.&lt;/p&gt;
&lt;p&gt;Note that Cloudflare doesn’t offer cache purging by wildcard. There is “Cache Tags” feature on
Enterprise tier but I have never used it.&lt;/p&gt;
&lt;p&gt;Other CDNs offer cache purging via API too. For example, Fastly has &lt;a href=&quot;https://docs.fastly.com/en/guides/soft-purges&quot;&gt;soft purging&lt;/a&gt; in addition to
hard purging. This is something I miss in Cloudflare API. Let’s say I updated
content page in my CMS and it automatically purged cache for some URLs that were affected by my update. If I managed to break the site
with my update, then purged URLs will be down for all anonymous users.
With soft purge + &lt;code&gt;stale-if-error&lt;/code&gt; you could stay always online.&lt;/p&gt;
&lt;p&gt;Alternately to automated cache purging, you can just keep cache TTL very short (10 mins like in Mozilla example) instead of
triggering automated cache invalidation on every content change.&lt;/p&gt;
&lt;h2&gt;stale-if-error or Always Online&lt;/h2&gt;
&lt;p&gt;As you may remember, I suggested to switch off Cloudflare’s “Always Online”
feature (which is often enabled by default) in favour of &lt;code&gt;stale-if-error&lt;/code&gt;.
&lt;code&gt;stale-if-error&lt;/code&gt; isn’t noticeable for the end users while
“Always Online” adds Cloudflare banner at the top of your web page informing your users
that the site isn’t working at the moment.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stale-if-error&lt;/code&gt; is a standard &lt;code&gt;Cache-Control&lt;/code&gt; directive that is supported by other CDNs as well.
It asks CDNs and browsers to serve stale cache if the page isn’t available on the origin web server. Different CDNs can understand page availability differently. For example,
Cloudflare will respond with stale content only to the specific error codes:&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;Excerpt from Cloudflare documentation&quot; loading=&quot;lazy&quot; width=&quot;1642&quot; height=&quot;558&quot; src=&quot;/_astro/cdn-cloudflare-error-codes.BDtRKuHf_Z2tSoMD.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;500 or 503 error codes trigger neither Always Online nor &lt;code&gt;stale-if-error&lt;/code&gt;.&lt;/p&gt;
&lt;h2&gt;To summarize&lt;/h2&gt;
&lt;p&gt;Modern CDNs (and HTTP) provide a simple and elegant way to make parts of your site
behave like they are static. CDN cache protects the site from traffic spikes and makes some of
the site errors and instabilities invisible for end users. It’s not just for heavy
enterprises. A mid-size website can save computing costs of their hosting by enabling CDN cache for the most
popular site pages.&lt;/p&gt;
&lt;p&gt;Of course, you should still work on the performance of the original site but CDN cache can be
nice low-hanging fruit in your journey &lt;span&gt;🍒&lt;/span&gt;&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Liked this article? Have a question? &lt;a href=&quot;https://dev.to/kalabro/let-cloudflare-cdn-speed-up-your-classic-website-like-it-s-static-oaf&quot;&gt;Please join discussion on DEV&lt;/a&gt; &lt;span&gt;👩‍💻&lt;/span&gt;&lt;span&gt;🧑‍💻&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>How to investigate technical solutions</title><link>https://kalabro.tech/tech-lead-investigate/</link><guid isPermaLink="true">https://kalabro.tech/tech-lead-investigate/</guid><description>We, developers, tend to value practice over theory because this is how we learn most of the things. Often though, we don&apos;t know how to start, which library or service to pick, etc. Quick investigation process described in this article helps me in such situations.</description><pubDate>Sat, 23 May 2020 20:00:34 GMT</pubDate><content:encoded>&lt;p&gt;In my &lt;a href=&quot;https://kalabro.tech/mental-health-full-stack-developers/&quot;&gt;previous post on the subject&lt;/a&gt; I suggested the long term approach to the learning problem: focus on general knowledge rather than on specific tools and implementations. But what if you need to investigate a new technical field &lt;em&gt;right now&lt;/em&gt;, let’s say this week, to proceed with the project at hand? Tech leads do this kind of work regularly in order to prepare high-level estimates and architect new systems.&lt;/p&gt;
&lt;p&gt;In this article, I will share my approach to a quick technical investigation. I apply it to new technologies and any other unknowns as they appear in my daily tasks. I mapped the steps to the days of the week, but the timeline can be scaled up or down based on the size of the problem. So, let’s get started:&lt;/p&gt;
&lt;h2&gt;Part 1: Monday&lt;/h2&gt;
&lt;h4&gt;&lt;span&gt;😍&lt;/span&gt; You are great&lt;/h4&gt;
&lt;p&gt;It’s totally fine to not know something. Don’t treat it as your “fault” or a lack of talent/education/seniority. You are going to figure it out and you are great!&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;🔍&lt;/span&gt; Be specific&lt;/h4&gt;
&lt;p&gt;Narrow down the area of investigation as much as possible. In practice, it means that technical investigation starts with business investigation. When the problem is defined, ensure you can’t solve it without further investigation. Sometimes people ask for AI, but their problem can be solved with a regular expression. Stop thinking that your solution isn’t “cool” enough. It’s super cool as long as it solves the problem.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;🙋‍♀️&lt;/span&gt; Ask people&lt;/h4&gt;
&lt;p&gt;If you need to proceed with further investigation, then first ask your colleagues and friends who were working on something similar in the past (don’t confuse friends and colleagues with random strangers on the internet!). There is no point in learning something the hard way if you can just ask your teammate for help. An extreme variant of this option is to hire a person who has the necessary experience and learn from them.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;📝&lt;/span&gt; Pick 10 random articles&lt;/h4&gt;
&lt;p&gt;Google your problem definition using different wording and pick 10 random articles and videos (it also can be one &lt;em&gt;short&lt;/em&gt; book). List them in your notes and start reading them all from top to the bottom. Don’t try to figure out your final solution, don’t make any decisions just yet, don’t try code snippets suggested in the articles. Just read them.&lt;/p&gt;
&lt;p&gt;Keep reading and taking quick notes. It can be a simple bullet list, a drawing or a mind map. Stop when you finished with your 10 articles. Sleep on it.&lt;/p&gt;
&lt;h2&gt;Part 2: Tuesday&lt;/h2&gt;
&lt;h4&gt;&lt;span&gt;🏁&lt;/span&gt; Fill in the gaps&lt;/h4&gt;
&lt;p&gt;Review your notes and compare with the problem definition. You’ll notice some gaps in your notes. Google them again, find 2-3 extra resources and add them to your list. Finish the notes and stop gathering information. Most likely you have already learned just enough to proceed to the next step.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;👯‍♀️&lt;/span&gt; Show it to a teammate&lt;/h4&gt;
&lt;p&gt;Now it’s time to present your notes to someone else. Explaining the topic to another person will help you understand what you learned.&lt;/p&gt;
&lt;p&gt;While presenting, reflect the fact that the information is not yet verified. For example, don’t say “The best A/B testing tool is X”. Instead, say “I found several authors who really enjoyed X”. Pay extra attention to the remaining unknowns (instead of leaving them out of the discussion).&lt;/p&gt;
&lt;p&gt;Together, narrow down potential solutions to a minimum. For example, if you have five A/B testing services in your notes, pick two most promising based on what you learned so far and on the problem definition. Don’t worry that you may occasionally exclude the “right” solution from your shortlist. There is no one right way to solving any technical problem.&lt;/p&gt;
&lt;h2&gt;Part 3: Wednesday, Thursday, Friday&lt;/h2&gt;
&lt;h4&gt;&lt;span&gt;🏖&lt;/span&gt; Try it in a sandbox&lt;/h4&gt;
&lt;p&gt;Finally, we are in the famous practice step. I remember times when I was putting together something new that I barely understood only to push it to production faster. This approach was fast at the beginning, but in some cases, it slowed down further development dramatically.&lt;/p&gt;
&lt;p&gt;Before starting to write any code, prepare a list of outstanding questions that you want to clarify through practice. When the problem is small enough, you can start implementing the real solution without properly finishing the investigation. But in the general case, proofs of concepts should not go straight to production to avoid unnecessary risks.&lt;/p&gt;
&lt;h4&gt;&lt;span&gt;✍️&lt;/span&gt; Write a summary&lt;/h4&gt;
&lt;p&gt;Finish with a concise report that you wish had been written by someone else before you
started your investigation. Don’t put too much effort in it - such reports usually become outdated in 6-9 months. Share the report with the team and agree on the next steps. Switch to something else for a little while to clear your mind.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;My quick investigation process includes the following parts:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Gathering &amp;amp; structuring information on a very narrow topic (&lt;em&gt;X time&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Sharing with someone else and filtering out (&lt;em&gt;X time&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Building proofs of concept to figure out some crucial details (&lt;em&gt;3X time&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Putting together a summary for discussion and further actions.&lt;/li&gt;
&lt;li&gt;Iterating.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This process is very intense because you consume and analyse a lot of new information within a short period of time. It also can be uncomfortable to touch something completely new and to feel stupid after being “an expert” in your field. As Josh Kaufman explained in &lt;a href=&quot;https://www.youtube.com/watch?v=5MgBikgcWnY&quot;&gt;“The first 20 hours”&lt;/a&gt; talk, the main barrier to learning something new is emotional. It’s often hard to start and even harder to finish. I hope that my article will help you to overcome those issues when you next time will be investigating a new technical problem. Remember, you are great!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Liked this article? Have a question? &lt;a href=&quot;https://dev.to/kalabro/how-to-investigate-technical-solutions-5gmj&quot;&gt;Please join discussion on DEV&lt;/a&gt; &lt;span&gt;👩‍💻&lt;/span&gt;&lt;span&gt;🧑‍💻&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>The Tech Lead rule: Management first, coding second</title><link>https://kalabro.tech/tech-lead-time-to-code/</link><guid isPermaLink="true">https://kalabro.tech/tech-lead-time-to-code/</guid><description>It took me two years to realise that “How to find time to code?” is the wrong question for a Tech Lead. In this blog post I&apos;m explaining why.</description><pubDate>Sun, 05 Apr 2020 15:30:34 GMT</pubDate><content:encoded>&lt;p&gt;I opened my previous post &lt;a href=&quot;https://kalabro.tech/tech-lead-one-on-one/&quot;&gt;about 1:1 meetings&lt;/a&gt; with the following paragraph:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Every new Tech Lead will struggle to find time for coding in their busy day. That’s very normal because when you step into Tech Lead shoes you suddenly need to learn all those management tools from planning and prioritisation to decision making to conflict solving.
You never know what you will need first, so you will have a fun time learning a bit of everything in parallel (and trying to meet your coding hours quota at the same time).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I now realised that the idea of that paragraph is not very obvious, especially if you are just about to start as a Tech Lead.&lt;/p&gt;
&lt;h2&gt;Tech Lead is a manager&lt;/h2&gt;
&lt;p&gt;It seems to be clear that we, Tech Leads, are developers, and we should write some code, should stay current and keep our hard skills sharp.&lt;/p&gt;
&lt;p&gt;What is often forgotten or put at lower priority is that a Tech Lead is a manager and our management skills are the key to our success in the role.&lt;/p&gt;
&lt;p&gt;It’s true that as Tech Leads we don’t usually have full-time management responsibilities (and often have no authority), but it doesn’t change the priority: management first, coding second.&lt;/p&gt;
&lt;p&gt;Even if you’ve got a very small team and management bit takes just 20% of your time, that 20% is still the most important part of your job. If you deprioritise it or do it poorly, then your small team is in danger: they may miss the deadline, spend time on the wrong task, get stuck or blocked by another team, overengineer the solution, overpromise to the stakeholders, fail at their performance quotas without understanding what they did wrong. Tech Lead as a manager can prevent or notice such issues sooner. Tech Lead as a developer can only try to write the entire codebase alone (and fail at that).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Management first, coding second&lt;/strong&gt; - once you start to see it in this order, it will become clearer what’s next.&lt;/p&gt;
&lt;h2&gt;Tech Lead is a developer&lt;/h2&gt;
&lt;p&gt;Usually, we learn the basics of management by watching how other Tech Leads and managers work. Some of us are good leaders naturally, and it helps too. Still, most of us grow into Tech Leads from Senior Developer role and we don’t have a degree in management. Furthermore, you may be affected by a bias that management isn’t that important and only creates problems for the dev teams.&lt;/p&gt;
&lt;p&gt;It’s important to recognise that &lt;strong&gt;you are now supposed to do a new type of work&lt;/strong&gt;, that you have never done professionally before. It’s time for opening your mind for learning and practising new skills. It’s not a good time for full-day coding tasks.&lt;/p&gt;
&lt;h2&gt;Management tasks&lt;/h2&gt;
&lt;p&gt;Now, when we have the priorities cleared, let’s review major areas of your management efforts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;📆&lt;/span&gt; Invest in team planning&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Help each team member to create a plan for their working week. It doesn’t mean that you need to assign tasks to everyone (sometimes you need, but it’s an edge case). Your goal is to create and maintain an environment where each team member can figure out what they will be doing tomorrow without checking with you/your manager/stakeholders every day.&lt;/p&gt;
&lt;p&gt;You’ll need to have a plan for your week, too, and it should reflect the “management first” rule.&lt;/p&gt;
&lt;p&gt;One common piece of advice to novice Tech Leads is to get better at time management. I think that &lt;strong&gt;you should first get better at mid-term planning (monthly and weekly)&lt;/strong&gt;. Then it will become easier to manage your time within each day.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;📚&lt;/span&gt;Invest in knowledge sharing&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Make sure documentation is treated seriously by the team. Lead by example: document things that are often asked by the clients and other team members.&lt;/p&gt;
&lt;p&gt;Make yourself available for questions during the day. If you put yourself in DND mode for an entire day, you won’t be able to create an environment where people are willing to help each other. In such an environment, you’ll be able to step back from time to time, and nobody will notice.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🌀&lt;/span&gt;Invest in workflows and processes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Meet your new best friends: company workflows and processes. They are “reusable libraries” of management. They can help many developers stay productive and creative, just like software libraries and frameworks help us build projects quickly and consistently.&lt;/p&gt;
&lt;p&gt;To elaborate further on this metaphor, software libraries should be carefully chosen and maintained by the technical team. The same applies to the workflows and processes in the company. No one software library works for all development projects, and no one workflow fits every software engineering team.&lt;/p&gt;
&lt;p&gt;As a first step, make sure you understand and follow the existing organisational workflows yourself. As an individual contributor, you could sometimes think that they were an unnecessary bureaucracy. As a new Tech Lead, make sure it’s not the case, or initiate the change. Workflows should serve the teams, not the other way around.&lt;/p&gt;
&lt;p&gt;Give extra focus to workflows that put you in a gatekeeper position (for example, pull requests can’t be deployed without Tech Lead approval). In rare cases, it may be a reasonable requirement, but usually, it indicates a problem.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;👯‍♀️&lt;/span&gt; Regularly check in with your manager&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;So now you keep an eye on the team. Start sharing your observations with your direct manager early, partly to let the problems bubble up. It can be a summary of what went well, what had to be fixed by you, and what requires senior management attention. One of the most important management rules is &lt;strong&gt;“No surprises”&lt;/strong&gt;. If you share the team status regularly, then senior management will be prepared to step in when necessary.&lt;/p&gt;
&lt;p&gt;Funny enough, they may see your problems from various unexpected angles. Be open to that. Sharing your vision helps to align the priorities in both ways.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example 1&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You:&lt;/em&gt; I have to manually perform project deployments and take database backups. It’s not a big deal for me, but I think it can be improved to follow best practices.&lt;br /&gt;
&lt;em&gt;Manager:&lt;/em&gt; the project is growing fast, and the dev team should be prepared for frequent and safe deployments. Make DevOps initiative the main priority starting from next week.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Example 2&lt;/strong&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;You:&lt;/em&gt; I have to manually perform project deployments and take database backups. I think it’s a major team blocker (and this is just not a fun job for me).&lt;br /&gt;
&lt;em&gt;Manager:&lt;/em&gt; there will be no more deployments for that project starting from next month. It will be replaced with the new development project which should be the main priority starting from next week.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You may say that the manager should have shared the details about the future of your current project sooner. Of course, they would share at some point or they might have already shared it but you missed the point.&lt;/p&gt;
&lt;p&gt;From my practice misalignments happen all the time because everything keeps on changing. Sharing your successes and problems with your manager regularly will help both of you to have “no surprises”, or at keep them at a minimum.&lt;/p&gt;
&lt;p&gt;A final note that you should not be focused on problems only, otherwise your manager will start escaping from you.&lt;/p&gt;
&lt;h2&gt;Developer tasks&lt;/h2&gt;
&lt;p&gt;So, your team know the priorities, help each other when they have questions, and follow workflows to perform common tasks. You manager is aware of some problems that you faced and helps to fix them. Not everything is going so well, but you have a plan in place to improve things in the long run.&lt;/p&gt;
&lt;p&gt;You still feel very busy and unproductive because you spend less time coding and more time planning and communicating.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🐌&lt;/span&gt; Reduce your expectations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Some organisations &lt;a href=&quot;https://github.com/webflow/leadership/blob/master/tech_lead.md#how-much-should-i-expect-to-code&quot;&gt;explicitly set coding expectations&lt;/a&gt; for Tech Lead role. Others don’t do that because it may depend on the team and the project at hand.&lt;/p&gt;
&lt;p&gt;In either way, you’ll have significantly less time for coding because:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;You are expected to do some management&lt;/li&gt;
&lt;li&gt;You are not good at management, and you need to learn how to do it well&lt;/li&gt;
&lt;li&gt;You are performing technical oversight and switching context between several different tasks per day&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Accepting this change was very hard for me. It took almost a year for me to understand that investing in my management skills will free up some time for technical tasks in the long term.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🥎&lt;/span&gt; Pick small, not urgent tasks&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you include yourself in a sprint as a developer, prefer smaller tasks that don’t block other team members. If it’s not possible, then prefer pair programming or very close collaboration on a task so that someone else will be able to finish it without you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🛩&lt;/span&gt; Block time for coding sessions&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This is a very common recommendation: book a time for coding in DND (Do not disturb / in airplane) mode, and everything will be fine. From my experience, it will indeed, &lt;strong&gt;if you follow all the other recommendations listed above&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I personally enjoy having 3-4hr focus slots at the beginning of the day, but we have our daily standup meetings in the middle of that slot. They immediately kill my focus as we start to discuss different aspects of the project, some problems and blockers that require my attention, and the new surprises that should be communicated up.&lt;/p&gt;
&lt;p&gt;I accept this distraction because I find our daily standups very valuable from the management perspective. I could also skip, postpone or make them asynchronous. As a Tech Lead, when you make choices like this, you have to keep the organisation and the team as your priorities.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;👏&lt;/span&gt; Take off your Tech Lead hat&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Normal Tech Lead schedule will not allow you to grow as a software developer at the same pace as it used to be. However, your technical expertise is crucial for running a technical team. Yes, you can learn from your teammates while reviewing the code. Yes, you can experiment with the code while you are working on your smaller tech tasks during your focus hours. Yes, you can read some blog posts in your spare time. Yes, you can build a pet project. It’s great, but not enough for staying current in the modern IT world.&lt;/p&gt;
&lt;p&gt;Tech Lead role isn’t the final career destination for most of us. First of all, it’s very challenging because you are a manager and a developer at the same time, and you are kind of okay at both. That’s why folks often move on to full management or full development roles from this point. Your Tech Lead experience will help you succeed in either route.&lt;/p&gt;
&lt;p&gt;Some companies periodically rotate Tech Leads in their teams. Others try to spread the management burden across the whole team (”&lt;span&gt;🦄&lt;/span&gt; No-Managers teams”). Finally, you can simply ask your manager to put you on another project for a couple of months. It may be enough to get refreshed and upskilled.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;It took me two years to realise that “How to find time to code?” is the wrong question for a Tech Lead. You should focus on getting better at management, and ask your boss to give you “management holidays” if you need to invest more time in your hard skills.&lt;/p&gt;
&lt;p&gt;Tech Lead is a very challenging role, partially because we put a lot of pressure on ourselves and hesitate to ask our senior colleagues for advice. This experience is “unforgettable” as it changes your understanding of software development process. With this new understanding, you can do more either as a developer or as a manager.&lt;/p&gt;
&lt;p&gt;Good luck!&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Liked this article? Have a question? &lt;a href=&quot;https://dev.to/kalabro/the-tech-lead-rule-management-first-coding-second-1k4f&quot;&gt;Please join discussion on DEV&lt;/a&gt; &lt;span&gt;👩‍💻&lt;/span&gt;&lt;span&gt;🧑‍💻&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>Why 1:1 meetings are so valuable for Tech Leads</title><link>https://kalabro.tech/tech-lead-one-on-one/</link><guid isPermaLink="true">https://kalabro.tech/tech-lead-one-on-one/</guid><description>1:1 is a simple and powerful management tool that is often underestimated by novice Tech Leads. Check out my practical recommendations to make the most of it.</description><pubDate>Wed, 01 Apr 2020 23:30:34 GMT</pubDate><content:encoded>&lt;p&gt;Every new Tech Lead will struggle to find time for coding in their busy day. That’s very normal
because when you step into Tech Lead shoes you suddenly need to learn all those management tools from planning and prioritisation to decision making to conflict solving.
You never know what you will need first, so you will have a fun time learning a bit of everything in parallel (and trying to meet your coding hours quota at the same time).&lt;/p&gt;
&lt;p&gt;One cheap thing that you can start doing earlier in your career is to set up 1:1 (one-on-one, face-to-face) meetings with your team and direct manager(s). That’s low effort to schedule a monthly call into your calendar, and a huge investment into your people management capabilities.&lt;/p&gt;
&lt;p&gt;First, let’s see why 1:1s are valuable, and then I’ll share some practical recommendations
how to get started.&lt;/p&gt;
&lt;h2&gt;The value of 1:1s&lt;/h2&gt;
&lt;p&gt;1:1 meetings exist in management practice to build and maintain an essential human connection between you and another person who happened to be your colleague.
In the long run, it simplifies all people management tasks that fall on a Tech Lead shoulders.&lt;/p&gt;
&lt;p&gt;Many of us don’t have specialised people management skills when we start as Tech Leads. Most of us don’t realise &lt;em&gt;how much&lt;/em&gt; people management work we Tech Leads actually do, so let me just list a few things to give you an idea:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;People performance / handling low performers&lt;/li&gt;
&lt;li&gt;Onboarding &amp;amp; mentoring&lt;/li&gt;
&lt;li&gt;Engaging &amp;amp; motivating&lt;/li&gt;
&lt;li&gt;Convincing people to get things right / follow the workflow&lt;/li&gt;
&lt;li&gt;Handling drama queens / emotional moments&lt;/li&gt;
&lt;li&gt;Handling complaints&lt;/li&gt;
&lt;li&gt;Asking and giving help&lt;/li&gt;
&lt;li&gt;Delegating&lt;/li&gt;
&lt;li&gt;Firing staff (Oops.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That looks like a full time job, but the funny thing is that Tech Leads are supposed to be aware of all these people management aspects and handle them on a &lt;em&gt;basic&lt;/em&gt; level while spending a couple of hours per day max on it.&lt;/p&gt;
&lt;p&gt;Instead of learning all of that in detail, you can invest in something that is a foundation of people management - human connection. Practising focused 1:1 meetings with each member of your team (and with your manager, of course) is the easiest way to get better in all those things at the same time.&lt;/p&gt;
&lt;p&gt;Tech Leads are often generalists, and 1:1 is another general tool that can help to solve different problems.&lt;/p&gt;
&lt;h2&gt;How to run my 1:1s&lt;/h2&gt;
&lt;p&gt;There are books written on the topic, but you will need them only if you decide to move further on the management ladder. Otherwise, you can use the basic,
“common sense” recommendations:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;⏱&lt;/span&gt; Start with monthly 45min meetings with 1 or 2 teammates. Add more slowly.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You should really stick to your company policy around 1:1s. If you don’t have one, I can recommend starting with monthly meetings
and make them more frequently if needed. Some of my 1:1s are monthly, others are weekly or quarterly. What’s important is that
they all are &lt;em&gt;recurring&lt;/em&gt;, and I generally try not to skip them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;👯‍♀️&lt;/span&gt; Discuss what you both have in common at work&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Should you prepare some interesting intellectual topics to discuss on your 1:1s? Not at all. You can stick to what you already have in common: a project that you both are working on. It doesn’t mean that you should be discussing a task that is currently in progress. Rather, you can talk about long term vision,
current development workflow, what was challenging and what was frustrating in the past month for the other person, etc. Making a discussion a bit more generic can suddenly reveal very concrete and interesting things.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;💎&lt;/span&gt; Feedback exchange&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Again, books have been written on it. Feedback is the root of improvement and growth, so take it seriously and prepare before the meeting.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Give colorful positive feedback. Make sure it’s detailed enough. “Well done!” isn’t enough.&lt;/li&gt;
&lt;li&gt;Give corrective feedback. Google different ways to do that. You should be framing it in “things to improve” message for the other person.&lt;/li&gt;
&lt;li&gt;Ask for corrective feedback. If the other person is not prepared or shy, then try questions like “How I could help with X”, “What would be an ideal scenario of Y”, “I need your advice about Z” etc. Corrective feedback is a treasure that you must collect in order to improve. Try hard to get your treasures.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;👂&lt;/span&gt;Practise active listening&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Active listening is a skill that helps in many areas of our work, especially when talking to our customers and users. You can use your 1:1s to practise
this skill. Start from noticing when you don’t understand or don’t really care about what the other person says.&lt;/p&gt;
&lt;p&gt;Example: when a junior team member was explaining in detail how they tried to install the project locally, you were thinking about your next meeting in the background of your mind. Instead, you can ask a few questions to figure out if it’s a problem in the project documentation, installation script, the developer skills. Maybe everything is totally fine, but your junior team member is really worried that they spent 2 days on it and they will be fired because of that. Listen to them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;📒&lt;/span&gt; Prepare private 1:1 document to take your own notes&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You will need to remind yourself of the outcome of previous 1:1 meeting as well as keep notes for the next one. Simple Google Doc should work just fine.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🎭&lt;/span&gt; Don’t play games&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Don’t try to pretend that you are a friendly extravert who shares all the opinions of another person.It will not help you maintain a healthy relationship. Behave as usual.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;span&gt;🐢&lt;/span&gt; Keep calm and have your 1:1&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Don’t rush, don’t complain that you are very busy, don’t multitask while on 1:1. If you are not in the right mood / not prepared for your next 1:1, then better to postpone and come back prepared.&lt;/p&gt;
&lt;h2&gt;To summarise&lt;/h2&gt;
&lt;p&gt;1:1 is a simple and powerful management tool that is often underestimated by novice Tech Leads. Regular 1:1s fall into “Important, not urgent” category of work — they are an investment in your people management capabilities. You don’t need to learn anything specific to get started, and it will get better and better with practice &lt;span&gt;🌈&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>Practical thinking</title><link>https://kalabro.tech/practical-thinking/</link><guid isPermaLink="true">https://kalabro.tech/practical-thinking/</guid><description>What I noticed in behaviours of great developers is that they find a moment to think outside the box and apply results of their thought process to reality. This is what I call practical thinking.</description><pubDate>Sun, 02 Feb 2020 00:30:34 GMT</pubDate><content:encoded>&lt;p&gt;I was first paid for some webdev related work in 2006. Since then, I’ve seen a lot of projects, played my role in several development teams, and worked closely with a few brilliant software engineers. Looking back and reflecting now, I think I have always been a mediocre developer, intuitively picking random opportunities and handling them well enough. In attempts to learn from better developers I was watching them and trying to copy their behaviour. I noticed a few things that they all do regardless of their specific role, seniority or tech stack. One of them is what I call practical thinking.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;As you grow in your career, you’ll experience a lot of teachable moments, a lot of lessons in how things should or should not be. These can be “best practices,” or scars caused by mistakes. This unconscious buildup can cloud our thinking and reduce our creativity. When we close our minds and stop learning, we start to lose the most valuable skill for maintaining and growing a successful technical career. Technology is always changing around us, so we must continually experience that change.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.amazon.com/dp/1491973897/ref=cm_sw_em_r_mt_dp_U_39UdEbGXEGAKQ&quot;&gt;&lt;em&gt;Fournier, Camille. The Manager’s Path.&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When I grew up, I suddenly realised that adults don’t think enough. Many of us are prisoners of our habits and habits of our relatives. We tend to overvalue our life experience and social status. We tend to avoid or replace thinking work with copy &amp;amp; paste from previous experience. It becomes more and more attractive as you become older. Don’t get hooked: stay curious and thoughtful.&lt;/p&gt;
&lt;p&gt;The problem with applying this piece of advice in practice is that a developer can’t just sit down and think while their time tracker is running. First of all, it is not always encouraged by employers who imagine developers writing code 40hr/week. Secondly, it’s hard to switch our brain in thinking mode when we need a brilliant idea for your current task. Finally, popular web developer courses and learning materials often skip this bit and offer tools-focused rather than thinking-focused exercises.&lt;/p&gt;
&lt;p&gt;What I noticed in behaviours of great developers is that they find a moment to think outside the box and apply results of their thought process to reality. This is what I call practical thinking.&lt;/p&gt;
&lt;p&gt;Because of the habit of practical thinking, they generate more ideas, and observe promising ideas deeper. They ask more questions, and get more insights. They notice potential issues before they became a catastrophe. They see opportunities for themselves and potential in talented team mates.&lt;/p&gt;
&lt;p&gt;Sounds great, and works great too, after some practice.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🤬&lt;/span&gt; Start from pain points&lt;/h3&gt;
&lt;p&gt;When I face an uncomfortably annoying problem, I try to think about it from different angles and write down my thoughts. It doesn’t solve the problem magically, but it helps me understand different aspects of it much better. It’s easier to start building a habit of practical thinking from very uncomfortable problems because they are already scratching you on the background of your mind. You will want to resolve them.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🎨&lt;/span&gt; Visualise your thinking process&lt;/h3&gt;
&lt;p&gt;Bullet list, mind map, whiteboard, colored pencils - find visualisation technique that works for you best. Human built-in RAM is very small for manipulating large controversial data sets. So use swap!&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🤖&lt;/span&gt; Automate&lt;/h3&gt;
&lt;p&gt;When you work on a boring task, think how it could be automated. In a worst-case scenario you’ll figure out that the task is actually hard to automate, but at least it will become less boring.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;📆&lt;/span&gt; Actively participate&lt;/h3&gt;
&lt;p&gt;When you are sitting on a meeting without being actively involved, ask yourself why. Did you come prepared for this meeting? Are other attendees feeling the same? How it could be improved? I know some teams dropped daily stand-ups because all attendees agreed on another way to share their status.&lt;/p&gt;
&lt;h3&gt;&lt;span&gt;🎓&lt;/span&gt; Share your knowledge and learn from others&lt;/h3&gt;
&lt;p&gt;When you are not satisfied by your team mate’s work, check if you can help them to improve. Is there hidden knowledge about the project that you can share? Are you open to alternative solutions that your peer proposes? Was a bug introduced because of code obscurity? How to improve it so that other developers will not repeat that mistake?&lt;/p&gt;
&lt;p&gt;I listed just a few examples. You will find yours and develop your own style of practical thinking. Good luck with it!&lt;/p&gt;
&lt;p&gt;Be prepared that your boss may not like that you think too much about something that is outside of your current tasks list. It’s senior leadership problem to re-focus employees on a company mission and give them just enough autonomy and responsibility, and this problem is not simple. Help your boss find the right problem for you to solve if you picked not the best one.&lt;/p&gt;
&lt;p&gt;One final note. The more thinking you do as part of your job, the less chance you have of being replaced by robots.&lt;/p&gt;</content:encoded></item><item><title>My tech year in review</title><link>https://kalabro.tech/my-tech-year-in-review-2019/</link><guid isPermaLink="true">https://kalabro.tech/my-tech-year-in-review-2019/</guid><description>A few tech highlights from 2019.</description><pubDate>Thu, 26 Dec 2019 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;2019 was an interesting and productive year for me. At SystemSeed, I keep sharpening my Tech Lead skills as well as observe the outer space for promising tools, good advice, and inspiration. Unfortunately I spend less time sharing my knowledge publicly and contributing to the open source, and I’m grateful to thousands of talented developers who build amazing libraries, frameworks and modules (that I have to cope with). Without you, web development wouldn’t be so wild and creative job. I’m proud to be part of web development industry, and I love my job very much &lt;span&gt;❤️&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Below are a few highlights from my tech work in 2019. All opinions are my own.&lt;/p&gt;
&lt;h2&gt;Books&lt;/h2&gt;
&lt;p&gt;As I get older, I tend to choose books over blog posts.
By the end of the year I can barely remember a good article or YouTube video -
there were too many of them. It’s much easier with good books: I’ve got only a couple of them to mention.&lt;/p&gt;
&lt;h3&gt;&lt;a href=&quot;https://www.goodreads.com/book/show/39080433-accelerate&quot;&gt;Accelerate: The Science of Lean Software and DevOps: Building and Scaling High Performing Technology Organizations&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The authors of Accelerate book acknowledge that business leaders are often unaware of DevOps as a powerful and effective instrument for IT organizations. This book helps me to facilitate conversations about
importance of DevOps with clients and stakeholders who may push
back on everything that is not pure feature development. In fact what businesses
often want is not just &lt;em&gt;a&lt;/em&gt; feature, but rather an ability to develop and deliver
features in a good pace, an ability to make changes as businesses learn from their users and evolve their strategies.&lt;br /&gt;
&lt;strong&gt;Business wants developer operations to be optimized for change.&lt;/strong&gt; It’s everyone responsibility
to ensure that DevOps is part of project scope naturally, part of planning and
prioritization. Accelerate book is amazing in explaining that.&lt;/p&gt;
&lt;p&gt;My video review for SystemSeed team is &lt;a href=&quot;https://www.youtube.com/watch?v=EJi1qCV-pfM&quot;&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;h3&gt;&lt;a href=&quot;https://www.goodreads.com/book/show/39996759-a-philosophy-of-software-design&quot;&gt;A Philosophy of Software Design&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;This is a brilliant read that I can recommend to every developer regardless of their experience and specialization.
You will definitely learn or re-discover something valuable about software craftsmanship.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I have noticed that the design-it-twice principle is sometimes hard for really smart people to embrace. When they are growing up, smart people discover that their first quick idea about any problem is sufficient for a good grade; there is no need to consider a second or third possibility. This makes it easy to develop bad work habits. However, as these people get older, they get promoted into environments with harder and harder problems. Eventually, everyone reaches a point where your first ideas are no longer good enough; if you want to get really great results, you have to consider a second possibility, or perhaps a third, no matter how smart you are. The design of large software systems falls in this category: no-one is good enough to get it right with their first try.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Apart from these two books, I would like to mention “Clean Architecture” by Uncle Bob (&lt;a href=&quot;https://www.youtube.com/watch?v=4AUVBtj04Cg&quot;&gt;my video review here&lt;/a&gt;).
It was a little bit hard to read for me because of special terminology and references to &lt;a href=&quot;https://en.wikipedia.org/wiki/SOLID&quot;&gt;SOLID&lt;/a&gt; in every single paragraph.&lt;br /&gt;
If your team already speak SOLID language, it will be a good reiteration of “Clean Code” for them. Otherwise “A Philosophy of Software Design” might be a better first step.
It does not introduce that many terms, and for me it was more intuitive, more inline with my own experience.&lt;/p&gt;
&lt;h2&gt;Technologies&lt;/h2&gt;
&lt;h3&gt;Decoupled Drupal&lt;/h3&gt;
&lt;p&gt;As you may know, most of my experience in web development is somehow related to Drupal. Once I joined community back in 2011, it affected dramatically my further career and views on technology in general.&lt;/p&gt;
&lt;p&gt;Last year I was working with Drupal 8 as a pure backend system. User facing applications were decoupled from Drupal and written in JavaScript (React, Next.js).&lt;/p&gt;
&lt;p&gt;You can watch and read about decoupled Drupal in detail here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://youtu.be/ouBIAap09oA&quot;&gt;SERVE THEM ALL! Headless Drupal as a backend for multiple frontend applications&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/systemseed/kicking-off-decoupled-drupal-react-projects-with-boilerplate-67253a8dee29&quot;&gt;Kicking off decoupled Drupal &amp;amp; React projects with boilerplate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you want to investigate this approach deeper, consider one of &lt;a href=&quot;https://www.enik.io/drupal/boilerplate/2019/08/30/drupal-boilerplates.html&quot;&gt;the available boilerplate projects&lt;/a&gt;. Please don’t expect it to be super straightforward. Decoupled Drupal is quite far away from the popular JavaScript stacks in terms of developer-friendliness.&lt;/p&gt;

&lt;h3&gt;Kubernetes&lt;/h3&gt;
&lt;p&gt;Surprisingly, as part of my job at SystemSeed I had an opportunity to learn some basics of AWS, Kubernetes, Helm, Terraform and other hosting-related stuff. A huge benefit of running your own cluster is that you have unlimited flexibility on hosting level. Node.js, PHP, Go, Elasticsearch, Redis - everything can be dockerized and reused for both local development and production run.&lt;/p&gt;
&lt;p&gt;My daily routines include basic operations with deployments, pods and jobs. I would love to have them automated eventually so that I can focus on building new features rather than on running the same commands in terminal.&lt;/p&gt;
&lt;p&gt;To sum up, it turned out that Kubertenes isn’t as scary and complected as I thought. If you plan to touch it, I can recommend high level overview from our CTO: &lt;a href=&quot;https://www.youtube.com/watch?v=mHxRUzZbzO4&quot;&gt;“Kubernetes, KOPS &amp;amp; Helm”&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Semantic UI&lt;/h3&gt;
&lt;p&gt;The other day I was reviewing the latest State of JS report. I found it a bit naive that most of developers who work almost only and exclusively with JavaScript &lt;a href=&quot;https://2019.stateofjs.com/demographics/jobTitle&quot;&gt;consider themselves Full Stack developers&lt;/a&gt;. Full Stack is when you put Kubernetes and Semantic UI one by one in your tech list &lt;span&gt;😄&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;But back to my list. This year I had a chance to try Semantic UI and its &lt;a href=&quot;https://react.semantic-ui.com/&quot;&gt;React addon&lt;/a&gt;. It’s well documented, feature-rich and very developer-friendly library. At SystemSeed we used it for admin dashboard, but I can see its potential for other types of MVP.&lt;/p&gt;
&lt;p&gt;As a side note, I’m intrigued by the raise of Tailwind CSS framework. In some cases component-based frameworks like Bootstrap or Material don’t fit custom design requirements. It such cases Tailwind may be a good alternative.&lt;/p&gt;
&lt;h3&gt;Auth0 &amp;amp; Okta for user management&lt;/h3&gt;
&lt;p&gt;These are two very different identity access management tools that I worked with recently.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://auth0.com/&quot;&gt;Auth0&lt;/a&gt; has a generous free plan with powerful APIs for developers and No-Code features for startups. If you plan to scale, Auth0 offers a lot of advanced features on their paid tiers. I had only positive experience with this service and can recommend it to everyone who considers cloud-based solution for user management.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.okta.com/&quot;&gt;Okta&lt;/a&gt; positions itself as Enterprise Identity Standard. If you work with larger organizations then at some point you will face a need to integrate with Okta. It’s the opposite to Auth0 in terms of learning curve and developer-friendliness. It’s fine to work with though, and it seems to have a huge list of features that make Okta attractive for enterprises.&lt;/p&gt;
&lt;h3&gt;JAMStack&lt;/h3&gt;
&lt;p&gt;A few paragraphs above I made a joke about Full Stack Developers. That was a sad joke for me. In fact, frontend developers can develop and deliver entire projects without traditional “backend”. Platforms like Netlify or Zeit make it very easy to build professional websites on top of JAMStack. Developers spend more dev time building project-specific UIs rather then setting up backends and APIs.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;With free GitHub account they can host codebase and assets as well as set up project management workflow and CI.&lt;/li&gt;
&lt;li&gt;On a free Rollbar plan, they can have error monitoring and alerting.&lt;/li&gt;
&lt;li&gt;With Cloudflare they can have powerful CDN for great performance and Cloudflare Workers for running custom application logic without a need for a server, all for free.&lt;/li&gt;
&lt;li&gt;With FaunaDB, they can store and retrieve their data, without a need for a server, again, all for free.&lt;/li&gt;
&lt;li&gt;With Auth0, they can have secure login and user management, for free.&lt;/li&gt;
&lt;li&gt;With Algolia…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I guess you’ve got the idea: everything that is not specific to the business can be delegated to a cloud service at a lower price then developing and hosting in house (It’s not JAMStack-specific though, and can be applied to any stack).&lt;/p&gt;
&lt;p&gt;I’m curious if Full Stack in the State of JS report means an ability to set up appropriate third-party services and complementary NPM packages to get job done.&lt;/p&gt;
&lt;p&gt;In general, I’m optimistic about this approach regardless of complaints about risks, data ownership, poor architectures. Javascript tech stacks unleashed creativity of hundreds of thousands frontend developers who wanted to start building their own things.
As a next step, No-Code trend will allow non-techies to build complex applications without writing a single line of code. As developers, we may not like this trend but &lt;a href=&quot;https://webflow.com/nocodeconf&quot;&gt;it’s already there&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;React state management&lt;/h3&gt;
&lt;p&gt;React Hooks is one of those tech concepts that I found truly elegant and intuitive. Unfortunately, there was too much of unhealthy hype around them and around React state managers in general. I would prefer people to spend more time learning web standards and general programming practices rather then building yet another state manager for React.&lt;/p&gt;
&lt;h3&gt;React Native&lt;/h3&gt;
&lt;p&gt;It’s common to mention React Native when we list benefits of React over some other JavaScript frameworks. For me, one real benefit is that developers who already know React will learn React Native faster than Swift of Flutter. They still will need to learn specifics of app development very well, and read a decent amount of app-specific code, sometimes in Java or Objective-C.&lt;/p&gt;
&lt;p&gt;For web developers who already know React and want to start building native apps professionally, React Native is a great choice, but be prepared to work hard.&lt;/p&gt;
&lt;p&gt;Watch my overview of React Native for SystemSeed team &lt;a href=&quot;https://www.youtube.com/watch?v=HiSkdF3QMmc&quot;&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;h3&gt;Strong Customer Authentication&lt;/h3&gt;
&lt;p&gt;If you build web sites for EU, you already know about GDPR regulation. The next challenge is SCA, Strong Customer Authentication for payments. As far as I know, initial plan was to enforce the new standard in September 2019, but many European regulators postponed it until &lt;strong&gt;the end of next year&lt;/strong&gt;. One of online payment processors that was ready on time is Stripe. They released a new version of their API that is optimized for SCA with minimum amount of work for developers. I enjoyed working with their new API and as you may already guess I shared my experience with SystemSeed team: &lt;a href=&quot;https://www.youtube.com/watch?v=eLeYeJvBjJw&quot;&gt;watch it here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Tools&lt;/h3&gt;
&lt;p&gt;I’m not a computer geek, but I’m quite comfortable with terminal and can impress non-technical people who watch me pressing Ctrl + R all the time. Below are some tools that I use every day at work:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Macbook Pro 2016 &lt;a href=&quot;https://sun9-30.userapi.com/c850720/v850720206/94d38/w5rcY3Xvk-U.jpg&quot;&gt;mounted on an arm&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Firefox and Chrome (but I try to avoid Chrome)&lt;/li&gt;
&lt;li&gt;BetterTouchTool&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;PhpStorm&lt;/li&gt;
&lt;li&gt;VS Code&lt;/li&gt;
&lt;li&gt;iTerm&lt;/li&gt;
&lt;li&gt;Evernote&lt;/li&gt;
&lt;li&gt;1Password&lt;/li&gt;
&lt;li&gt;Wakatime (for personal purposes, I don’t report data from it to my employer)&lt;/li&gt;
&lt;li&gt;Pen and paper&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;What’s up next&lt;/h2&gt;
&lt;p&gt;I am a workaholic developer. I love working. I can forget about everything when I’m hooked by my next project, either routine or challenging. I know very well how &lt;a href=&quot;https://en.wikipedia.org/wiki/Flow_(psychology)&quot;&gt;“the flow state”&lt;/a&gt; feels (it’s amazing!), as well as how burnout and anxiety feel. I’m learning how to keep balance between work and rest, how to avoid perfectionism and do more with less.&lt;/p&gt;
&lt;p&gt;Programming languages and frameworks are great, but these days I’m more interested in human side of software development. How to build working environment where humans feel safe and empowered to unleash all their intelligence and creativity?&lt;/p&gt;
&lt;p&gt;In the past I thought that I must work hard so that later I would have time and resources for a creative and relaxed hobby. I thought I have to separate work and creativity. I don’t think so any more. We spend most of our active hours at work, so why wouldn’t we make them fun, creative and fulfilling?&lt;/p&gt;
&lt;p&gt;I wish a creative decade to all of us &lt;span&gt;🎄&lt;/span&gt;&lt;/p&gt;</content:encoded></item><item><title>Automated releases in a cross-language monorepo</title><link>https://kalabro.tech/monorepo-automated-releases/</link><guid isPermaLink="true">https://kalabro.tech/monorepo-automated-releases/</guid><description>Sharing my recent experience in automating software releases in a monorepo.</description><pubDate>Sat, 14 Sep 2019 10:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;On monorepos&lt;/h2&gt;
&lt;p&gt;Monorepo is a popular way of organizing code bases in large organizations like
Google, Facebook and Twitter. You can also find many open source projects that use a single git repository
to store and develop multiple sub-packages. Some examples are &lt;a href=&quot;https://github.com/babel/babel&quot;&gt;Babel&lt;/a&gt; and &lt;a href=&quot;https://github.com/laravel/framework&quot;&gt;Laravel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you are not familiar with the term “monorepo”, check out &lt;a href=&quot;https://www.youtube.com/watch?v=ZVsDA6GhKOU&quot;&gt;this 5 min video&lt;/a&gt; from Fabien Potencier, creator of Symfony framework.&lt;/p&gt;
&lt;p&gt;I personally have been using this technique for many years without knowing its name.
The idea is very simple: you store your &lt;code&gt;backend/&lt;/code&gt; and &lt;code&gt;frontend/&lt;/code&gt; folders in one
repository. This is a natural approach for full stack developers who usually
touch both folders on a daily basis. It is very handy to have entire project
codebase in one place when you develop and test the application. Below just a few benefits
that came to my mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fewer repositories to maintain on GitHub (less &lt;code&gt;git clone&lt;/code&gt; and &lt;code&gt;git pull&lt;/code&gt; commands to execute)&lt;/li&gt;
&lt;li&gt;Fewer steps to install full application on local machine&lt;/li&gt;
&lt;li&gt;Less CI configuration to spin up and test the entire project&lt;/li&gt;
&lt;li&gt;No mocking needed (all services are installed and available for testing without faking their APIs)&lt;/li&gt;
&lt;li&gt;Easier to deliver entire features that involve backend and frontend work&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On the other hand, this approach isn’t applicable to all teams and all organizations.
Read an article &lt;a href=&quot;http://yosefk.com/blog/dont-ask-if-a-monorepo-is-good-for-you-ask-if-youre-good-enough-for-a-monorepo.html&quot;&gt;“Don’t ask if a monorepo is good for you – ask if you’re good enough for a monorepo”&lt;/a&gt; to learn more about
monorepo disadvantages. It’s important to remember &lt;a href=&quot;https://haacked.com/archive/2007/07/17/the-eponymous-laws-of-software-development.aspx/#conways-law&quot;&gt;Conway’s law&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Organizations which design systems are constrained to produce designs which are copies of the communication structures of these organizations.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In case of SystemSeed, monorepos feel very natural because they reflect communication structures in a flat team of full stack developers.
For different kind of organizations, setting up a monorepo may require significant changes in development &amp;amp; collaboration practices, which is not always worth it.&lt;/p&gt;
&lt;h2&gt;Automated releases&lt;/h2&gt;
&lt;p&gt;Back to original topic for this post, let’s say we have a monorepo with two (or more)
separate packages written in different programming languages: PHP for backend and
Javascript for frontend. When changes are made in one of them, or in both, we want
the corresponding packages to be released in Packagist for PHP and in NPM for Javascript.&lt;/p&gt;
&lt;p&gt;Initially I prepared myself for writing a lot of bash scripts in our CI to make automated
releases for both packages work. It turned out that everything has already been written in Javascript (Atwood’s law in action), and all I needed is to install and configure a couple of packages.&lt;/p&gt;
&lt;h3&gt;Step 1: install and configure semantic-release&lt;/h3&gt;
&lt;p&gt;From project description:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes and publishing the package.&lt;/p&gt;
&lt;p&gt;This removes the immediate connection between human emotions and version numbers, strictly following the Semantic Versioning specification.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If all your code is written in Javascript, you can skip further reading and go ahead with &lt;a href=&quot;https://github.com/Updater/semantic-release-monorepo&quot;&gt;semantic-release-monorepo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In my case, I had to install semantic-release for both packages separately.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example package.json for PHP:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;name&quot;: &quot;@kalabro/mixed-monorepo-php&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;version&quot;: &quot;0.0.0-semantic-release&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;description&quot;: &quot;PHP subpackage from mixed-monorepo.&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;author&quot;: &quot;kalabro&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;license&quot;: &quot;MIT&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;repository&quot;: &quot;https://github.com/kalabro/mixed-monorepo-php&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;release&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;plugins&quot;: [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;@semantic-release/commit-analyzer&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;@semantic-release/release-notes-generator&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;semantic-release-slack-bot&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;notifyOnSuccess&quot;: true,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;notifyOnFail&quot;: true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;scripts&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;semantic-release&quot;: &quot;semantic-release&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;devDependencies&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;semantic-release&quot;: &quot;^15.13.18&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;semantic-release-slack-bot&quot;: &quot;^1.1.2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Example package.json for Javascript package:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;name&quot;: &quot;@kalabro/mixed-monorepo-js&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;version&quot;: &quot;0.0.0-semantic-release&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;description&quot;: &quot;JS subpackage from mixed-monorepo.&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;main&quot;: &quot;index.js&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;author&quot;: &quot;kalabro&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;license&quot;: &quot;MIT&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;repository&quot;: &quot;https://github.com/kalabro/mixed-monorepo-js&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;release&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;plugins&quot;: [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;@semantic-release/commit-analyzer&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;@semantic-release/release-notes-generator&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      &quot;@semantic-release/npm&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      [&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        &quot;semantic-release-slack-bot&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;notifyOnSuccess&quot;: true,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;          &quot;notifyOnFail&quot;: true&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;      ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ]&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;publishConfig&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;access&quot;: &quot;public&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;scripts&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;semantic-release&quot;: &quot;semantic-release&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  },&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;devDependencies&quot;: {&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;semantic-release&quot;: &quot;^15.13.18&quot;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    &quot;semantic-release-slack-bot&quot;: &quot;^1.1.2&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that Javascript version has “@semantic-release/npm” plugin enabled. This
is default semantic-release behavior that I switched off for PHP. When CI will call
semantic-release (later in this article), semantic-release will do the following:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Analyze all commit messages since previous release.&lt;/li&gt;
&lt;li&gt;Decide which version number to assign to the new release based on &lt;a href=&quot;https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines&quot;&gt;Angular Commit Message Conventions&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Add a new git tag for this version and push the tag to the remote origin (along with changelog notes).&lt;/li&gt;
&lt;li&gt;Release to NPM (optional, switched off for PHP).&lt;/li&gt;
&lt;li&gt;Notify the team in Slack.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Step 2: Publishing to Packagist&lt;/h3&gt;
&lt;p&gt;To add a new package to Packagist you need to link a repository with a valid composer.json file
in the repo root.&lt;/p&gt;
&lt;p&gt;&lt;img alt=&quot;packagist.org homepage&quot; loading=&quot;lazy&quot; width=&quot;2400&quot; height=&quot;1738&quot; src=&quot;/_astro/monorepo-automated-releases-packagist.CIszToUj_ZL80HD.webp&quot; /&gt;&lt;/p&gt;
&lt;p&gt;It means that I have to push PHP code from my monorepo
to a separate PHP-only repo for Packagist to be happy.&lt;/p&gt;
&lt;p&gt;To mirror monorepo to separate child repositories, I used &lt;a href=&quot;https://github.com/splitsh/lite&quot;&gt;splitsh-lite&lt;/a&gt;, the tool that is used by Laravel and Symfony for the same purpose. The tool finds commits that affected the package’s codebase and pushes them to another repository. Obviously, it preserves all commit information so that
semantic-release can decide what kind of release to create for each package.&lt;/p&gt;
&lt;h3&gt;Step 3: Configuring CI&lt;/h3&gt;
&lt;p&gt;In SystemSeed, we’ve been using Circle CI long before I joined the team in 2015.
I’ve never worked with other CI tools but they all seem to be quite similar.&lt;/p&gt;
&lt;p&gt;You can find example setup for Circle CI in a &lt;a href=&quot;https://github.com/kalabro/mixed-monorepo&quot;&gt;demo project&lt;/a&gt; on GitHub.&lt;/p&gt;
&lt;p&gt;CI setup contains two steps. First, on merging in master &lt;code&gt;splitsh-lite&lt;/code&gt; script is triggered.
It mirrors new commits (of any) to the corresponding child repos.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;See Circle CI config here: &lt;a href=&quot;https://github.com/kalabro/mixed-monorepo/blob/master/.circleci/config.yml#L13&quot;&gt;https://github.com/kalabro/mixed-monorepo/blob/master/.circleci/config.yml#L13&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;See &lt;code&gt;./bin/split.sh&lt;/code&gt; code here: &lt;a href=&quot;https://github.com/kalabro/mixed-monorepo/blob/master/bin/split.sh&quot;&gt;https://github.com/kalabro/mixed-monorepo/blob/master/bin/split.sh&lt;/a&gt; (inspired by &lt;a href=&quot;https://github.com/laravel/framework/blob/6.x/bin/split.sh&quot;&gt;the script in Laravel repo&lt;/a&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The second step is to trigger semantic-release for each child repo. Again, a simple Circle CI config
handles it on every push into child repo: &lt;a href=&quot;https://github.com/kalabro/mixed-monorepo/blob/master/js/.circleci/config.yml&quot;&gt;https://github.com/kalabro/mixed-monorepo/blob/master/js/.circleci/config.yml&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;Result&lt;/h3&gt;
&lt;p&gt;You can find full monorepo setup for a real project here: &lt;a href=&quot;https://github.com/systemseed/falcon&quot;&gt;https://github.com/systemseed/falcon&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Falcon repo includes Drupal distribution on backend (&lt;em&gt;falcon/ folder&lt;/em&gt;) and
complementary React frontend (&lt;em&gt;falconjs/ folder&lt;/em&gt;). The latter uses &lt;a href=&quot;https://yarnpkg.com/lang/en/docs/workspaces/&quot;&gt;yarn workspaces&lt;/a&gt;
inside to organize multiple JS packages &amp;amp; templates.&lt;/p&gt;
&lt;p&gt;All you need to start developing is to clone the repo and run &lt;strong&gt;make install&lt;/strong&gt;.
When you are done and your pull request is merged in master, CI will figure out
what to release and which version numbers to assign.&lt;/p&gt;
&lt;p&gt;Give it a try and let me know your thoughts!&lt;/p&gt;</content:encoded></item><item><title>Don&apos;t get lost in never ending learning curve</title><link>https://kalabro.tech/mental-health-full-stack-developers/</link><guid isPermaLink="true">https://kalabro.tech/mental-health-full-stack-developers/</guid><description>Maintaining mental health for Senior Software Engineers</description><pubDate>Sun, 17 Mar 2019 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Yesterday I spent a few hours learning &lt;a href=&quot;https://dev.to/danlebrero/kubernetes-explained-in-pictures-the-theme-park-analogy-3d99&quot;&gt;basics of Kubernetes&lt;/a&gt; and then another couple of
hours upgrading this blog from &lt;a href=&quot;https://github.com/gatsbyjs/gatsby/blob/v2/docs/docs/migrating-from-v1-to-v2.md&quot;&gt;GatsbyJS v1 to v2&lt;/a&gt;. The fact of
mentioning these two technologies in one sentence illustrates the state of web in 2019. The dream of Lego for web, where everyone can grab a container with any feature from authentication to ecommerce and easily connect to their projects, comes true with its own side effects: additional layers of complexity and dependency on many third party providers.&lt;/p&gt;
&lt;p&gt;As a result, we can see more and more specializing in the industry. There is a MySQL expert and there is a Webpack expert, and &lt;a href=&quot;https://overreacted.io/things-i-dont-know-as-of-2018/&quot;&gt;they barely have anything in common&lt;/a&gt;.
In my opinion, specialization is the best strategy for junior and mid-level developers.&lt;/p&gt;
&lt;p&gt;If you are Senior Developer or Tech Lead, or Software Architect, then you probably recall that your career path had multiple rounds of specializing on different technologies and tools within one domain. My own path started from
basic HTML &amp;amp; CSS back in 2004. Then I installed LAMP and learned a couple of &lt;code&gt;foreach&lt;/code&gt; tricks in PHP to avoid copy-pasting. 15 years later I find myself digging into Kubernetes stuff and it’s not the final destination for sure.&lt;/p&gt;
&lt;p&gt;The truth is that it is very easy to get stuck in another loop of never ending learning curve. Even worse, it’s easy to become demotivated and depressed when after so many years spent in the industry you feel that you left behind.&lt;/p&gt;
&lt;p&gt;I want to share a couple of things that help me to stay inspired and motivated to keep climbing the curve:&lt;/p&gt;
&lt;h3&gt;1. Focus on General knowledge&lt;/h3&gt;
&lt;p&gt;Instead of installing every hot new library and diving into implementation details I try to spend more time learning generic things such as Maths, Computer Science, &lt;a href=&quot;https://www.lullabot.com/articles/why-programmers-should-read-good-fiction&quot;&gt;fiction&lt;/a&gt;, etc. They help to focus on &lt;em&gt;understanding concepts&lt;/em&gt; over gathering facts. It’s fine to learn more narrow topics such as frameworks or libraries if you can abstract from immediate implementation and let your mind think why things built the way they built and which concepts underlie them.&lt;/p&gt;
&lt;h3&gt;2. Automated Testing&lt;/h3&gt;
&lt;p&gt;Often I feel uncomfortable working with new technologies and stacks because I
don’t trust them yet. They are strangers in the room and I don’t even recall their names, so how can I begin to trust them? The answer is damn simple: start writing tests from day 1!&lt;/p&gt;
&lt;p&gt;After working for a while on a large project where I couldn’t keep in mind all implementation details and review all committed code, I realized how calm and relaxed I am when new code is being merged. Thanks to the great team, and, first of all, to good tests coverage, you don’t need to worry that all the fancy dependencies will go crazy and shoot you in the foot.&lt;/p&gt;
&lt;p&gt;Unfortunately, there are not that many good learning resources about automated
testing so I decided to write my own blog post series about it. You are very welcome to follow me on Medium &lt;a href=&quot;https://medium.com/systemseed/testing-modern-web-apps-part-1-2e143f5bfaf4&quot;&gt;to check them out&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;P.S.&lt;/h3&gt;
&lt;p&gt;Obviously, it’s essential to maintain a healthy work/life balance and have coding-free retreats on a regular basis. When I’m stuck with something at work, in many cases I’m just tired. The silliest thing to do in such situation is to continue working or, even worse, to attempt to learn something new.&lt;/p&gt;
&lt;p&gt;Not so long ago, I started experimenting with my work day to reduce amount of time spent in front of computer. This is probably a topic for another post, hopefully before GatsbyJS v3 release &lt;span&gt;😊&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Thank you for reading and have an awesome ride in never ending learning curve!&lt;/p&gt;</content:encoded></item><item><title>Reading list: on technical leadership</title><link>https://kalabro.tech/reading-on-tech-lead/</link><guid isPermaLink="true">https://kalabro.tech/reading-on-tech-lead/</guid><description>I&apos;ve got a couple of great resources to share with those who eventually found themselves in a team lead / tech lead shoes...</description><pubDate>Sat, 04 Aug 2018 20:11:34 GMT</pubDate><content:encoded>&lt;p&gt;I’ve got a couple of great resources to share with those who eventually found themselves in a team lead / tech lead shoes (just like me).&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://lcamtuf.blogspot.com/2018/02/on-leadership.html&quot;&gt;&lt;strong&gt;Progressing from tech to leadership&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Great write-up from a security expert and experienced techie leader Michał Zalewski.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But first, let me start on a somewhat somber note: what nobody tells you is that one’s level on the leadership ladder tends to be inversely correlated with several measures of happiness. The reason is fairly simple: as you get more senior, a growing number of people will come to you expecting you to solve increasingly fuzzy and challenging problems - and you will no longer be patted on the back for doing so. This should not scare you away from such opportunities, but it definitely calls for a particular mindset: your motivation must come from within. Look beyond the fight-of-the-day; find satisfaction in seeing how far your teams have come over the years.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=hMz6QDURQOM&quot;&gt;&lt;strong&gt;The Critical Career Path Conversation&lt;/strong&gt; (video)&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.johnriviello.com/&quot;&gt;John Riviello&lt;/a&gt; shares his story from being a senior engineer, taking the managerial route and then back to an individual contributor position.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.codementor.io/npostolovski/8-tips-for-being-a-good-tech-lead-ke35g7em8&quot;&gt;&lt;strong&gt;8 Tips for Being a Good Tech Lead&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;In the best teams I’ve worked in, the tech lead role is a little like an invisible conch shell that gets passed around between team members throughout the hours, days, and weeks. One person often holds this conch shell most of the time, but other people also get the chance to hold the conch when it is appropriate. If you find yourself in the tech lead role, don’t be possessive of it. Recognize when it is time to pass the role to someone else, and when it is time to take the role back.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.freecodecamp.org/cognitive-bias-and-why-performance-management-is-so-hard-8852a1b874cd&quot;&gt;&lt;strong&gt;Cognitive Bias And Why Performance Management is So Hard&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Trying to motivate a person to do a task that they’re procrastinating on due to anxiety is likely to have the opposite effect — it makes the task more meaningful, and increases anxiety.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;These and other great articles appear in a great &lt;a href=&quot;https://softwareleadweekly.com/&quot;&gt;Software Lead&lt;/a&gt; newsletter.&lt;/p&gt;</content:encoded></item><item><title>Decode Alias and Union Types in Elm</title><link>https://kalabro.tech/decode-alias-union-types-in-elm/</link><guid isPermaLink="true">https://kalabro.tech/decode-alias-union-types-in-elm/</guid><description>I’m so exited to open this blog with a post about Elm, a functional programming language for building web frontend. As a user, I interact with Elm almost every day...</description><pubDate>Sun, 21 Jan 2018 18:58:34 GMT</pubDate><content:encoded>&lt;p&gt;I’m so exited to open this blog with a post about Elm, a functional programming language for building web frontend. As a user, I interact with Elm almost every day — we at SystemSeed use &lt;a href=&quot;https://www.pivotaltracker.com/blog/Elm-pivotal-tracker/&quot;&gt;Pivotal Tracker&lt;/a&gt; as a project management tool.&lt;/p&gt;
&lt;p&gt;As a developer, I started playing with Elm after a year of React experience and I found some of Elm concepts very easy to get started with, especially if you are familiar with Redux.&lt;/p&gt;
&lt;p&gt;Still, things like decoders are quite new to me and I recently spent some time reviewing &lt;a href=&quot;https://guide.elm-lang.org/interop/json.html&quot;&gt;the docs&lt;/a&gt; and &lt;a href=&quot;https://github.com/zwilias/elm-demystify-decoders&quot;&gt;demystifying decoders&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There are a lot of examples of how to decode JSON objects into Elm alias types. Let me start with yet another one and then enhance it to use union types.&lt;/p&gt;
&lt;h2&gt;Decoding into alias types&lt;/h2&gt;
&lt;p&gt;I’m going to decode the following piece of JSON from api.themoviedb.org into a &lt;code&gt;Movie&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;{&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;homepage&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;http://www.thegodfather.com/&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;id&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 238&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;imdb_id&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;tt0068646&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;original_language&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;en&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;original_title&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;The Godfather&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;overview&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;Spanning the years 1945 to 1955, a chronicle of the fictional Italian-American Corleone crime family...&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;popularity&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; 64.346383&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;release_date&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;1972-03-14&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;original_language&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;en&quot;&lt;/span&gt;&lt;span&gt;,&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;  &quot;title&quot;&lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; &quot;The Godfather&quot;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let’s take a look at &lt;code&gt;Movie&lt;/code&gt; alias type:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;type alias Movie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    { title &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; description &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; year &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; language &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are four simple string fields and that’s it, so it should be fairly easy to decode. Let’s pick up an appropriate mapping function &lt;a href=&quot;http://package.elm-lang.org/packages/elm-lang/core/5.1.1/Json-Decode#mapping&quot;&gt;&lt;code&gt;map4&lt;/code&gt;&lt;/a&gt; and write a decoder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; Decoder&lt;/span&gt;&lt;span&gt; Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Json&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Decode&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map4 Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;title&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;overview&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;release_date&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;original_language&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;map4&lt;/code&gt; takes a function and runs four decoders to pass as params to that function. In our case &lt;code&gt;map4&lt;/code&gt; will call &lt;code&gt;Movie&lt;/code&gt; counstructor and pass four decoded strings in the order which &lt;code&gt;Movie&lt;/code&gt; counstructor expects. That looks pretty good so far exept the &lt;code&gt;year&lt;/code&gt; field. I’d rather use integer for that. Let’s decode a string of format &lt;code&gt;YYYY-MM-DD&lt;/code&gt; from our JSON into an integer field instead:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;type alias Movie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    { title &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; description &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; year &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; language &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Below is an example solution for this task:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; Decoder&lt;/span&gt;&lt;span&gt; Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Json&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Decode&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map4 Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;title&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;overview&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;release_date&quot;&lt;/span&gt;&lt;span&gt; string &lt;/span&gt;&lt;span&gt;|&amp;gt;&lt;/span&gt;&lt;span&gt; andThen decodeYear)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;original_language&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;-- Takes a string in YYYY-MM-DD format and tries to decode YYYY into integer.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeYear&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Decoder&lt;/span&gt;&lt;span&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeYear&lt;/span&gt;&lt;span&gt; releaseDate &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    let&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        -- Get first 4 characters from the left side of a string&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        -- add pass them into toInt function which will return a Result.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        result &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; releaseDate &lt;/span&gt;&lt;span&gt;|&amp;gt;&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toInt&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    in&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        case &lt;/span&gt;&lt;span&gt;result &lt;/span&gt;&lt;span&gt;of&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Ok year &lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            succeed year&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Err error &lt;/span&gt;&lt;span&gt;-&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;            fail error&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;andThen&lt;/code&gt; in &lt;code&gt;string |&amp;gt; andThen decodeYear&lt;/code&gt; combines two decoders into one: first, decode JSON into a string and then call another decoder for that string.&lt;/p&gt;
&lt;p&gt;You can also delegate Result handling from &lt;code&gt;decodeYear&lt;/code&gt; function to &lt;code&gt;fromResult&lt;/code&gt; helper from Json.Extra library. You can read more about it &lt;a href=&quot;https://www.brianthicks.com/post/2017/01/13/create-custom-json-decoders-in-elm-018/#in-real-life-use-fromresult-from-json-decode-extra&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; Decoder&lt;/span&gt;&lt;span&gt; Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Json&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Decode&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map4 Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;title&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;overview&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;release_date&quot;&lt;/span&gt;&lt;span&gt; string &lt;/span&gt;&lt;span&gt;|&amp;gt;&lt;/span&gt;&lt;span&gt; andThen (decodeYear &lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; JsonExtra&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromResult))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;original_language&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;-- Takes a string in YYYY-MM-DD format and tries to parse YYYY into integer.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeYear&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Result&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeYear&lt;/span&gt;&lt;span&gt; releaseDate &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -- Get first 4 characters from the left side of a string&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    -- add pass them into toInt function which will return a Result.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;left &lt;/span&gt;&lt;span&gt;4&lt;/span&gt;&lt;span&gt; releaseDate &lt;/span&gt;&lt;span&gt;|&amp;gt;&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;toInt&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Cool! Time to play with union types.&lt;/p&gt;
&lt;h2&gt;Decoding into union types&lt;/h2&gt;
&lt;p&gt;Let’s introduce a new union type for the &lt;code&gt;language&lt;/code&gt; field. That field will differentiate English movies from others and also store language codes and original titles of foreign films so we can display them in a specific way if we want.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;type alias Movie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    { title &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; description &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; year &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Int&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    ,&lt;/span&gt;&lt;span&gt; language &lt;/span&gt;&lt;span&gt;:&lt;/span&gt;&lt;span&gt; Language&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    }&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;-- Language can be either English or Other.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;-- Other encapsulates language code and original title values.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;type Language&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    =&lt;/span&gt;&lt;span&gt; English&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    |&lt;/span&gt;&lt;span&gt; Other &lt;/span&gt;&lt;span&gt;Langcode&lt;/span&gt;&lt;span&gt; OriginalTitle&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;-- Langcode and OriginalTitle are just strings.&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;type alias Langcode&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;type alias OriginalTitle&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;span&gt; String&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;First, I’ll create a function which takes a language code and an original title and returns a new &lt;code&gt;Language&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;initLanguage&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; Langcode&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; OriginalTitle&lt;/span&gt;&lt;span&gt; -&amp;gt;&lt;/span&gt;&lt;span&gt; Language&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;initLanguage&lt;/span&gt;&lt;span&gt; langcode title &lt;/span&gt;&lt;span&gt;=&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    if &lt;/span&gt;&lt;span&gt;langcode &lt;/span&gt;&lt;span&gt;==&lt;/span&gt;&lt;span&gt; &quot;en&quot;&lt;/span&gt;&lt;span&gt; then&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        English&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    else&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        Other langcode title&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There is nothing to do with decoders yet. We’ve just prepared a universal “constructor” to initiate &lt;code&gt;Language&lt;/code&gt; from two passed params.&lt;/p&gt;
&lt;p&gt;Those two params should be decoded into strings first and then passed to &lt;code&gt;initLanguage&lt;/code&gt;. Sounds like &lt;code&gt;map2&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;decodeLanguage&lt;/span&gt;&lt;span&gt; :&lt;/span&gt;&lt;span&gt; Decoder&lt;/span&gt;&lt;span&gt; Language&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;decodeLanguage&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Json&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Decode&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map2 initLanguage&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;original_language&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;original_title&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, let’s call this custom decoder from our parent decoder:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span&gt;&lt;span&gt;decodeMovie&lt;/span&gt;&lt;span&gt; =&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;    Json&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;Decode&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;map4 Movie&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;title&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;overview&quot;&lt;/span&gt;&lt;span&gt; string)&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (field &lt;/span&gt;&lt;span&gt;&quot;release_date&quot;&lt;/span&gt;&lt;span&gt; string &lt;/span&gt;&lt;span&gt;|&amp;gt;&lt;/span&gt;&lt;span&gt; andThen (decodeYear &lt;/span&gt;&lt;span&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span&gt; JsonExtra&lt;/span&gt;&lt;span&gt;.&lt;/span&gt;&lt;span&gt;fromResult))&lt;/span&gt;&lt;/span&gt;
&lt;span&gt;&lt;span&gt;        (decodeLanguage)&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Instead of extracting data into a field directly in &lt;code&gt;map4&lt;/code&gt; function I passed a custom decoder which will process multiple fields by calling &lt;code&gt;map2&lt;/code&gt; and then return &lt;code&gt;Decoder Language&lt;/code&gt; which is what &lt;code&gt;map4&lt;/code&gt; expects in our case.&lt;/p&gt;
&lt;p&gt;Full code example is available here: &lt;a href=&quot;https://ellie-app.com/nQWbXjrTBa1/2&quot;&gt;https://ellie-app.com/nQWbXjrTBa1/2&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please contact me in Twitter if you’ve got any comment on that. So far thanks for reading and happy decoding!&lt;/p&gt;</content:encoded></item></channel></rss>