<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mihnea Simian</title>
    <description>The latest articles on DEV Community by Mihnea Simian (@mihneasim).</description>
    <link>https://dev.to/mihneasim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F889789%2F5422a0e6-6084-4b68-a890-aa6f90d4989e.jpg</url>
      <title>DEV Community: Mihnea Simian</title>
      <link>https://dev.to/mihneasim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mihneasim"/>
    <language>en</language>
    <item>
      <title>Constraints and creativity: Partial rollout feature without a server component</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Mon, 29 Sep 2025 20:08:48 +0000</pubDate>
      <link>https://dev.to/mihneasim/constraints-and-creativity-partial-rollout-feature-without-a-server-component-3lom</link>
      <guid>https://dev.to/mihneasim/constraints-and-creativity-partial-rollout-feature-without-a-server-component-3lom</guid>
      <description>&lt;p&gt;"I never castle" - &lt;em&gt;Tom&lt;/em&gt;, chess player&lt;/p&gt;

&lt;p&gt;"I never expand" - &lt;em&gt;printf&lt;/em&gt;, Starcraft pro-player&lt;/p&gt;

&lt;p&gt;Constraints lead to innovation. Without constrains, the road is paved and the best you can do is optimize and innovate on top of existing paradigms. That's how, without having the option to implement a proper server-side service component, I was forced to design a way to implement partial rollout on the client side.&lt;/p&gt;

&lt;p&gt;I teamed up with one of my colleagues and laid out the specs we wanted for our partial rollout feature: as a delivery squad, we wanted to give early access to a feature to a group of a limited amount of customers, so that we can monitor incidents while we increase the amount of customer that have access, or roll back the feature completely, in case of an unforeseen major failure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;allocate &lt;strong&gt;a configurable percentage&lt;/strong&gt; of total traffic that would experience the new feature - a percentage that we can change between 0 to 100, without redeploying the application&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;don't shuffle the users&lt;/strong&gt; between the groups on a given configuration. Allocation should be sticky, so that users don't see different features every time they log in&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;because of organizational constraints, we couldn't build any backend service components. We had to figure out a &lt;strong&gt;quick, good-enough solution, in the client side&lt;/strong&gt; code.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We were lucky enough to find some piece of customer data that's monotonic: unique and increasing - uniformly distributed. Once we had that, we were able to use it to distribute the individual users in a fixed amount of buckets (sharding), i.e. by modulo-operation. Imagine you have 200.000 users, which are allocated 200000 unique ID-s, integers, in consecutive sequence. You can choose to allocate them to 100 buckets, by computing their Modulo 100:&lt;/p&gt;

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

&lt;p&gt;We then found a problem with this design - for every new feature we wanted to partially roll out, it was always the same users that got to be targeted:&lt;/p&gt;

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

&lt;p&gt;If your user identifiers are not countable and uniformly distributed, then you will need to come up with an additional stateless transformation that would directly convert the identifiers to a monotonic sequence. If the hash function does not distribute the users evenly into the buckets, you'd risk having significantly more traffic in one or more of the buckets, and thus, the percentage you configure can be a bad underestimation or overestimation.&lt;/p&gt;

&lt;p&gt;The crux of this design is that it only works if the traffic is evenly distributed in the buckets, and you are comfortable having the frontend decide the configuration of your features or version of the features of your app.&lt;/p&gt;

&lt;p&gt;For more advanced designs, you'd want to include this in your load balancer and handle the allocation logic there. Then, the frontend app can request the feature configuration, which may change based on how the user session is assigned to the control groups of your new features. This approach is not only more powerful but also more secure, as you can verify the feature configuration on the server, preventing malicious users from manually accessing a feature.&lt;/p&gt;

&lt;p&gt;Creativity isn't always about revolutionary solutions. In this case, it was about a simple, easy-to-implement change in the frontend that helped us roll out gradually without much development effort.&lt;/p&gt;

</description>
      <category>sre</category>
      <category>frontend</category>
      <category>abtest</category>
      <category>development</category>
    </item>
    <item>
      <title>How I changed a team meeting ritual so that I can grow</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Tue, 02 Apr 2024 15:11:15 +0000</pubDate>
      <link>https://dev.to/mihneasim/how-i-changed-a-team-meeting-ritual-so-that-i-can-grow-4k7i</link>
      <guid>https://dev.to/mihneasim/how-i-changed-a-team-meeting-ritual-so-that-i-can-grow-4k7i</guid>
      <description>&lt;p&gt;Leaders evolve alongside their team's growth. The more the team adopts behaviours from their leader, the more space the leader has to take on new challenges and explore wider horizons. However, it's only now, when I've pushed myself to expand my scope, that I've learned how to facilitate these changes. I made a plan to clear my calendar and to-do list of tasks that my team can handle by April 1st. This way, starting from that date, I can concentrate on other projects in 2024..&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Once you're satisfied with a new process or ceremony that' you got it working well for your team, consider &lt;strong&gt;how much it depends on your involvement&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Your target is to lower that involvement to zero.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a previous article, I shared &lt;a href="https://dev.to/mihneasim/ive-lead-a-frontend-chapter-for-three-years-and-this-is-the-idea-im-most-proud-of-1ocp"&gt;how I created a ceremony&lt;/a&gt; for all Frontend chapter members to openly discuss and improve their frontend expertise and craftsmanship during a weekly "Frontend Open Office Hours". It was all hunky-dory until I realised how much the get-together relied on me to moderate, prepare the agenda, and conduct live presentations. This had to change - the frontends needed to self-organise so that I could step back from managing frontends exclusively and better mind my own development.&lt;/p&gt;

&lt;p&gt;Reflecting back to the learnings in group-coaching sessions, I realised I needed to design &lt;em&gt;a role&lt;/em&gt;. I called this new role &lt;em&gt;the Frontend Open Office Host&lt;/em&gt;. This role would be designed to include all the tasks I was doing:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Gather agenda&lt;/strong&gt; just before the meeting&lt;br&gt;&lt;br&gt;
If the host is unable to make a non-empty list of topics, the meeting is skipped until the next week. Cycle repeats.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Launch and &lt;strong&gt;Moderate the meeting&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pick the next host!&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
This is the part that keeps the ball rolling. Make sure the hosts does this at the 55-minute mark, as some discussion tend to bleed over the time limit. Which is fine, we want people to engage - but we also want all people present when we randomly choose the next host.&lt;br&gt;&lt;br&gt;
I particularly wanted to make this part fun - we ended up using a randomiser built by one of our frontends, as a frontend challenge - go &lt;a href="https://github-vv.github.io/survivor/"&gt;check it here&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Record the topics &amp;amp; references&lt;/strong&gt; in our "Frontend Open Office Hours" one-pager.&lt;br&gt;&lt;br&gt;
Always keep a public track of whom presented what. This helps us to jump back to the past presenters and topics, every time we need to remember something that was presented. It's also useful during mid-year or end-of-year review discussions to recognize those who have made significant contributions. Meeting logs don't lie!&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You know what happened? Suddenly, more and more diverse voices began to take the mic. Although the host's role was primarily organizational, to keep administrative responsibilities to one person, almost every time, the host also introduced a topic for discussion. It is true sometimes the meeting got delayed several weeks in a row - don't be shy and throw yourself some log to the fire to keep it running.&lt;/p&gt;

&lt;p&gt;This is just an example on how to move the needle towards self-organization - and it won't happen overnight, but the benefits are clear: a more engaged team, a culture of shared responsibility, and the freedom for leaders to explore new horizons. As I reflect on changes like these, I am reminded that the essence of leadership lies in empowering others to grow and lead. True leadership is about the power of letting go, trusting your team, and the incredible outcomes of collective growth.&lt;/p&gt;

</description>
      <category>leadership</category>
      <category>management</category>
      <category>productivity</category>
      <category>team</category>
    </item>
    <item>
      <title>Leading Remote: How to Handle Instant Messaging Distractions</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Wed, 31 Jan 2024 18:41:53 +0000</pubDate>
      <link>https://dev.to/mihneasim/remote-management-how-to-handle-instant-messaging-distractions-29mk</link>
      <guid>https://dev.to/mihneasim/remote-management-how-to-handle-instant-messaging-distractions-29mk</guid>
      <description>&lt;p&gt;There's an undeniable surge in services trying to improve communication inside organizations, once these have shifted to hybrid or remote working. While efforts are made having communication and interactions take place easier remotely, there is another side to the coin: employers that were already acting as a 'communications hub' have to become even more skilled at balancing individual time versus outside interruptions, since the 'interrupters' have received the super-power of instant messaging on Slack / Teams / Hangouts.&lt;/p&gt;

&lt;p&gt;Instant Push Notifications are a powerful tool. If you don't already do this, you can start by creating a "Work Focus mode" on your phone. Don't let random apps disturb you. If you're waiting for deliveries to your door, you can add delivery apps on your exception list, and enable receiving calls. Or simply put the phone in full-DND and only check on it during breaks. I'd argue the "Inbox Zero" habit should now be replaced by "Zero irrelevant push notifications"-mantra.&lt;/p&gt;

&lt;p&gt;However, blocking or delaying colleagues that are trying to reach you is not a part of the solution, it just postpones the problems and clusters the interruptions on your own terms. I'm not saying it's a bad approach, but you still want to lead the persons that are trying to reach you, and in a timely manner. Sometimes answering a team member or reading a comment just in time may save yourself a lot of trouble in the future. What you need is &lt;strong&gt;a systematic, leadership-oriented approach&lt;/strong&gt; by which you &lt;em&gt;elevate the quality and reduce the quantity&lt;/em&gt; of your incoming interruptions. So whenever somebody buzzes you, you know it's worth switching context.&lt;/p&gt;

&lt;p&gt;In 2021, as a Chapter Lead of 14 chapter members spread in 10 delivery squads in a large organization at full speed at leveraging Microsoft Teams, I had to find a way to cope with interruptions. It's true that leadership roles are mostly about communication, but &lt;strong&gt;structure is always preferred&lt;/strong&gt;. The following method is what I personally developed and at least one peer successfully used it; so if you too are struggling with being interrupted at work by instant messages or impromptu calls, this is something for you to try.&lt;/p&gt;

&lt;h2&gt;
  
  
  The LOG Method
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;L-O-G:&lt;/strong&gt; &lt;strong&gt;L&lt;/strong&gt;og, &lt;strong&gt;O&lt;/strong&gt;rganise, &lt;strong&gt;G&lt;/strong&gt;et &lt;em&gt;:chocolate-soft-serve-swirl-emoji:&lt;/em&gt; done&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1706725582145%2F3d789dab-34f1-4e92-bcd0-d75343121a71.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1706725582145%2F3d789dab-34f1-4e92-bcd0-d75343121a71.jpeg" alt="shelf with bookshelves"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Keep an instant messaging log, by writing down every time somebody starts up a convo or a call with you. You want to write who messaged you and why. I also label them "self-initiated" if I was the one to start the conversation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Log
&lt;/h3&gt;

&lt;p&gt;Make the habit of logging every conversation topic for 1-3 weeks. It helps keeping this file on your desktop, or open at all times. Although I'm a big fan of jotting down in markdown or in a structured data format (yml, json), I gave in and used a spreadsheet 'cause I always wanted to Excel at work 🥁.&lt;/p&gt;

&lt;p&gt;I group interruptions &lt;strong&gt;by day&lt;/strong&gt;, and always include &lt;strong&gt;who&lt;/strong&gt; interrupted and the &lt;strong&gt;reason&lt;/strong&gt; why.&lt;br&gt;&lt;br&gt;
Here's an example from mine, based on real data; persons and some details are made up.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Day&lt;/th&gt;
&lt;th&gt;Who&lt;/th&gt;
&lt;th&gt;Reason&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;31.01&lt;/td&gt;
&lt;td&gt;John&lt;/td&gt;
&lt;td&gt;self initiated: spotted something in his PR that was worth debating in the chapter meeting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Danny&lt;/td&gt;
&lt;td&gt;about our Edge browser support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Diddy&lt;/td&gt;
&lt;td&gt;about an old user story on browser support&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Joanne&lt;/td&gt;
&lt;td&gt;pulled me in a design meeting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Jerry&lt;/td&gt;
&lt;td&gt;shared news about that tech meetup I was interested in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;30.01&lt;/td&gt;
&lt;td&gt;Jade&lt;/td&gt;
&lt;td&gt;self initiated: on that promote of insurance product that got us unprepared&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Jordy&lt;/td&gt;
&lt;td&gt;on why we thought we had a "lite" version of change management for tiny changes - to be used for that insurance product&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;/td&gt;
&lt;td&gt;Jamila&lt;/td&gt;
&lt;td&gt;pulled in a meeting on planning promote of insurance product&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Step 2: Organise
&lt;/h3&gt;

&lt;p&gt;Once you have enough data, start labeling logged interruptions. The category labels will come to you :) don't worry for that. You'll see how the interruptions cluster around topics.&lt;/p&gt;

&lt;p&gt;Or don't label. Simply read them, one after another. Patterns will start talking to you.&lt;/p&gt;

&lt;p&gt;I'd ask you to extract the categories in a separate list, and sort them descending, by how much they generate noise in your Messaging app. But that's not the case for me. I simply could pin-point 2-3 big issues that were generating noise, straight away.&lt;/p&gt;

&lt;p&gt;For instance, if we had documented our browser support list and shared that with QA chapter, my 31st of January would have had 2 less interruptions. Not to mention 30th of January was a wreck simply because somebody in my team had misinfo on the change management process.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Get it done - the action items
&lt;/h3&gt;

&lt;p&gt;For each category, it's you, the tech leader, that needs to come up with a plan to make your colleagues more autonomous and require your assistance less frequently. For me, that meant walking all of my chapter through change management process in all its intricacies, so at least they're aware of its steps and reasoning behind it. And made sure we have clear, up to date docs on the org wiki on what devices and browsers we support. At least these two shouldn't generate noise anymore in my Teams app.&lt;/p&gt;

&lt;p&gt;In closing, there's no silver bullet for managing interruptions - it depends on the culture of the team, on the nature of your team's priorities and how good you can cope with context switch. When reaching for my Teams window, I prioritise my same reporting line peers (my &lt;em&gt;first&lt;/em&gt; team), my direct reports and my manager. They should always hear back from me, &lt;strong&gt;almost immediately&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In large organisations, information overload is practically unavoidable: you have to turn off some channels to cope with it. If the info were important, it would eventually swing back to you. But as a leader, you are responsible for how you handle instant messaging and ad-hoc call interactions.&lt;/p&gt;

</description>
      <category>management</category>
      <category>leadership</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Rapidly boost code review efficiency for sizeable distributed teams</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Sat, 20 Jan 2024 15:43:02 +0000</pubDate>
      <link>https://dev.to/mihneasim/rapidly-boost-code-review-efficiency-for-sizeable-distributed-teams-mli</link>
      <guid>https://dev.to/mihneasim/rapidly-boost-code-review-efficiency-for-sizeable-distributed-teams-mli</guid>
      <description>&lt;p&gt;Not surprisingly, there's already a lot of literature on what makes a good Code Review - also known as &lt;em&gt;Merge Request&lt;/em&gt; or &lt;em&gt;Pull Request&lt;/em&gt;; e.g. "What to Look for in a Code Review" by Trisha Gee. &lt;em&gt;Code Review&lt;/em&gt; can also be found as a part of a technical interview.&lt;/p&gt;

&lt;p&gt;However, what I want to focus on is the process of code review in its entirety that takes part in one or more teams - typically split into the following parts: the creation of the CR request, the actual act of giving feedback by one or more reviewers, the subsequent amendments as a result of applying the feedback and asking for a subsequent review and finally, closing the Code Review either through merging the changes into the target branch or abandoning the changes.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1745390144679530890-405" src="https://platform.twitter.com/embed/Tweet.html?id=1745390144679530890"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1745390144679530890-405');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1745390144679530890&amp;amp;theme=dark"
  }



 &lt;/p&gt;

&lt;p&gt;Trouble is, once you have some sort of &lt;strong&gt;Code Review process guidelines&lt;/strong&gt; in place, how do you get large teams to learn from these guidelines and change their behaviour during the Code review process accordingly? Yes, I know, I just stated pretty much the whole mission of technical leadership. Creating comprehensive guidelines on all of the steps of the code review process, for both actors - &lt;em&gt;code author&lt;/em&gt; and &lt;em&gt;reviewer -&lt;/em&gt; is a good start, but definitely not enough in order to yield results.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Only a few will read the guidelines&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The ones who do, will forget most of the details, without actively practicing. A few things will stick, depending on what each individual is prone to remember, and it can work as a "go-to" place for beginners. Still, as time passes, folks will forget they exist.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;you can link them in the Code Review template; yet again, do not expect too many people to click and skim through them. Clicking and opening a new page from a CR is an effort most won't take.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A &lt;strong&gt;Code Review template&lt;/strong&gt; has better odds to yield results, if well tailored!
&lt;/h2&gt;

&lt;p&gt;There's a good read on templates &lt;a href="https://dev.to/opensauced/how-to-create-a-good-pull-request-template-and-why-you-should-add-gifs-4i0l"&gt;here&lt;/a&gt;, mentioning one example &lt;a href="https://github.com/forem/forem/blob/main/.github/PULL_REQUEST_TEMPLATE.md" rel="noopener noreferrer"&gt;here&lt;/a&gt; and another &lt;a href="https://github.com/open-sauced/.github/blob/main/.github/PULL_REQUEST_TEMPLATE.md" rel="noopener noreferrer"&gt;here&lt;/a&gt;. I won't share with you yet another template, but I'd like to walk you through the most important bits when designing it for your team. The purpose of the template is three-folded:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;👍 to inflict the &lt;strong&gt;good habits&lt;/strong&gt; you listed down in the detailed guidelines that no-one reads&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;✌️ to as &lt;strong&gt;many people&lt;/strong&gt; as possible&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;👌 on the &lt;strong&gt;long term&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CR template is the default free-text body of the Code Review. Therefore, it is probably the &lt;em&gt;most precious and "expensive" advertising place amongst engineers in your org&lt;/em&gt;, so choose your words wisely, and don't overdo it. Keep it short and efficient. Give the authors the choice not to fill-in the template, instead erase it and do their own thing in the free-text area. I chose to mention that upfront, in the template.&lt;/p&gt;

&lt;h3&gt;
  
  
  Author should be reminded about creating the best possible experience for the reviewer
&lt;/h3&gt;

&lt;p&gt;The body should include any non-obvious reason &lt;strong&gt;what the code change is about&lt;/strong&gt;, &lt;strong&gt;how&lt;/strong&gt; it tries to achieve that and &lt;strong&gt;why&lt;/strong&gt;. If the change is one commit with a good enough commit message, then fine, just point to it. I've heard engineers say "but I am already required to link a workitem on my backlog". I don't believe that's enough: we all know the User Story is not about the "codez" so much as the acceptance criteria and the business request; e.g. it won't mention the reason why the code author moved one class from one package to another. That's for the author to explain in the CR. And few reviewers will actually open and read the workitem to gain context (kudos to you if you do!).&lt;/p&gt;

&lt;p&gt;The Code Change should be &lt;em&gt;as final as possible&lt;/em&gt;. Don't submit code for review that's not production-ready - unless you're asking for a quick feedback, which is totally fine, but a different process. To check upon this, in my team's template we're asking the author to write exactly &lt;strong&gt;how the change was tested&lt;/strong&gt;. Manually, with fabricated inputs? Unit-tested? End to end? On a feature-testing build? Which one?&lt;/p&gt;

&lt;h3&gt;
  
  
  Reviewer should be reminded what's important to touch upon
&lt;/h3&gt;

&lt;p&gt;And of course, to be kind 😊. Although I haven't seen this anywhere else, we chose to include a short &lt;strong&gt;checklist for the reviewer&lt;/strong&gt;, as a &lt;em&gt;read-only section&lt;/em&gt; in the template. The checklist will vary heavily on the nature of the project, so each technical lead or manager of a delivery team should have a strong say on what should be included here.&lt;/p&gt;

&lt;h3&gt;
  
  
  Make it fun
&lt;/h3&gt;

&lt;p&gt;Or create some different intrinsic drive for both the author and the reviewer to put in the effort - don't make it sound like another chore. Ask for some creative input. Ask how they felt coding that. Occasionally publicly praise great Code Reviews, pointing to what made it stand out. Don't force it, pick genuinely good code review requests, or code reviews. I've seen people include before&amp;amp;after screenshots, performance metrics, or JavaScript bundle sizes comparisons.&lt;/p&gt;

&lt;h2&gt;
  
  
  Success indicator?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1705765447603%2F8c69474a-0f6d-4cc5-b1be-6cea1f007497.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.hashnode.com%2Fres%2Fhashnode%2Fimage%2Fupload%2Fv1705765447603%2F8c69474a-0f6d-4cc5-b1be-6cea1f007497.jpeg" alt="A lot of gauges"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When we started this out with multiple teams in my org, I received an interesting question: &lt;em&gt;How would we tell the template was successful? What would this metric be?&lt;/em&gt;&lt;br&gt;&lt;br&gt;
I would like to address this question in a separate follow-up post. Reviewing is not quantifiable. It's all up to professional judgement. What we would need to do is sample Code Reviews before and after using the template, and subjectively judge how much it made a difference.&lt;/p&gt;

</description>
      <category>codereview</category>
      <category>leadership</category>
      <category>management</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Revojs: How a Local Conference in 🇷🇴 Romania turned into a Networking Gold Mine</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Mon, 11 Dec 2023 12:52:36 +0000</pubDate>
      <link>https://dev.to/mihneasim/revojs-how-a-local-conference-in-romania-turned-into-a-networking-gold-mine-3eio</link>
      <guid>https://dev.to/mihneasim/revojs-how-a-local-conference-in-romania-turned-into-a-networking-gold-mine-3eio</guid>
      <description>&lt;p&gt;Two large frontend events are happening in Romania each year, and one of them is &lt;strong&gt;revojs&lt;/strong&gt; in Timisoara, which I attended for both of their on-site editions, that is October 2019 and October 2023.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Talks
&lt;/h2&gt;

&lt;p&gt;Let's jump right in, one by one. Note - my notes are written based on my memory of the presentation. Later I saw they were published on YouTube. Expect discrepencies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tug of War – Pushing and Pulling In JavaScript by Ben Lesh
&lt;/h3&gt;

&lt;p&gt;Ben is best known for his involvement in writing RxJS, but also a dad of three, living in Texas. He touched upon the topic of Signals with a creative approach, the one of data pull and pushing: &lt;em&gt;"Each line of code either pulls or pushes"&lt;/em&gt;. He surprised us by creating a set of logical operations which represented syntactical transformations of Promises and Observables by the "pull or push"-pattern, which he then applied to model Signals after the same pattern - proving Signals are not, in essence, much more different than Observables.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/JbL_kqTZAc4"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  There Is No Such Thing as a 'Generic' by Matt Pocock
&lt;/h3&gt;

&lt;p&gt;Matt is best known for his Typescript course called Total Typescript. &lt;em&gt;"Generic is overloaded"&lt;/em&gt;: There is no such thing as a &lt;em&gt;Generic&lt;/em&gt; (noun) because &lt;em&gt;generic&lt;/em&gt; is an adjective, and it is used in constructs such as "generic functions" or "generic types". While the generic types have at least one parameter (type parameter), generic functions don't require type arguments, because they infer (resolve) the type.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/le5ciL1T7Hk"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Type-Safe Style Systems: The Future of CSS by Josh Goldberg, selected from ✍️ CFP
&lt;/h3&gt;

&lt;p&gt;CART: Convenient. Assistable. Refactorable. Themeable. (Performant).&lt;br&gt;&lt;br&gt;
We were presented with possible futures of CSS - circling around CSS modularizations, "themeable-ities" and developer experience while writing and organizing styles. I see I jotted down "@vanilla-extract/" and chackra-ui. Oh, and "squiglies".&lt;br&gt;&lt;br&gt;
Josh couldn't find his favourite button-down shirt because his luggage chose a different flight. Luckily he got that back for the next day, and he was the one to volunteer (I presume) for a second talk standing in for a speaker that couldn't make it to the conference anymore.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/XMn9JnPH9ic"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  New CSS Features You Can Use Today by Rachel Andrew
&lt;/h3&gt;

&lt;p&gt;Rachel is Content Lead for Chrome DevRel at Google, and yeah, you could tell she's a professional tech writer; I'm just reading on her website that she has authored or co-authored more than 20 books! I love how articulate she is, providing all the right info for the right purpose on her website.&lt;br&gt;&lt;br&gt;
But now back to her presentation. We got a primer on CSS latest standards adopted or soon to be adopted by browsers: sizing units based on viewport sizes (svw/svh, lvw/lvh, dvw/dvh), :focus-visible ("&lt;em&gt;browser: 'is focus ring required?'"&lt;/em&gt;), Cascade Layers, @layer framework, layout, utilities, container queries, range operator for media queries, "High Definition CSS Color Guide", color-mix, gradient.style, :not(:has(img)), @property (type, initial - fallback), Web Platform Baseline.&lt;br&gt;&lt;br&gt;
Never have I thought I'd write down so many notes on a CSS presentation.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/dUz72A96qqg"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Understanding Rendering Patterns by Atila Fassina, selected from ✍️ CFP
&lt;/h3&gt;

&lt;p&gt;Atila learns Rust, was born in Brazil and lives in Berlin. This talk was a walkthrough on rendering patterns - including a live demo sampling a performance optimization in reactivity based on signals (hope I don't mix up). My doodles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;Abstract the DOM -&amp;gt; batch changes -&amp;gt; Reconcile&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;prop drilling&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;"tide" vs "wave" - the tide raises everyone, as opposed to the wave that only raises a subset&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/ATXgJR1H7Cs"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Demystifying Web Performance Tooling by Anna Migas
&lt;/h3&gt;

&lt;p&gt;When you think you saw and read everything you could on web performance, then there's this presentation that can very well serve as a performance audit starting point. My doodles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Load web performance&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Runtime web performance - jank, code splitting, animation optimization&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;em&gt;Perceived web performance - Laboratory Data versus Field Data&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;em&gt;PageSpeed Insights, Webpack, Web Vitals extension, devTools: Network, Performance, Lighthouse.&lt;br&gt;&lt;br&gt;
Lighthouse: paint flashes, Layout Borders, Rendering tab -&amp;gt; use a different Chrome Profile&lt;br&gt;&lt;br&gt;
Network tab: Priority column&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Time to first byte (waiting for the server to respond). SpeedCurve, Calibre&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/X3PKBYmbTkU"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  No-BS SEO for web developers by Martin Splitt
&lt;/h3&gt;

&lt;p&gt;Martin put on a show. He made up (I think?) a website trying to sell toasters, in two flavours: the no-go one, and the SEO optimized. We had a good laugh since the &lt;em&gt;joke&lt;/em&gt; was the brutal truth for many online businesses.&lt;br&gt;&lt;br&gt;
I appreciate how Martin creates his GIF-s out of his personal video content - and avoids any comments on licensing - I do the same Martin, with my image content. My doodles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;content, strategy, technology&lt;br&gt;&lt;br&gt;
"protoduction", "build an aeroplane while in flight"&lt;br&gt;&lt;br&gt;
a fly on the wall of a company&lt;br&gt;&lt;br&gt;
efficient &amp;amp; no sense of humour&lt;/em&gt; (loved this joke - how many Germans do you need to change a💡? One. Because..)*&lt;br&gt;&lt;br&gt;
evergreen, GoogleBot, crawl budget*&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/xgyvh9TOdYM"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Security by(e) Design? by Benedek Gagyi, selected from ✍️ CFP
&lt;/h3&gt;

&lt;p&gt;This talk draws attention to balancing web security and UX decisions. My doodles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;tea brewing, gongfu&lt;br&gt;&lt;br&gt;
Devs &amp;lt;-&amp;gt; UX &amp;lt;-&amp;gt; Security&lt;br&gt;&lt;br&gt;
Credentials API, Web OTP API, WebAuthn -&amp;gt; Passkeys&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/O8LPgLTxKxk"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  You Could Lint More by Josh Goldberg
&lt;/h3&gt;

&lt;p&gt;Josh, previously selected through CFP, stepped in to hold this second talk as a replacement for a speaker on the agenda who couldn't make it to Timisoara because of personal reasons. The title is spot-on: indeed, es-lint is a gold mine for teams. My doodles:&lt;br&gt;&lt;br&gt;
&lt;code&gt;--max-warnings&lt;/code&gt; &lt;em&gt;- create a gate of a maximum number of warnings allowed in the CI pipeline. eslint-plugin-deprecated, eslint-comments, eslint-plugin-jsdoc, eslint-plugin-markdown, eslint-plugin-perfectionist, eslint-plugin-regexp regexp create-typescript-app, warp - terminal, vitest, pnpm&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/voYSdj3Xqvc"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  The Ethical Choice by Alex Moldovan, selected from ✍️ CFP
&lt;/h3&gt;

&lt;p&gt;This goes beyond accessibility or UX: what choice does it &lt;em&gt;feel&lt;/em&gt; to be good or bad for the interest of the user when designing web experiences? We all know the annoying tiny "unsubscribe" links lacking contrast. Or the "opt-in" default selection. Yeap, those. I'm happy somebody framed this topic in a talk.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/qGjJ6-xNfM0"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Have You Heard the Joke About Async Debugging? I Promise It Is Good. by Jay Phelps
&lt;/h3&gt;

&lt;p&gt;Async issues are the worst! Not to brag, but I spotted the one in the talk on time. Jay was top of the game on teaching - he led you in solving the mysterious bug by yourself. I can't wait to show this talk to my team. My doodles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;"input" event - including Paste&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;request coming back out of order&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;typescript-eslint/return-await: "error"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/YOxgYrS4d8E"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Breaking Down JavaScript Complexities With Generative Art by Ritvi Mishra, selected from ✍️ CFP
&lt;/h3&gt;

&lt;p&gt;How many of you are visual learners? Ritvi showed us how one can learn Javascript as their first programming language by coding visualisations: such as visually describing the steps in repetitive structures or the call stack.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/MQ1slSVl2tE"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Node.js in 2023 – What’s New in the Node.js Native Test Runner by Erick Wendel, selected from ✍️ CFP
&lt;/h3&gt;

&lt;p&gt;I have to admit that this talk stretched my Javascript knowledge and attention. Erick is a high performing professional, contributing to nodejs's native test runner. Kudos for an enjoyable in-depth walk-through of such a difficult topic. My doodles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;v-test&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;TAP - protocol&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;dot; spec; junit; lcov&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;test sharding &amp;amp; concurrency&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;why-is-node-running&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/q3OQz5E1OpI"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Testing Your Testing Strategy by Trent Willis
&lt;/h3&gt;

&lt;p&gt;I empathised a lot with this topic: what types of testing and how much testing do you need? How do you know "&lt;em&gt;you're good&lt;/em&gt;" or "&lt;em&gt;yikes, too many tests to maintain, are they really paying off..&lt;/em&gt;"? My doodles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;The value of testing is in quality, not in quantity&lt;/em&gt;&lt;br&gt;&lt;br&gt;
*Optimize invested time versus confidence. The trouble is - confidence can't be quantified&lt;br&gt;&lt;br&gt;
&lt;em&gt;[*noti.st/trentmwillis&lt;/em&gt;](&lt;a href="http://noti.st/trentmwillis"&gt;http://noti.st/trentmwillis&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/kEkMqppoyHA"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Requiem for APIs – The Evolution of Web Development by Ciprian Caba
&lt;/h3&gt;

&lt;p&gt;Ciprian created a sort of "time-lapse" for web development, showing us how the data rendering into the presentation layer has circled back from server to client to server, and pointing out API-s can get obsolete, once we use the full abilities of the new frameworks that can simply access the data model directly, on the server side.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/bmtW_IT63P4"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h3&gt;
  
  
  Beyond the Web of Today by Kenneth Rohde Christiansen
&lt;/h3&gt;

&lt;p&gt;I had no idea about all the work involved to better support high-level API-s from the producers of hardware processing units. We're talking hardware that can speed up software related to (but not limited to) computer vision: blurring background, virtual background, eye-following, real-time visual filters, as well as anything that involves tensor calculus &amp;amp; whatnot. A hard subject. My dribbles:&lt;br&gt;&lt;br&gt;
&lt;em&gt;Project Fugu&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;Web Codecs&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;WebGPU, NPU / TPU, Web Neural Network API (Web NN)&lt;/em&gt;&lt;br&gt;&lt;br&gt;
&lt;em&gt;ONNXM, MediaPipe, OpenCV.js&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Vx-dlSUx18Y"&gt;
&lt;/iframe&gt;
 &lt;/p&gt;
&lt;h2&gt;
  
  
  The Vibes
&lt;/h2&gt;

&lt;p&gt;I can't thank the community of professionals in Timisoara enough for making &lt;strong&gt;revojs&lt;/strong&gt; happen. I know it isn't easy. It takes time, energy, commitment, lots of helping hands, and sponsors (and trust me they do need a lot of sponsorships for such a scale of an event). The thing is - their commitment and their helping hands are something money can't buy for a conference to take place - and that's what makes revojs so special.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1714239446269280344-284" src="https://platform.twitter.com/embed/Tweet.html?id=1714239446269280344"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1714239446269280344-284');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1714239446269280344&amp;amp;theme=dark"
  }



 &lt;/p&gt;

&lt;p&gt;Most of the participants are part of the local community. Both of the times I travelled by myself to the conference and made friends on the spot. This time, however, I couldn't see anyone familiar at the after-beer outdoorsy party, and I was fortunate enough to bump into Jay while ordering drinks and, long story short, I ended up having a great time drinking and chatting with all the speakers at the party, for hours. I even realised I had been walking very close to Matt's home address in Oxford when attending RenderConf 2016. Such a small world, isn't it?&lt;/p&gt;

&lt;p&gt;Who would have imagined I would one day have a drink with Matt and talk about that conference in his hometown? Can't wait to see what the next revojs has in store.&lt;/p&gt;

&lt;p&gt;&lt;iframe class="tweet-embed" id="tweet-1710364519208251625-636" src="https://platform.twitter.com/embed/Tweet.html?id=1710364519208251625"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1710364519208251625-636');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1710364519208251625&amp;amp;theme=dark"
  }



&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>conferences</category>
      <category>javascript</category>
      <category>networking</category>
    </item>
    <item>
      <title>Hyrum's law in modern frontend</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Tue, 30 May 2023 21:38:02 +0000</pubDate>
      <link>https://dev.to/mihneasim/hyrums-law-in-modern-frontend-1ma5</link>
      <guid>https://dev.to/mihneasim/hyrums-law-in-modern-frontend-1ma5</guid>
      <description>&lt;p&gt;The best professional books for you are the books that are revealing situational problems that you will encounter in your engineering journeys. I had the fortune to read about Hyrum's law in &lt;a href="https://www.google.ro/books/edition/Software_Engineering_at_Google/V3TTDwAAQBAJ"&gt;Software Engineering at Google: Lessons Learned From Programming Over Time&lt;/a&gt; (Great one!) and see that law happening magically just before my eyes, in a team near me.&lt;/p&gt;

&lt;p&gt;The law says that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;With a sufficient number of users of an API, it does not matter what you promise in the contract: all observable behaviours of your system will be depended on by somebody&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;One colleague (desperately) needed to access a couple of properties of a web component that was developed and maintained by a different team, but consumed in his own micro frontend. For the simplicity of the example, let's consider the default web component generated by OpenWC's npm generator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AppMain&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;LitElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="nx"&gt;properties&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;header&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;String&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
   &lt;span class="nf"&gt;render&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="s2"&gt;`
      &amp;lt;main&amp;gt;
        &amp;lt;h1&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;header&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/h1&amp;gt;
       ....
     `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Consider you'd be consuming this component in your template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;main&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/app-main&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And you, as a consumer, imagine yourself not knowing the implementation of the component, but needing to access the data rendered through the means of the &lt;code&gt;header&lt;/code&gt; property. You'd probably select the element in DevTools, then jump to Console, type &lt;code&gt;$0.&lt;/code&gt; and see what properties pop up. That's the exact process one colleague followed and ended up using the &lt;em&gt;hidden&lt;/em&gt; &lt;em&gt;dunder&lt;/em&gt; property (double underscore property) - the equivalent &lt;code&gt;$0.__header&lt;/code&gt; in our example.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lit's quirks
&lt;/h2&gt;

&lt;p&gt;So what's up with lit shadowing any &lt;code&gt;.property&lt;/code&gt; in a &lt;code&gt;.__property&lt;/code&gt;? Why is there a property called &lt;code&gt;__header&lt;/code&gt; with, surprisingly-not-so-surprisingly, the same value as &lt;code&gt;header&lt;/code&gt; property? Well, we've run into an implementation detail that at no point was intended to be used by component consumers, or any developer building web components on top of lit. But since I can't leave you wondering, lit's actual component properties are setters and getters, whilst the true value is stored in this hidden dunder property. By the use of this wrapping, at any point, lit can detect when the setter is writing something different than what it's already stored so that the rendering cycle, as well as update hooks are triggered only then. Simple and effective!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fun, hackish experiment: If you do set a value for __header, it won't trigger the render process, since you're bypassing lit's setter, so the template will not update. If you then do set the exact same value through the &lt;em&gt;header&lt;/em&gt; property, again the render cycle will be skipped, because it would be compared against the value in __&lt;em&gt;header&lt;/em&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftoc282e29aliiasokdgg.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftoc282e29aliiasokdgg.gif" alt="Animation showing hidden lit element properties called accessors or descriptors" width="600" height="335"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Advanced Deep Dive
&lt;/h3&gt;

&lt;p&gt;If you reaaaally want to see the bottom of what I just explained, then head to lit-element's &lt;a href="https://github.com/lit/lit-element/blob/v2.4.0/src/lib/updating-element.ts#L329"&gt;source code&lt;/a&gt;. What we call properties, are actually called accessors or descriptors in lit, and one can implement and configure a custom accessor, should someone need a different one, for a given property, on a given component class. As far as I can see, the property itself, created on the prototype, is an &lt;em&gt;accessor&lt;/em&gt;, while the assigned value is called a &lt;em&gt;property&lt;/em&gt; &lt;em&gt;descriptor&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nf"&gt;createProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;PropertyDeclaration&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;defaultPropertyDeclaration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Note, since this can be called by the `@property` decorator which&lt;/span&gt;
    &lt;span class="c1"&gt;// is called before `finalize`, we ensure storage exists for property&lt;/span&gt;
    &lt;span class="c1"&gt;// metadata.&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;_ensureClassProperties&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;_classProperties&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// Do not generate an accessor if the prototype already has one, since&lt;/span&gt;
    &lt;span class="c1"&gt;// it would be lost otherwise and that would never be the user's intention;&lt;/span&gt;
    &lt;span class="c1"&gt;// Instead, we expect users to call `requestUpdate` themselves from&lt;/span&gt;
    &lt;span class="c1"&gt;// user-defined accessors. Note that if the super has an accessor we will&lt;/span&gt;
    &lt;span class="c1"&gt;// still overwrite it&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;noAccessor&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hasOwnProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;symbol&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nc"&gt;Symbol&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`__&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;descriptor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getPropertyDescriptor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;descriptor&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;undefined&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nb"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;defineProperty&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;descriptor&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  But what about Hyrum's law?
&lt;/h2&gt;

&lt;p&gt;Lit dunder properties were never meant to be used. However, since they're observable, and usable, voilà.&lt;/p&gt;

&lt;p&gt;Strongly typed, mature, compiled, object oriented programming languages like C++ or Java employ the use of &lt;em&gt;Access Modifiers&lt;/em&gt;, offering developers the possibility to precisely define which members of a class can be &lt;em&gt;used&lt;/em&gt; (depending on its type, you can read it, set it, execute it etc.). All you need is the following cheatsheet:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kprehws6l3agtxo7vpp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6kprehws6l3agtxo7vpp.png" alt="Access modifiers in Java" width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Typescript uses access modifiers as presented before, but the concept is called &lt;strong&gt;Member Visibility&lt;/strong&gt;, and the list is shorter, only three - private, protected, public - where &lt;em&gt;public&lt;/em&gt; is the default and no sane person specifies it explicitly in code. There's no need for "default", as Typescript does not have such a strong notion as &lt;em&gt;packages&lt;/em&gt; in C#/Java. Moreover, as stated in their docs,&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Like other aspects of TypeScript’s type system, private and protected are only enforced during type checking.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Javascript itself didn't have any encapsulation, until recently. It's called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Private_class_fields"&gt;Private class fields&lt;/a&gt; and .. you guessed it, it allows you to explicitly prevent your consumers from directly accessing specified members of your class.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Class fields are &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Public_class_fields"&gt;public&lt;/a&gt; by default, but &lt;strong&gt;private class members&lt;/strong&gt; can be created by using a hash &lt;code&gt;#&lt;/code&gt; prefix. The privacy encapsulation of these class features is enforced by JavaScript itself.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ClassWithPrivate&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateFieldWithInitializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;privateMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// …&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateStaticField&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nx"&gt;privateStaticFieldWithInitializer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="err"&gt;#&lt;/span&gt;&lt;span class="nf"&gt;privateStaticMethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// …&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The browser support is good, but not fabulous. The syntax is understood by Chrome &amp;gt;= 74 (April 2019), Safari &amp;gt;= 14.1 (April 2021), so if you want to go lower with supported clients, consider transpiling your production code using babel &amp;gt;= 7.14 which enables the required plugins by default, or include them yourself in the transpiling configuration.&lt;/p&gt;

&lt;p&gt;I've seen great enthusiasm throughout my team for adopting this level of encapsulation, despite adding one more concern (class member access) to the JavaScript developer; a developer previously spoiled with simplicity, but simplicity that may backfire on long-lived software. As they say in Google, &lt;em&gt;"Software engineering is programming integrated over time".&lt;/em&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>softwareengineering</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>What are some obscure technologies you once learnt and don't expect to use them again?</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Wed, 24 May 2023 19:09:36 +0000</pubDate>
      <link>https://dev.to/mihneasim/what-are-some-obscure-technologies-you-once-learnt-and-dont-expect-to-use-them-again-o4b</link>
      <guid>https://dev.to/mihneasim/what-are-some-obscure-technologies-you-once-learnt-and-dont-expect-to-use-them-again-o4b</guid>
      <description>&lt;p&gt;And what still &lt;strong&gt;stuck with you&lt;/strong&gt; after that experience? What unique facts do you still remember?&lt;/p&gt;

&lt;p&gt;I start!&lt;/p&gt;

&lt;p&gt;At my first (actual) job, I used &lt;a href="https://www.zope.dev/"&gt;Zope2&lt;/a&gt;, a Python framework that, for that version, was able to hold code and templates in its database. The database was not relational, but instead, a tree-like structure of objects, called &lt;a href="https://zodb.org/en/latest/"&gt;ZODB&lt;/a&gt; - zope object database. I see both projects are actively maintained.&lt;/p&gt;

&lt;p&gt;In a big tech I had to migrate some API clients that were written in Perl, while some template rendering was done in &lt;a href="https://metacpan.org/pod/Mason"&gt;Mason&lt;/a&gt;. What stuck with me, was that Mason scripts had some kind of delimitation of execution context; they had some kind of header that was being executed in a faster manner than the rest of the script. Can't remember much.&lt;/p&gt;

&lt;p&gt;In spring 2022, I went through Primeagen's &lt;a href="https://soliditylang.org/"&gt;Solidity&lt;/a&gt; class on frontendmasters when I was doing "my research" on non-fungible tokens and blockchain tech. I don't see myself coming back to that language, but it did showcase a framework in which operations matter in terms of cost. Directly. In 2022 I also watched Richard Feldman's class on &lt;a href="https://www.rust-lang.org/"&gt;Rust&lt;/a&gt; - the way you could "cast" the life span (&lt;em&gt;lifetime&lt;/em&gt;) of the allocated memory for a variable to an annotation (&lt;em&gt;'a&lt;/em&gt;) - that, that stuck with me. Probably, on this list, Rust has the highest potential to find its way into my keystrokes again.&lt;/p&gt;

&lt;p&gt;Reminding myself of computational cost and memory brings me back memories of all the obscure development environments I went through in my 4-year Computer Science Bsc - &lt;a href="https://en.wikipedia.org/wiki/Assembly_language"&gt;Assembly&lt;/a&gt; (mnemonic processor instructions), Matlab (actually &lt;a href="https://octave.org/"&gt;Octave&lt;/a&gt;, useful for running numerical algorithms that approximate or sample continuous signals), &lt;a href="https://en.wikipedia.org/wiki/Verilog"&gt;Verilog&lt;/a&gt; (simulating simple logical circuits or more advanced electronics, using static gates as well as clock based circuits). Then we have the other programming paradigms that we experimented in, as students: &lt;a href="https://www.swi-prolog.org/features.html"&gt;Prolog&lt;/a&gt; (solving the Wolf, Sheep And Cabbage Game), &lt;a href="https://www.clipsrules.net/"&gt;Clips&lt;/a&gt; and &lt;a href="https://www.haskell.org/"&gt;Haskell&lt;/a&gt; (functional programming).&lt;/p&gt;

&lt;p&gt;Can you top it? :) What's your less-popular development experience?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>programming</category>
      <category>learning</category>
    </item>
    <item>
      <title>Your last read before your next great idea of an app using OpenAI APIs</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Sun, 07 May 2023 18:45:02 +0000</pubDate>
      <link>https://dev.to/mihneasim/your-last-read-before-your-next-great-idea-of-an-app-using-openai-apis-192d</link>
      <guid>https://dev.to/mihneasim/your-last-read-before-your-next-great-idea-of-an-app-using-openai-apis-192d</guid>
      <description>&lt;p&gt;Sooner rather than later, you will face the fact that you'll want to experiment with building a project on top of open ai. Let's face it - we've all been sick of building Todo apps just for the sake of learning a new language or framework; and guess what, this time, not even a Hello World or a Todo-App will cut it! I'm going to provide you with a simple framework for coming up with a product idea if asked to build a project based on OpenAI's APIs.&lt;/p&gt;

&lt;p&gt;As I was saying, this is a framework for brainstorming &lt;strong&gt;initial ideas&lt;/strong&gt;. Don't rush me into theory on Product design. It's up to you to iterate on the ideas you will produce, by using Design Thinking and other techniques as such. You're free to start writing your business canvas.&lt;/p&gt;

&lt;p&gt;But before experimenting and pivoting on a solution, you first need to find the problem to address. And that's why &lt;em&gt;"thinking of an idea of an app that does something"&lt;/em&gt; just so you can practice or learn a new technology is so difficult: because &lt;strong&gt;rarely&lt;/strong&gt; do we search for a market of customers, just because we have a certain technology at hand. It's like buying a fancy hammer, before knowing whether you'd have any bolts to hammer in.&lt;/p&gt;

&lt;h2&gt;
  
  
  Offers vs Ameliorates
&lt;/h2&gt;

&lt;p&gt;It comes down to understanding what the technology &lt;em&gt;offers&lt;/em&gt; and what problems it &lt;em&gt;ameliorates&lt;/em&gt;. It's a subtle difference, and it's easier to explain by using an example. If we look at Dall-E, it offers a way to generate images based on a natural language definition. But it can ameliorate a lot of needs, such as obtaining images based on a brief description, ready to be used, without the hassle of contracting and/or paying for a license. Maybe you're a magazine editor or a publisher looking for your next cool book cover. The cover of this article was generated by Dall-E using the prompt "a lightbulb surfing a wave".&lt;/p&gt;

&lt;p&gt;Once we figured that out, we move on to synergies: yes, you guessed it, combining the technology advantage with your added value, if they're a good mix!&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Added Value
&lt;/h2&gt;

&lt;p&gt;A good example of added value here is unique data. Something no other possesses. Do you have an encyclopedia you built on all possible water sprinklers ever produced? Do you have unique cooking recipes from your ancestors? Extensive documents of architecture in your organisation? All of these may be the subject of your next unique idea. It doesn't even need to be structured data, because that's something OpenAI can do for you. Just try to match your data with the technology &lt;strong&gt;offerings&lt;/strong&gt; in order to list &lt;strong&gt;new problems&lt;/strong&gt; your potential solution &lt;strong&gt;ameliorates&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Water with a drop of dish soap
&lt;/h2&gt;

&lt;p&gt;When practising the steaming of the milk for latte art, using an espresso, a fairly good replacement for actual milk is water plus a drop of dish soap. Works like a charm fairly similar to milk.&lt;/p&gt;

&lt;p&gt;You can do the same by looking for synthetic data or producing it yourself. And you can do that with GPT itself ;) I found this &lt;a href="https://data.world/datafiniti/consumer-reviews-of-amazon-products"&gt;data set&lt;/a&gt; on &lt;a href="http://data.world"&gt;data.world&lt;/a&gt; (under BY-NC-SA license by Datafiniti). It contains a bunch of customer reviews of their purchases - mainly Amazon hardware products, such as Kindle. I created a prompt where I asked for the topic to be changed to something that I needed the reviews to be about.&lt;/p&gt;

&lt;p&gt;I.e., if we consider this real review of Kindle Paperwhite:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Great for those that just want an e-reader I am enjoying it so far. Great for reading. Had the original Fire since 2012. The Fire used to make my eyes hurt if I read too long. Haven't experienced that with the Paperwhite yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;..when asked to change the topic to a &lt;strong&gt;restaurant&lt;/strong&gt;, "text-davinci-003" model will return:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Great for those that just want a meal I am enjoying it so far. Great for dining. Had the original restaurant since 2012. The restaurant used to make my stomach hurt if I ate too much. Haven't experienced that with this restaurant yet.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The repo is &lt;a href="https://github.com/mihneasim/synthetic-reviews"&gt;on my Github&lt;/a&gt;; please pardon my clumsiness in Python and pandas - it's been a while (about 8 years since I last wrote some py; but not much has changed I see).&lt;/p&gt;

&lt;h2&gt;
  
  
  Iterate
&lt;/h2&gt;

&lt;p&gt;This. This is the part where you dive into Design thinking methodology; of course, if you want to go out there and build a service for actual users.&lt;br&gt;&lt;br&gt;
Otherwise, if you just want to try out your technology of choice, simply start prototyping your fresh idea.&lt;/p&gt;

&lt;p&gt;How did you find your latest idea?&lt;/p&gt;

</description>
      <category>openai</category>
      <category>ai</category>
      <category>startup</category>
      <category>chatgpt</category>
    </item>
    <item>
      <title>Cracked: Why Will's JavaScript The Hard Parts class is so efficient</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Thu, 20 Apr 2023 18:20:12 +0000</pubDate>
      <link>https://dev.to/mihneasim/cracked-why-wills-javascript-the-hard-parts-class-is-so-efficient-10e4</link>
      <guid>https://dev.to/mihneasim/cracked-why-wills-javascript-the-hard-parts-class-is-so-efficient-10e4</guid>
      <description>&lt;p&gt;I've watched Will Sentance's class JavaScript, The Hard Parts v2, and I liked it - without knowing who he is and how much experience he invested in teaching - I didn't only like it as a virtual participant, but especially as a lead and a trainer wannabe. I would like one day to be able to replicate, in my own style, of course, some of his strategies.&lt;/p&gt;

&lt;p&gt;Will is CEO of &lt;a href="https://www.codesmith.io"&gt;codesmith.io&lt;/a&gt;, a &lt;em&gt;top-ranked coding school, online and in NYC&lt;/em&gt;. That's the bit I didn't know about when I came up with the idea of documenting his class.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I stumbled upon JavaScript: The Hard Parts v2 class
&lt;/h2&gt;

&lt;p&gt;In my organisation, we dedicate about 1 day out of 10 sprint days for self-development; yes, that's during office hours, I'm not talking about moonlight coding - or at least that's the &lt;em&gt;deal on paper&lt;/em&gt;. You probably heard of something similar taking place at Google, on Fridays - that's how Gmail was born. But here, we choose to invest it in the development of our craftsmanship. We're taking this study time in an organised fashion, in alignment with one's development plan. Otherwise, it would just sound like a day off to read online content.&lt;/p&gt;

&lt;p&gt;As a Chapter Lead, I struggled to make my chapter take this seriously. Engineers have a greater incentive to perform to the goals of the tribe, so they often commit to the delivery for the entire sprint-time, rather than saving some for their own learning and development. Of course, it is a trap; in the long run, we're rotting as engineers, becoming blind to innovation opportunities and growth. Becoming better professionals would benefit the organisation, the projects, and the effectiveness of the delivery, as a whole.&lt;/p&gt;

&lt;p&gt;To move the needle, I become more aggressive in decisions: I asked a colleague to pick a class on Frontend Masters (really, &lt;em&gt;any&lt;/em&gt; class), by 5 pm the same day, or else I would make this choice for him. So I chose &lt;a href="https://frontendmasters.com/courses/javascript-hard-parts-v2/"&gt;JavaScript: The Hard Parts, v2&lt;/a&gt;. Since we're working a lot with web components, and we're converting business logic from AngularJs to Vanilla Js classes, it looked like we need strong JavaScript-skilled engineers with proper ownership of the fundamentals of the language. Not just frameworks.&lt;/p&gt;

&lt;p&gt;And so, a couple of weeks later, my colleague returned to provide his thoughts. Bracing myself for harsh feedback on my choice of topic, I got particularly enthusiastic to hear that he considered the class &lt;em&gt;amazing&lt;/em&gt;. &lt;em&gt;"We all use and think we know those things, but it helps to understand their underlying reasoning once again"&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Just after Christmas of '22, I had some spare time and gave it a shot. I went through the class myself. The content - indeed, fundamentals of Js. But I was immensely impressed by the manner the class was built and delivered.&lt;/p&gt;

&lt;p&gt;I studied Will, I decomposed his style, his setup, and his props, and I reverse-engineered his recipe to three key advantages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Distraction-free teaching "props"&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Live audience - In-person participants&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Smart use of creativity&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Distraction-free teaching props
&lt;/h2&gt;

&lt;p&gt;Will is using a blackboard and white or colourful markers. He's not employing any digital means. He's not typing code, he's writing it, by hand. The representations limit themselves to basics: global scope, local scope, and execution stack. When needed, a slide with code pops up.&lt;/p&gt;

&lt;h2&gt;
  
  
  Live audience - In-person participants
&lt;/h2&gt;

&lt;p&gt;Will is not recording himself teaching the class to a camera, or to a virtual participant. He has actual participants sitting and learning physically in the same room. They don't appear in the footage, maybe just rarely when one is "called to the blackboard". You get to be an actual spectator to the learning activities taking part between Will and his trainees. I've seen this before and it's highly beneficial:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;you get a sense of what is expected to understand or to have trouble with, in each moment, because the real people in the class will articulate that. You will &lt;em&gt;feel&lt;/em&gt; what they feel. You will share their silence when some concept needs time &lt;em&gt;to sink in&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;it's auto-paced by the audience. The trainer will adjust speed and level according to a tight, real-time feedback loop with the audience. Will stops after every milestone, to ask how much they understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;thumb up = I got it, move on&lt;/li&gt;
&lt;li&gt;thumb down = I don't get it&lt;/li&gt;
&lt;li&gt;horizontal thumb = I need to ask a question&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I said I saw this before - ages ago when I started learning German, I ran into the so-called &lt;a href="https://www.youtube.com/watch?v=U9Xh-by50pI"&gt;Michel Thomas Method&lt;/a&gt; which, besides many other techniques specific to foreign language learning, also leverages the power of having actual people participate in the act of teaching together with the trainer, while the class is being recorded for a much larger, remote, audience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Smart use of creativity
&lt;/h2&gt;

&lt;p&gt;Many engineers display passion, but it takes skill and creativity to convey it in a &lt;em&gt;catchy&lt;/em&gt; manner, in a phrasing that &lt;em&gt;sticks&lt;/em&gt;. It takes some degree of creativity and lateral thinking to portray a JavaScript closure as &lt;em&gt;a backpack&lt;/em&gt; that gets carried by a function that's returned as a value.&lt;/p&gt;

&lt;h2&gt;
  
  
  Teaching styles are different,
&lt;/h2&gt;

&lt;p&gt;But some stand out. And by no accident, with solid experience in his backpack, Will Sentance is a model for the teacher in me. I wouldn't rush out the door, into buying and installing a blackboard. It's not about techniques one can copy. It's about having the act of teaching in the centre, with a spotlight on the main actor - the trainee, not the trainer. Whenever you're building a new product, all decisions revolve around the potential customer. If you look at teaching as a product, then yes, you have to put the participants first, preferably in person, in the same room with you.&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>javascript</category>
      <category>learning</category>
      <category>leadership</category>
    </item>
    <item>
      <title>Accessibility 101</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Tue, 07 Mar 2023 07:25:00 +0000</pubDate>
      <link>https://dev.to/mihneasim/accessibility-101-3eoi</link>
      <guid>https://dev.to/mihneasim/accessibility-101-3eoi</guid>
      <description>&lt;p&gt;I spent about 10-15 hours on edx's &lt;a href="https://learning.edx.org/course/course-v1:W3Cx+WAI0.1x+3T2019/home"&gt;online course&lt;/a&gt; on &lt;em&gt;Introduction to Web Accessibility&lt;/em&gt;, authored by W3Cx, which seems to be a collection of trainings straight from the people in W3C (in W3C's &lt;a href="https://www.w3.org/WAI/"&gt;WAI&lt;/a&gt; for this one, to be more precise).&lt;/p&gt;

&lt;p&gt;I'm writing this so you don't have to spend the same amount of time on the course; although if you care about the Web and its fundamental principles, I strongly encourage you to do so. It's free and it's enlightening.&lt;/p&gt;

&lt;p&gt;My prior knowledge to Accessibility, before attending this course:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;there are contrast thresholds readable text should meet&lt;/li&gt;
&lt;li&gt;use descriptive &lt;code&gt;alt&lt;/code&gt; attribute for images&lt;/li&gt;
&lt;li&gt;use appropriate css units for sizing font (&lt;code&gt;em&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;one should be able to browse a website or use a web app without a pointing device (keyboard only)&lt;/li&gt;
&lt;li&gt;something with &lt;code&gt;aria&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;there are some online evaluation tools that can score the accessibility of
your website&lt;/li&gt;
&lt;li&gt;a11y is the &lt;a href="https://en.wikipedia.org/wiki/Numeronym"&gt;numeronym&lt;/a&gt; for accessibility&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And that was it.&lt;/p&gt;

&lt;p&gt;What I was looking for:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Theory, but in a practical approach. School was cool, but we need real life
usable stuff shipped&lt;/li&gt;
&lt;li&gt;Structure&lt;/li&gt;
&lt;li&gt;Fundamentals on which to build upon - not just &lt;em&gt;tips and tricks&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Theory
&lt;/h2&gt;

&lt;p&gt;All great stories start with a history lesson, and accessibility makes no exception. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The power of the Web is in its universality. Access by everyone regardless&lt;br&gt;
of disability is an essential aspect said Tim Berners-Lee, W3C Director and inventor of the World Wide Web.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And because we're greedy and hungry for the greatest, the fastest, the bestest ways to grow a business, policies and laws were required to come in place and protect &lt;strong&gt;people&lt;/strong&gt;. People are imperfect - we don't see, hear, move, or infer with the same acuity, and most often than not, not because of their own fault; not that it would matter. People are people, and in the society we want to live in, we ought to use technology in the &lt;em&gt;interest of all the human beings&lt;/em&gt;. Not just the young, the sharp, the healthy, the genetically lucky ones, the ones privileged in the society. Let's remove the word &lt;em&gt;privileged&lt;/em&gt; as much as we can.&lt;/p&gt;

&lt;p&gt;The course is not intentionally sentimental; but it does showcase people with all sorts of disabilities. You will step into the shoes of the disadvantaged people. You will become emotional, realising how lucky you most probably are. Statistically, there's an 85% chance you have all your senses and your motor function in good shape to browse to and to read and understand the content on dev.to. Some people would have to use a keyboard with the aid of a stick in their mouth to get here.&lt;/p&gt;

&lt;p&gt;WCAG - Web Content Accessibility Guidelines version 2.1 is what you're aiming to adhere to, when offering your services on the web. I like how the course is spot on from the start: &lt;em&gt;Don't jump to the standard&lt;/em&gt;. Half of it explains how the other half should be read. It's a show stopper. Instead, the course introduces a less scary approach. And provides structure.&lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;There are two types of approaches people use to improve the way they interact with technology:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Through the means of &lt;em&gt;assistive technologies&lt;/em&gt;, meaning software or hardware
that help people more easily operate. I.e. a screen reader, a switch control,
or even the ordinary glasses!&lt;/li&gt;
&lt;li&gt;By employing &lt;em&gt;adaptive strategies&lt;/em&gt; such as enlarging font size, changing
contrast, resizing a window. Some people need to enlarge font and window
width, others, surprisingly, read better when the text is smaller and the
line length is much shorter.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Second module of the course focuses on these two, grouped by the types of disabilities: physical and visual, hearing and speech, cognition and learning.&lt;/p&gt;

&lt;p&gt;Third module is all about business cases and benefits; probably the most dull, at least for me. Accessibility needs no business case, but in case you need some, they can be easily found.&lt;/p&gt;

&lt;p&gt;Fourth module is the real deal, diving into &lt;em&gt;WCAG 2.1&lt;/em&gt; fundamentals.&lt;/p&gt;

&lt;p&gt;And the fifth is just as dull as the third. It's how to lure the important stakeholders in the organisation into accessibility. How to &lt;em&gt;get started&lt;/em&gt;. I'm not sure one can make a real-life working guide on that, but I should however appreciate the &lt;em&gt;Shift-left&lt;/em&gt; recommendation. I'm seriously starting to laugh every time I hear &lt;em&gt;shift-left&lt;/em&gt;. So much shifting that one starts to wonder what's left on the &lt;em&gt;right-side&lt;/em&gt; of the delivery, but that's for another story.&lt;/p&gt;

&lt;p&gt;Key takeaway on the shifting is probably that particularly the persons involved  at the start of the product design process (product designers, UX architects, project managers)&lt;br&gt;
&lt;strong&gt;need&lt;/strong&gt; to have a working literacy on Accessibility, so issues are addressed earlier in the process. Don't leave Accessibility for the last week before first MVP go-live.&lt;/p&gt;

&lt;h2&gt;
  
  
  Fundamentals
&lt;/h2&gt;

&lt;p&gt;W3C WAI contributes with not one, but three guidelines:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;WCAG - Web Content Accessibility Guidelines; the most popular ones, regarding Web Content.&lt;/li&gt;
&lt;li&gt;ATAG - Authoring Tool Accessibility Guidelines; guidance in building
accessible software used by content creators. Imagine the admin panel of a
blogging platform. Or the "Create a Post" page of a social network.&lt;/li&gt;
&lt;li&gt;UAAG - User Agent Accessibility Guidelines - for browsers, media players and
other user agents.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;WCAG defines four principles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Perceivable&lt;/strong&gt; - techniques for making information available in different ways.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Operable&lt;/strong&gt; - In addition to perceiving info, users should be able to operate,
to navigate, fill in and submit forms, have some sort of interactivity with
the application; in order to do so, they might employ a mouse,
or no mouse at all and stick to keyboard only, sip and puff, speech input; yes, some people
are limited to simple switches because of their lack of mobility and their
difficulty in speaking.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understandable&lt;/strong&gt; - both information, and functionality; use simple vocabulary,
make intentions clear, be explicit on what is required and in which form.
Don't make the user think or guess what is expected on his/her side.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Robust&lt;/strong&gt; - Reliability when rendering the content or running the
application on a variety of platforms. If it's a web content or app, it
should run without issues in any present or future version of a major browser.
If it's multimedia content, we should expect to behave the same on multiple players.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Technical dive-in
&lt;/h3&gt;

&lt;p&gt;On a scale of 1 to 5 on technical expertise, you need a 2, but it's not a hard requirement to follow through. The course only scratches the surface, for both web content and mobile apps - iOS and Android.&lt;/p&gt;

&lt;p&gt;You will need some tiny knowledge on HTML and to be able to grasp basic native UI elements, like backward and forward navigation, gestures and haptic. That's it. The material &lt;em&gt;is not designed&lt;/em&gt; for engineers. It's universal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key takeaways
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Accessibility&lt;/strong&gt; is important for anyone who cares &lt;strong&gt;about people&lt;/strong&gt;, before any policy or checkbox that we need to tick off, in our large business or for our small project. Following accessibility guidelines never stops, it's not a one time process. It needs to be embedded in the design and delivery process. The sooner, the better, the cheaper. Just like you strive to do with your other non functional requirements.&lt;/p&gt;

&lt;p&gt;You only truly know your accessibility makes a difference when testing with &lt;strong&gt;real people&lt;/strong&gt;. Evaluation tools can mislead. Ask for feedback people having trouble using technology, older people, your grandparents; reach out to organisations for people with disabilities. I bet they can't wait to help with feedback.&lt;/p&gt;

&lt;p&gt;Thank you for reading, and keep caring!&lt;/p&gt;

</description>
      <category>a11y</category>
      <category>webdev</category>
      <category>frontend</category>
      <category>design</category>
    </item>
    <item>
      <title>Image rendering 101. Ultimate raster-vector battle: PNG vs SVG</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Sat, 29 Oct 2022 09:22:18 +0000</pubDate>
      <link>https://dev.to/mihneasim/image-rendering-101-ultimate-raster-vector-battle-png-vs-svg-18jc</link>
      <guid>https://dev.to/mihneasim/image-rendering-101-ultimate-raster-vector-battle-png-vs-svg-18jc</guid>
      <description>&lt;p&gt;I was having a discussion with one of my colleagues on the decision of using SVG format instead of PNGs of various predefined sizes. We knew predefined-PNGs was the preferred way to go for our colleagues in charge with Android/iOS development.&lt;/p&gt;

&lt;p&gt;As a web developer engineer, I was a bit in shock hearing PNG, a raster format, would indeed be an option. Isn't a vectorial format supposed to deliver top quality for illustrations? I started to challenge my beliefs - What if, just what if, for a given width and a given height, a PNG export would have a superior result when compared to the "on-the-fly" rendering of an SVG?&lt;/p&gt;

&lt;p&gt;With this question in mind, let's set our image rendering theory straight.&lt;/p&gt;

&lt;h3&gt;
  
  
  Small intro into image formats
&lt;/h3&gt;

&lt;p&gt;PNG, JPG and WEBP are raster data formats for images. Their canvas size is predefined, described by width &amp;amp; height, and the data inside the file describes the colors of all the pixels in W x H area. Even though they use smart data structures, similar to archiving, to save up disk space and network traffic, they still contain all the data needed for all the pixels to be painted.&lt;/p&gt;

&lt;p&gt;SVG, a vectorial format, also specifies canvas size (width and height), but as a default and a point of reference for content proportions. SVG does not describe the pixels themselves (or dots, to be more precise), but it instead describes shapes that then need to be converted to pixels or dots during painting - on the display, in a projector, or on a paper by the printer. The shapes are described through relative coordinates and other primitives such as lines, circles, curves, arcs - by using markup that specifies descriptions of paths and fills, rather than actual color data per pixel.&lt;br&gt;
Of course, this type of format puts a limit on the content of the image. You can't use it for photographs, you are limited to illustrations with solid-colors or uniform gradients. Moreover, it increases the requirements and computational usage of the renderer, now in charge with actually computing&lt;br&gt;
the values for the pixels/dots. Other vectorial formats are EPS (most used), AI (Adobe's), and PDF (yes, PDF may contain vector data, but are not limited to).&lt;/p&gt;

&lt;p&gt;SVG is the only vector format that can be used natively in web browsers.&lt;/p&gt;
&lt;h3&gt;
  
  
  Small intro into image rendering
&lt;/h3&gt;

&lt;p&gt;Image rendering is the process of interpreting the contents of the data (i.e. the image file) and translating them into the actual instructions to paint the image for the user to see (on screen, on paper, on e-ink display etc.).&lt;/p&gt;

&lt;p&gt;In browsers, image rendering basically means deciding what color should every pixel on your webpage be painted, so that the user can visualize the image.&lt;/p&gt;

&lt;p&gt;The PNG rendering is straight forward - it already contains the raster data for each pixel. For the SVG, the browser needs to perform a process called &lt;strong&gt;rasterization&lt;/strong&gt;. During rasterization, the browser needs to decide exactly what color every pixel should be, based on the geometrically described shapes in the file.&lt;/p&gt;

&lt;p&gt;Let's suppose we have a solid color square in an SVG. If we need that rendered in a 16px x 16px canvas, the browser simply fills those pixels with the corresponding solid color. Any rectangular shape (that is not rotated by any degree), is almost always a perfect match to the target pixels, and the easiest thing to render.&lt;br&gt;
Issues occur when they are scaled up or down, by such a scale that either the width or the height wouldn't be an integer anymore.&lt;/p&gt;

&lt;p&gt;Consider a vectorial image describing a 41 x 20 rectangle, that we need to render half the size. The renderer would probably need to scale it down to an actual 20 x 10 (instead of 20.5 x 10, cause there's no such thing as half a pixel). What does the render do about the extra width-pixel column that it had to trim from the original image? Some options -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flrl8rh2xrgwmvgjevrsy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flrl8rh2xrgwmvgjevrsy.png" alt="41 by 20 rectangle" title="Original 41x20 rectangle" width="550" height="178"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;just drop it, simply draw a 20 x 10 solid color rectangle. What if the rectangle wasn't all the same solid color, and in addition it had a red color 1px right border? Wouldn't we lose that red detail completely?&lt;/li&gt;
&lt;li&gt;draw a 21 x 10 rectangle, where the 21st column is a much more blended variant of the solid color with the canvas color. I.e., if drawing a black rectangle over a white background, the 21st column would be a light gray, to try and mimic the original aspect ratio of 20.5:10, instead of 20:10.  In our earlier example, if the rectangle had a right 1px solid border, probably the 21st column in the downsized version would of a faded out red color to mimic the "half a pixel".&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is what Adobe Photoshop chose to produce when asked to downsize the original image by 50%. Interestingly, I guessed it right with for the last column, but never have I thought that the first column would also be tampered to a light gray.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7p5ers5zgtd40t4dhp2p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7p5ers5zgtd40t4dhp2p.png" alt="21 by 10 rectangle" title="Photoshop's choice of 50%&amp;lt;br&amp;gt;
downsizing" width="550" height="222"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Things get much more complicated when rasterizing rotated shapes and non-linear shapes. That complicated, that it gave birth to a dedicated field of study. I remember having entire classes on rasterization in my final year of Computer Science.&lt;/p&gt;
&lt;h3&gt;
  
  
  Experiment
&lt;/h3&gt;

&lt;p&gt;Let's compare the rasterization quality of an SVG in a browser, to the quality of a PNG produced by an image processing software (Adobe Photoshop) for the same size. We would only compare the rendering of curvilinear shapes for simplicity, but also keeping the test relevant.&lt;/p&gt;

&lt;p&gt;Procedure:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We will draw a 300px-radius black color filled circle.&lt;/li&gt;
&lt;li&gt;On top of it, in its center, a 280px radius white filled circle. For simplicity, we're only rendering a quarter of this drawing.&lt;/li&gt;
&lt;li&gt;We will use Adobe Photoshop to export the same shape, at the same size, in PNG format.&lt;/li&gt;
&lt;li&gt;In an HTML file, we will render both the SVG and the PNG file. We will use screenshots that we will enlarge in Adobe Photoshop until we can see how each pixel was rendered.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg67vwrjzpu33228ovh9g.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg67vwrjzpu33228ovh9g.png" alt="showcase-of-canvas-to-work-with" title="Scenario Setup" width="358" height="301"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;SVG File (canvas #1):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;svg version="1.1"
     width="300" height="300"
     xmlns="http://www.w3.org/2000/svg"&amp;gt;
  &amp;lt;circle cx="300" cy="300" r="300" /&amp;gt;
  &amp;lt;circle cx="300" cy="300" r="280" fill="white" /&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;SVG File that would be opened and used to generate PNG (canvas #2):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;svg version="1.1"
     width="300" height="300"
     xmlns="http://www.w3.org/2000/svg"&amp;gt;
  &amp;lt;circle cx="0" cy="300" r="300" /&amp;gt;
  &amp;lt;circle cx="0" cy="300" r="280" fill="white" /&amp;gt;
&amp;lt;/svg&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;index.html:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt; &lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./circles.svg"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"./circles.png"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Results
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvf7ie1lbzv1dm29qhipd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvf7ie1lbzv1dm29qhipd.png" alt="showcase of result in browser" title="Our result in browser" width="620" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now let's zoom in and inspect, side by side, how the curves look.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82spcr2aatko00rtgha8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F82spcr2aatko00rtgha8.jpg" alt="zooming in on the curves" title="Side by Side of curves rendering" width="800" height="813"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interesting, it seems the browser is doing a smoother job on the SVG than Photoshop did when writing the PNG file. Let's cut out only two rows of pixels, part of the top curve, and enlarge them side by side. We are able to compare the gradients that were rendered in order to model the rounded shape.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpchcjhekh7h5u4osnnz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjpchcjhekh7h5u4osnnz.png" alt="zooming in on curves gradients" title="Side by Side of gradients for curves" width="660" height="198"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As far as we can see, the result is crazy similar. Only by zooming in and looking at the pixels themselves can we tell that the SVG quality is marginally better than PNG, but the margin is too small for the human eye - even educated human eye - to see.&lt;/p&gt;

&lt;h3&gt;
  
  
  What we left out
&lt;/h3&gt;

&lt;p&gt;The experiment did not perform a comprehensive comparison. What we left out of the picture (pun intended):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Rasterization of color gradients.&lt;/li&gt;
&lt;li&gt;Rasterization of all the other different shapes: other curves and angled lines.&lt;/li&gt;
&lt;li&gt;What happens when downsizing details? How would each engine choose what details to drop and how?&lt;/li&gt;
&lt;li&gt;How about upscaling details?&lt;/li&gt;
&lt;li&gt;Is there a rendering performance impact on the browser when dealing with more complex illustrations?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As previously stated, rasterization is a complex field by itself, which by the way, also addresses the rendering of 3D scenes onto our 2D screens; and I'm only scratching the surface here with the quickest intro I could offer in this article.&lt;/p&gt;

&lt;p&gt;If you also have a tiny story to share, something to contribute or correct, don't hesitate to reach me or the comments section!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ui</category>
      <category>design</category>
      <category>graphics</category>
    </item>
    <item>
      <title>npm list and npm explain explained</title>
      <dc:creator>Mihnea Simian</dc:creator>
      <pubDate>Mon, 17 Oct 2022 16:51:38 +0000</pubDate>
      <link>https://dev.to/mihneasim/npm-list-and-npm-explain-explained-58b5</link>
      <guid>https://dev.to/mihneasim/npm-list-and-npm-explain-explained-58b5</guid>
      <description>&lt;p&gt;Long long time ago, when I used to do Rapid App Development using Python, my package manager of choice was &lt;a href="https://pip.pypa.io/en/stable/"&gt;pip&lt;/a&gt;. And one feature I very much liked was being able to output all the names and versions of the dependencies available in the environment, one per line. You could simply redirect that output to a text file, add it to the VCS, and later use that file to install the same version set.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;pip freeze &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; requirements.txt
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;cat &lt;/span&gt;requirements.txt
&lt;span class="go"&gt;pytest==3.3.2
requests==2.18.4
requests-mock==1.4.0
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It sounds simple enough, and it really was that simple, especially when combined with virtualenv. But let's talk about JavaScript's infamous &lt;code&gt;npm&lt;/code&gt;, self-titled on Twitter "The package manager for JavaScript". Pip's &lt;em&gt;requirements.txt&lt;/em&gt; is equivalent to npm's &lt;em&gt;package.json&lt;/em&gt; and&lt;br&gt;
there is no need for an npm &lt;em&gt;freeze&lt;/em&gt; command. &lt;code&gt;npm&lt;/code&gt; will create and update it for you every time you use it to manage requirements.&lt;/p&gt;

&lt;p&gt;However, the actual "freeze" of a pip project is rather the equivalent of &lt;em&gt;package-lock.json&lt;/em&gt;, which contains the full list and metadata of the exact version set in use. Apart from that, there is a command one can use to inspect the versions of the installed packages and their relation - &lt;code&gt;npm list&lt;/code&gt;. Be advised that the behaviour of &lt;code&gt;npm list&lt;/code&gt; changed in npm&lt;br&gt;
version 7 (bundled with nodejs v15).&lt;/p&gt;

&lt;p&gt;I stumbled upon the change myself, and I had to convince myself something indeed had changed. The output was a flat list of deps, instead of the fluffy tree structure I used to know. Running multiple versions of npm/nodejs is made so easy by using &lt;a href="https://github.com/nvm-sh/nvm"&gt;nvm&lt;/a&gt;. This way, I couldn't resist not showcasing this change to my own eyes.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nvm &lt;span class="nb"&gt;install &lt;/span&gt;14
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nvm use 14
&lt;span class="go"&gt;Now using node v14.17.4 (npm v6.14.14)
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npm &lt;span class="nb"&gt;help &lt;/span&gt;list
&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;   Description
       This command will print to stdout all the versions of
packages that are installed, as well as their
dependencies, in a tree-structure.
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nvm &lt;span class="nb"&gt;install &lt;/span&gt;15
&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;nvm use 15
&lt;span class="go"&gt;Now using node v15.14.0 (npm v7.7.6)
&lt;/span&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npm &lt;span class="nb"&gt;help &lt;/span&gt;list
&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;   Description
       This command will print to stdout all the versions of
packages that are installed, as well as their
dependencies when --all is specified,
in a tree structure.
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;span class="go"&gt;       Also, in the years since npm got an ls command
(in version 0.0.2!), dependency graphs have gotten
much larger as a general rule. Therefore, in order
to avoid dumping an excessive amount of content
to the terminal, npm ls now only shows
the top level dependencies,
unless --all is provided.
&lt;/span&gt;&lt;span class="c"&gt;...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A-ha! So &lt;code&gt;npm list&lt;/code&gt; in npm version &amp;lt;= 6 is &lt;code&gt;npm list --all&lt;/code&gt; in npm version 7 or higher; which is of course stated in their &lt;a href="https://github.com/npm/cli/blob/v7.0.0/CHANGELOG.md#npm-ls"&gt;v7 Changelog&lt;/a&gt; - but looking up changelogs is way too mainstream.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;npm ls&lt;/p&gt;

&lt;p&gt;Extraneous dependencies are listed based on their location in the node_modules tree.&lt;/p&gt;

&lt;p&gt;npm ls only prints the first level of dependencies by default. You can make it&lt;br&gt;
print more of the tree by using --depth= to set a specific depth,&lt;br&gt;
or --all to print all of them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  npm explain
&lt;/h3&gt;

&lt;p&gt;Since the installed packages follow a tree-like structure, based on &lt;em&gt;dependency transitivity&lt;/em&gt;, i.e. A needs B, B needs C, so installing A, installs C, one might fall into the trap of importing directly from C.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://eslint.org/"&gt;ESLint&lt;/a&gt; was not shy enough not to complain:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;2:1 error 'stringify-object' should be listed in the project's dependencies.&lt;br&gt;
Run 'npm i -S stringify-object' to add it import/no-extraneous-dependencies&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;where line 2 was:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;import stringifyObject from 'stringify-object';&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Fear not. This is where &lt;code&gt;npm explain&lt;/code&gt; comes into play.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;This command will print the chain of dependencies causing a given package to&lt;br&gt;
be installed in the current project.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;npm explain stringify-object
&lt;span class="go"&gt;stringify-object@3.3.0 dev
node_modules/stringify-object
  stringify-object@"^3.3.0" from lint-staged@10.5.4
  node_modules/lint-staged
    dev lint-staged@"^10.5.4" from the root project
  stringify-object@"^3.3.0" from workbox-build@6.5.4
  node_modules/workbox-build
    workbox-build@"^6.2.4" from rollup-plugin-workbox@6.2.0
    node_modules/rollup-plugin-workbox
      dev rollup-plugin-workbox@"^6.2.0" from the root project
      rollup-plugin-workbox@"^6.0.0" from @open-wc/building-rollup@2.0.2
      node_modules/@open-wc/building-rollup
        dev @open-wc/building-rollup@"^2.0.1" from the root project
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But then, I thought - didn't &lt;code&gt;npm list&lt;/code&gt; also have positional arguments - accepting specific package names as input? Let's try that&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="gp"&gt;$&lt;/span&gt;&lt;span class="w"&gt;  &lt;/span&gt;npm list stringify-object                                                      1 ↵
&lt;span class="go"&gt;node-play@0.0.0 /Users/mihnea/code/node-play
├─┬ lint-staged@10.5.4
│ └── stringify-object@3.3.0
└─┬ rollup-plugin-workbox@6.2.0
  └─┬ workbox-build@6.5.4
    └── stringify-object@3.3.0 deduped
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gorgeous. &lt;code&gt;npm list&lt;/code&gt; is indeed capable of focusing on one &lt;em&gt;leaf&lt;/em&gt; in the deps tree.&lt;/p&gt;

&lt;p&gt;In closing, &lt;em&gt;package.json&lt;/em&gt; and &lt;em&gt;node_modules&lt;/em&gt; are one of the regrets of nodejs creator Ryan Dahl, as beautifully and wholeheartedly stated in &lt;a href="https://www.youtube.com/watch?v=M3BM9TB-8yA&amp;amp;t=591s"&gt;JSConf 2018&lt;/a&gt;.&lt;br&gt;
Luckily, having the proper knowledge on the npm tooling at hand, we can make npm work for us, rather than against us.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>npm</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
