<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Salma Alam-Naylor</title>
    <description>The latest articles on Forem by Salma Alam-Naylor (@whitep4nth3r).</description>
    <link>https://forem.com/whitep4nth3r</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%2F492757%2F404b3ab3-6e90-4183-99a6-b116c579ecfe.png</url>
      <title>Forem: Salma Alam-Naylor</title>
      <link>https://forem.com/whitep4nth3r</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/whitep4nth3r"/>
    <language>en</language>
    <item>
      <title>How to make your first contribution to an open source project</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Tue, 03 Mar 2026 12:25:26 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/how-to-make-your-first-contribution-to-an-open-source-project-5e50</link>
      <guid>https://forem.com/whitep4nth3r/how-to-make-your-first-contribution-to-an-open-source-project-5e50</guid>
      <description>&lt;p&gt;Getting involved in open source doesn't have to be scary! Understand how to find a great project and make your first contribution in this guide.&lt;/p&gt;




&lt;p&gt;I recently (and accidentally) became a maintainer of a new open source project, &lt;a href="https://npmx.dev/" rel="noopener noreferrer"&gt;npmx.dev&lt;/a&gt;. The project’s vision is to provide a new way to browse the npm package registry, with some exciting bonus features.&lt;/p&gt;

&lt;p&gt;I’ve always been on the fringes of open source; I’ve contributed to a few projects here and there, such as the &lt;a href="https://github.com/withastro/docs/pull/8476" rel="noopener noreferrer"&gt;Astro docs&lt;/a&gt;, &lt;a href="https://github.com/GoogleChrome/lighthouse/pull/13412" rel="noopener noreferrer"&gt;Google Lighthouse&lt;/a&gt;, and some others, and most of my code on GitHub is open source for the wider community. But, contributing to open source projects can be scary: big codebases, unfamiliar tech, lots of new people, and a sea of open issues can make it hard to know where to start.&lt;/p&gt;

&lt;p&gt;However, open source isn’t really all about &lt;em&gt;code&lt;/em&gt;, it’s about &lt;em&gt;community&lt;/em&gt;. Since my involvement in npmx, I’ve experienced first-hand what a welcoming and inclusive approach to open source can do to empower anyone to make a variety of contributions to help make The Web ecosystem a great place to be and work.&lt;/p&gt;

&lt;p&gt;And so, with that experience and some great examples of what good looks like in open source, and because npmx just announced their &lt;a href="https://npmx.dev/blog/alpha-release" rel="noopener noreferrer"&gt;alpha release&lt;/a&gt;, I thought I’d put together a guide on how to get involved in open source to help you get started.&lt;/p&gt;

&lt;p&gt;Throughout this guide, I’ll be using some specific open source terms. Here's what they mean:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Open source&lt;/strong&gt;: a software development model that encourages open collaboration, with source code, documentation, and discussion around the development of the project freely available to the public.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Issue&lt;/strong&gt;: A ticket used to track bugs, features, questions, or tasks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pull Request (PR)&lt;/strong&gt;: a request to merge any changes into the main project, and to review and discuss those changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintainer&lt;/strong&gt;: a key contributor to the project who leads, manages, and steers the direction of the project. Maintainers are responsible for reviewing and merging pull requests, managing issues, and taking care of the community, usually acting as the final decision-makers. Some maintainers may also be called &lt;strong&gt;stewards&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contributor&lt;/strong&gt;: anyone who has contributed anything to an open source project, whether it is code, documentation, testing and reviewing pull requests, design, finding issues, community management, or anything else related to the project.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Where this guide provides specific examples on things such as pull requests and issues, the examples will be specific to &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;, as that's where all the action is happening for npmx.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Find a cool project
&lt;/h2&gt;

&lt;p&gt;The first step is to find a project that you are excited about. Maybe it’s a library or tool you already use that you want to help improve, or perhaps its a project that you really want to see succeed, or it could be that some of your friends are working on something fun.&lt;/p&gt;

&lt;p&gt;Your interests matter more than the popularity of the project, and your time is valuable. If you care about the problems that the project is solving, you’ll be more motivated to contribute and invest more of your time in the project.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Making ten contributions to a single project is much more valuable for &lt;u&gt;you&lt;/u&gt; than making ten contributions to ten different projects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And don’t worry if you don’t feel like you’re unqualified to contribute: you are.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Read the community guidelines
&lt;/h2&gt;

&lt;p&gt;Before making your first contribution, look for the project’s community guidelines or code of conduct. You can usually find this type of document in the root of a project repository, named &lt;code&gt;CODE_OF_CONDUCT.md&lt;/code&gt; or similar.&lt;/p&gt;

&lt;p&gt;A code of conduct should help you understand what you can expect from the community: how people treat each other, how conflict is handled, and what behaviour is encouraged or discouraged. A great example is the &lt;a href="https://github.com/npmx-dev/npmx.dev/blob/main/CODE_OF_CONDUCT.md" rel="noopener noreferrer"&gt;npmx code of conduct&lt;/a&gt;, outlining the community’s standards and the responsibilities of the project maintainers.&lt;/p&gt;

&lt;p&gt;If your chosen project doesn’t have a code of conduct or community standards, you might consider skipping it. That being said, your first contribution &lt;em&gt;could&lt;/em&gt; be to create these community standards from one of the &lt;a href="https://opensource.guide/code-of-conduct/" rel="noopener noreferrer"&gt;many templates available&lt;/a&gt;. If you’re comfortable agreeing to the code of conduct for your chosen project, move on to the next step!&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Browse closed pull requests
&lt;/h2&gt;

&lt;p&gt;Take a look at some closed pull requests to help you understand more about the project culture and direction, and how maintainers and contributors work together. It will also give you an idea of how the community standards are being upheld. Some questions you can ask yourself:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What kind of work is being contributed?&lt;/li&gt;
&lt;li&gt;Are reviews kind and constructive?&lt;/li&gt;
&lt;li&gt;How are mistakes or incomplete work handled?&lt;/li&gt;
&lt;li&gt;If the project is busy, how are multiple pull requests addressing the same issue handled?&lt;/li&gt;
&lt;li&gt;What’s missing from contributions?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you’re browsing a project on GitHub, you can find the closed PRs by navigating to the pull requests page, and filtering by closed.&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%2Fdr58x6koycrg7f55bua0.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%2Fdr58x6koycrg7f55bua0.png" alt="A list of closed PRS on GitHub from the npmx.dev project. This filter is achieved by clicking on the closed filter at the top of the list." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Check the contributors list
&lt;/h2&gt;

&lt;p&gt;Next, take a look at the contributors list. A healthy and active project often has:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Many contributors (not just one or two people doing everything)&lt;/li&gt;
&lt;li&gt;Recent activity&lt;/li&gt;
&lt;li&gt;A visible breadth of contributors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While you can’t conclude everything from avatars and usernames, immediate visual diversity can be a strong signal that the project is welcoming to all kinds of people. This, in my opinion, always makes for a more exciting project to get involved with. It's been really wholesome to see &lt;a href="https://npmx.dev/about" rel="noopener noreferrer"&gt;how many contributors have been working on npmx so far&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Explore open issues
&lt;/h2&gt;

&lt;p&gt;Exploring open issues will help you get an idea of what needs to be worked on. Issues may be bugs, tasks, larger feature requests, or discussions about ideas that are not yet set in stone. Project maintainers will often use helpful issue labels to categorise issues based on skills or areas of the project. When you’re just starting out, it’s a good idea to look for issues with the label &lt;code&gt;good first issue&lt;/code&gt;, or you could filter issues by your area of expertise.&lt;/p&gt;

&lt;p&gt;For example, when joining a new project, I often use the issue filter to surface good first issues, or issues labelled &lt;code&gt;front&lt;/code&gt; or &lt;code&gt;front end&lt;/code&gt;, &lt;code&gt;a11y&lt;/code&gt; or &lt;code&gt;accessibility&lt;/code&gt;, or &lt;code&gt;docs&lt;/code&gt;, as those are my areas of expertise. Another good label to look for is &lt;code&gt;help wanted&lt;/code&gt;, as this type of issue is usually more of a discussion around planning an approach to solving a problem.&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%2F27luf900vhx6q5luxm8m.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%2F27luf900vhx6q5luxm8m.png" alt="A list of issues labelled with good first issue on the npmx.dev project on GitHub. This view is achieved by using the filter options in the UI, and their configuration is represented as a text query in the search box at the top of the list." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For your first contribution, I recommend choosing a small, low-lift issue. A lot of the time investment when making your first contribution is taking time to understand the code or the documentation, learning the process of contributing, and ultimately, building relationships with other contributors and maintainers as you move through the process. Choosing a smaller issue means less cognitive overheads for you, and more opportunity to make a meaningful impact. For example, my first contribution to npmx was &lt;a href="https://github.com/npmx-dev/npmx.dev/pull/514" rel="noopener noreferrer"&gt;a pull request to fix the alignment of the logo in the header&lt;/a&gt;. This pull request fixed &lt;a href="https://github.com/npmx-dev/npmx.dev/issues/498" rel="noopener noreferrer"&gt;a very small issue&lt;/a&gt; that was reported by another contributor that allowed me to open my first pull request with minimal effort.&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%2Ft7n33e2g61dzkugsttxx.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%2Ft7n33e2g61dzkugsttxx.png" alt="Screenshot of my a PR in GitHub with the title fix: center align icon in nav, which shows I added two CSS classes, flex and items-center to a div inside the header." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In a very active open source project, there may be multiple open pull requests that address the same issue. This could feel a little daunting at first (and it’s sometimes tricky for maintainers to manage), but it’s usually not a big deal and can be managed effectively. If you’re worried about this and don’t want to attempt something that is already in progress, GitHub helpfully identifies which issues have open PRs on the issues list with an icon, which I’ve highlighted on the image below.&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%2Fzg8mhtrebuyoj1yvnpx0.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%2Fzg8mhtrebuyoj1yvnpx0.png" alt="A list of open issues on the npmx.dev repository." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Read the contributing guide
&lt;/h2&gt;

&lt;p&gt;When you’ve found an issue you’d like to make a contribution for, it’s time to understand how the process works. Well-maintained open source projects will have a contribution guide in the project, which you can usually find in the root of a project repository, named &lt;code&gt;CONTRIBUTING.md&lt;/code&gt;. A contributing guide is usually geared towards contributing to code or documentation, and will include instructions on how to set up the project, maintaining a consistent code style, testing, and how to format your pull requests.&lt;/p&gt;

&lt;p&gt;If you get stuck or notice something confusing or outdated whilst you’re trying to set up the project, you may have found your first opportunity for a contribution! In fact, when setting up the npmx project, I wasn’t sure how the code formatting worked because it wasn’t clear in the contributing guide. And so, after discussing with other maintainers, I opened &lt;a href="https://github.com/npmx-dev/npmx.dev/pull/523" rel="noopener noreferrer"&gt;a pull request to clarify how code is formatted&lt;/a&gt;.&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%2Fq4i6ia2rc2fwiqt3b3ph.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%2Fq4i6ia2rc2fwiqt3b3ph.png" alt="A merged PR on GitHub showing I added the following text to the contributing.md: When committing changes, try to keep an eye out for unintended formatting updates. These can make a pull request look noisier than it really is and slow down the review process. Sometimes IDEs automatically reformat files on save, which can unintentionally introduce extra changes. To help with this, the project uses  raw `oxfmt` endraw  to handle formatting via a pre-commit hook. The hook will automatically reformat files when needed. If something can’t be fixed automatically, it will let you know what needs to be updated before you can commit. If you want to get ahead of any formatting issues, you can also run  raw `pnpm lint:fix` endraw  before committing to fix formatting across the whole project." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Chat with the community
&lt;/h2&gt;

&lt;p&gt;Many projects have a Discord, Slack, or other space for chatting with the community, which will usually be linked somewhere in the project repository or in the project itself. If you want help or just want to chat about the project and what issues would be good to tackle, it’s a great idea to join one of those spaces. It’s also a good opportunity to check that the community standards are being upheld and that you feel welcomed by the maintainers and contributors when you join.&lt;/p&gt;

&lt;p&gt;Also, don’t feel like you need to jump in and get involved straight away. It can be daunting to jump into an active chat stream of people who are actively working on a project. Take your time, and do a little lurking until you feel comfortable enough to take part.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Open a pull request
&lt;/h2&gt;

&lt;p&gt;If you’ve found an open issue and you know how to tackle it, you can usually do the work and open a pull request without asking for it to be assigned to you. That being said, in a very active project it is always helpful to leave a comment on an issue stating that you intend to work on it.&lt;/p&gt;

&lt;p&gt;Communication in open source is key, especially with many people working asynchronously on a project across multiple time zones, day and night. But on the other hand, a very active project can feel very noisy and overwhelming, and more often than not, maintainers will appreciate your initiative when it comes to direct contributions, rather than the extra admin of assigning people to issues, and the extra time it takes for contributors to wait for permission.&lt;/p&gt;

&lt;p&gt;To open a code-based pull request, &lt;a href="https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/fork-a-repo" rel="noopener noreferrer"&gt;fork the repository&lt;/a&gt; to your own GitHub account using the fork button on the main page of the repository, and clone your fork of the repository to your local machine.&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%2Fowhylwwkm3lmatyonzc8.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%2Fowhylwwkm3lmatyonzc8.png" alt="The fork button at the top of the npmx repository showing that I have one existing fork." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you've cloned the repository to your local machine, create a new branch off of main to make your changes. When you push those changes to your own GitHub fork, you'll see a banner at the top of your repository page with a "Compare &amp;amp; pull request" button.&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%2F8jhvv0wmhkkmosh2b9nq.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%2F8jhvv0wmhkkmosh2b9nq.png" alt="A banner at the top of my fork of the npmx repository showing that fix-123 had recent pushes 11 seconds ago, with the compare and pull request button to the right." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click this button to write a title and description for your PR, making sure to follow the contributing guidelines. Then, click "Create pull request". In an active project, you probably won't need to message the maintainers to notify them that you've submitted a PR, as they'll be watching for pull requests coming in. I know you're probably really excited to make your first contribution, but be patient in waiting for a review and approval!&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%2F8n8djmeap6tx9pm9d2pk.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%2F8n8djmeap6tx9pm9d2pk.png" alt="A PR title fix: update readme with the description: this PR adds clarity to the README about submitting pull requests, fixes #123." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Not every PR needs an issue
&lt;/h2&gt;

&lt;p&gt;If you spot a typo, a small refactor, or an improvement worth making, you can propose it directly with a PR rather than creating an issue. Make sure to include a clear description of the change and why it’s useful, especially if it’s your first contribution. Even if your pull request is not accepted, you’ve practised the contribution workflow, so you’re ready for the next issue.&lt;/p&gt;

&lt;p&gt;Even if someone else submits a similar PR before you, your work won’t be wasted. Maintainers may still merge your pull request, borrow ideas from it, or use it to improve the final solution. This happened to me on an early PR for npmx, where I made &lt;a href="https://github.com/npmx-dev/npmx.dev/pull/545" rel="noopener noreferrer"&gt;a small change to the Open Graph images for the package pages&lt;/a&gt;, which will eventually be superseded by a full redesign of the Open Graph images across the project.&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%2F4ogwpkhqejzliva9md5a.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%2F4ogwpkhqejzliva9md5a.png" alt="A merged PR on GitHub to the npmx.dev repository showing I added an inline star SVG to the open graph image, with the number of stars to the right of it." width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Not every contribution has to be code
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In open source, all contributions are valuable&lt;/strong&gt;, whether or not they make it into the project codebase or documentation. Finding and reporting issues, requesting or suggesting features, reviewing and testing pull requests, opening PRs that don’t get merged, updating documentation, and welcoming people into the community are all valuable ways to get involved. Participating in open source projects gives you a wealth of opportunities to use your existing strengths, or learn new skills to add to your experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Get involved
&lt;/h2&gt;

&lt;p&gt;In my experience, open source really is about humans, rather than code. Open source projects have huge potential to bring people together and solve problems for the people that work on The Web, making the ecosystem (and, optimistically, the world) better for everyone to benefit.&lt;/p&gt;

&lt;p&gt;If you’re looking for a great open source experience to get involved in, I would highly recommend the npmx project, who welcomed me with open arms from the outset. Find an open issue, give it a try, and join us in the &lt;a href="https://build.npmx.dev/" rel="noopener noreferrer"&gt;npmx Discord&lt;/a&gt; to experience a truly wholesome community approach to building great tools for The Web. Start small, and have fun!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to delete all squash-merged local git branches with one terminal command</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Mon, 08 Sep 2025 08:17:04 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/how-to-delete-all-squash-merged-local-git-branches-with-one-terminal-command-1p11</link>
      <guid>https://forem.com/whitep4nth3r/how-to-delete-all-squash-merged-local-git-branches-with-one-terminal-command-1p11</guid>
      <description>&lt;p&gt;In 2022 I wrote about how I use a bash function to &lt;a href="https://whitep4nth3r.com/blog/delete-all-merged-git-branches-one-terminal-command/" rel="noopener noreferrer"&gt;delete all merged git branches with a single terminal command&lt;/a&gt;. This works great for branches that have been &lt;em&gt;merged&lt;/em&gt;, but not &lt;em&gt;squashed&lt;/em&gt;. Given the team I'm working on right now like to squash and merge pull requests on GitHub, and also how I like to keep my dev environment clean, it was time to update the clean up function to take squashed branches into account.&lt;/p&gt;

&lt;p&gt;Now, this was a total rabbit hole I went down, so bear with me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The difference between "merge" and "squash and merge"
&lt;/h2&gt;

&lt;p&gt;The default option when merging pull requests on GitHub is &lt;strong&gt;merge&lt;/strong&gt;. When you &lt;strong&gt;merge&lt;/strong&gt; a pull request on GitHub, all commits from a feature branch are added to the base branch in a &lt;strong&gt;merge commit&lt;/strong&gt;. A merge commit preserves the full history of the changes being merged, allowing you to see an intertwining history of events that happened on both branches after a feature branch is merged into the base branch.&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%2Fwsx4lbnyhzhchdr2yly6.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%2Fwsx4lbnyhzhchdr2yly6.png" alt="All checks have passed. 1 neutral, 3 successful checks. No conflicts with base branch. Merging can be performed automatically. Merge pull request call to action green button." width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On GitHub, a default merge uses the &lt;a href="https://git-scm.com/docs/git-merge#Documentation/git-merge.txt---no-ff" rel="noopener noreferrer"&gt;--no-ff option in git&lt;/a&gt;, which means &lt;strong&gt;no fast-forward&lt;/strong&gt;. This option is what creates the &lt;strong&gt;merge commit&lt;/strong&gt; and allows you to inspect the complete history of both the feature and base branches.&lt;/p&gt;

&lt;p&gt;When you &lt;strong&gt;squash and merge&lt;/strong&gt; a pull request, all commits on the feature branch are "squashed" into a single commit, using the &lt;strong&gt;fast-forward&lt;/strong&gt; option. A &lt;strong&gt;fast-forward&lt;/strong&gt; commit merges all file changes after the most recent change on the base branch. This loses the distinct feature branch timeline of changes. This can be useful when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You want to keep your commit history tidy on the base branch&lt;/li&gt;
&lt;li&gt;You're merging small changes on short-lived branches&lt;/li&gt;
&lt;li&gt;You don't need to preserve the feature branch history&lt;/li&gt;
&lt;/ol&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%2F5re7oqj0uz4avrs9vwzn.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%2F5re7oqj0uz4avrs9vwzn.png" alt="All checks have passed. 1 neutral, 3 successful checks. No conflicts with base branch. Merging can be performed automatically. Squash and merge pull request call to action green button." width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why the original bash script doesn't work for squashed branches
&lt;/h2&gt;

&lt;p&gt;Here's the original bash script I wrote to delete all merged branches. The first line, &lt;code&gt;git checkout main &amp;amp;&amp;amp; git branch --merged&lt;/code&gt;, checks out the main branch, and lists all branches that can be detected as being merged into the main branch.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# delete all branches merged into main&lt;/span&gt;
dam&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Deleting all merged branches ==="&lt;/span&gt;
  git checkout main &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git branch &lt;span class="nt"&gt;--merged&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-vE&lt;/span&gt; &lt;span class="s2"&gt;"(^&lt;/span&gt;&lt;span class="se"&gt;\*&lt;/span&gt;&lt;span class="s2"&gt;|main)"&lt;/span&gt; | xargs git branch &lt;span class="nt"&gt;-d&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"☑️ Done!"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you do a &lt;strong&gt;squash merge&lt;/strong&gt;, Git takes all the changes from the feature branch, compresses them into a &lt;em&gt;new commit&lt;/em&gt;, and applies it to main as the latest change. The original branch’s commits are &lt;strong&gt;not in the history&lt;/strong&gt;, so Git still sees that branch as “not merged". The &lt;code&gt;git branch --merged&lt;/code&gt; command won't match any branches, and so won't find any branches to delete.&lt;/p&gt;

&lt;h2&gt;
  
  
  The script that finds and deletes squashed branches
&lt;/h2&gt;

&lt;p&gt;To delete all squashed branches that merged using the fast-forward option we need to take a different approach. This script is named dams(), which stands for "delete all merged squashed". To use the script:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;add the following code to your .bashrc or .zshrc file (switch out main for what you usually call your main branches if necessary)&lt;/li&gt;
&lt;li&gt;save the file&lt;/li&gt;
&lt;li&gt;source the new changes (or reload your terminal)&lt;/li&gt;
&lt;li&gt;run dams in a git project directory (without the brackets)&lt;/li&gt;
&lt;li&gt;enjoy the cleanup!&lt;/li&gt;
&lt;li&gt;(This may need to be adjusted according to your shell, please don't come for me.)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;dams&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Deleting merged and squash-merged branches ==="&lt;/span&gt;

  &lt;span class="c"&gt;# Ensure main is checked out and up to date&lt;/span&gt;
  git checkout main &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
  git pull &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;

  &lt;span class="c"&gt;# Loop over all local branches except main&lt;/span&gt;
  &lt;span class="k"&gt;for &lt;/span&gt;branch &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;git &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="nt"&gt;-each-ref&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'%(refname:short)'&lt;/span&gt; &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;refs/heads/main refs/heads/&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Skip if branch does not exist on remote&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; git ls-remote &lt;span class="nt"&gt;--exit-code&lt;/span&gt; &lt;span class="nt"&gt;--heads&lt;/span&gt; origin &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Skipping &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt; (not on remote)"&lt;/span&gt;
      &lt;span class="k"&gt;continue
    fi&lt;/span&gt;

    &lt;span class="c"&gt;# Delete only if content is fully in main&lt;/span&gt;
    &lt;span class="k"&gt;if &lt;/span&gt;git diff &lt;span class="nt"&gt;--quiet&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; main&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;git branch &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deleted &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;else
      &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Keeping &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt; (has unmerged changes)"&lt;/span&gt;
    &lt;span class="k"&gt;fi
  done

  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"☑️ Done!"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's break down what the script does, and learn some things about Git!&lt;/p&gt;

&lt;h3&gt;
  
  
  Check out the main branch and update it
&lt;/h3&gt;

&lt;p&gt;First we want to make sure we checkout main and pull in the latest changes to compare the other branches against.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git checkout main &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git pull &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Loop over local branches and check for changes
&lt;/h3&gt;

&lt;p&gt;Here, the script loops over the branch names returned from the command &lt;code&gt;[git for-each-ref](https://git-scm.com/docs/git-for-each-ref)&lt;/code&gt;, which iterates over all branches (or refs) that match a &lt;strong&gt;pattern&lt;/strong&gt; and shows them according to the given &lt;strong&gt;format&lt;/strong&gt;. The &lt;strong&gt;pattern&lt;/strong&gt; excludes the main branch (&lt;code&gt;--exclude&lt;/code&gt;), and the &lt;code&gt;--format&lt;/code&gt; requests the short branch name. &lt;code&gt;refs/heads/&lt;/code&gt; at the end of the line instructs the script to look only at local branches.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;for &lt;/span&gt;branch &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;git &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="nt"&gt;-each-ref&lt;/span&gt; &lt;span class="nt"&gt;--format&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;'%(refname:short)'&lt;/span&gt; &lt;span class="nt"&gt;--exclude&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;refs/heads/main refs/heads/&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check if a local branch has been pushed to the remote
&lt;/h3&gt;

&lt;p&gt;This following code runs &lt;code&gt;[git ls-remote](https://git-scm.com/docs/git-ls-remote)&lt;/code&gt; to check if the branch in the loop has been pushed to the remote to avoid deleting branches that haven't been pushed. The &lt;code&gt;--exit-code&lt;/code&gt; flag instructs the command to exit with status "2" when no matching refs are found in the remote repository. In Bash, if considers &lt;strong&gt;exit code 0 as true&lt;/strong&gt; and non-zero as false. Exit code 2 will evaluate to false, so with the ! at the start of the &lt;code&gt;if&lt;/code&gt;, we're checking if &lt;code&gt;git ls-remote&lt;/code&gt; returns false. If it does, we skip deleting that branch.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;&amp;gt;/dev/null 2&amp;gt;&amp;amp;1&lt;/code&gt; part instructs the script to throw away both stdout and stderr output so that it produces no output at all, to keep the terminal free of noise. The script still produces a success or failure via the exit code, but suppresses all output.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Skip if branch does not exist on remote&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; git ls-remote &lt;span class="nt"&gt;--exit-code&lt;/span&gt; &lt;span class="nt"&gt;--heads&lt;/span&gt; origin &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;/dev/null 2&amp;gt;&amp;amp;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Skipping &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt; (not on remote)"&lt;/span&gt;
  &lt;span class="k"&gt;continue
fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check for diffs and delete the local branch
&lt;/h3&gt;

&lt;p&gt;This part of the script checks for diffs between the branch in the loop and the main branch. Again, in Bash, if considers &lt;strong&gt;exit code 0 as true&lt;/strong&gt; and non-zero as false, so whilst this may look backwards compared traditional programming languages, if there is no diff found between the branches, then the branch will be deleted using &lt;code&gt;[git branch -D](https://git-scm.com/docs/git-branch#Documentation/git-branch.txt--D)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I decided to use the &lt;code&gt;-D&lt;/code&gt; flag to force the delete in this script, seeing as I'm operating on my local machine and it's safe to force delete local branches in my case, especially if we have checked at the start of the script if the local branch has been pushed to the remote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Delete only if content is fully in main&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;git diff &lt;span class="nt"&gt;--quiet&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; main&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;git branch &lt;span class="nt"&gt;-D&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Deleted &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Keeping &lt;/span&gt;&lt;span class="nv"&gt;$branch&lt;/span&gt;&lt;span class="s2"&gt; (has unmerged changes)"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It uses the &lt;code&gt;--quiet&lt;/code&gt; flag to suppress all output, as we don't need to view that whilst the script runs. Without the &lt;code&gt;--quiet&lt;/code&gt; flag, here's what the command outputs in isolation when there is a diff:&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%2Fc3m1ca0spu8kq2y9e7pf.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%2Fc3m1ca0spu8kq2y9e7pf.png" alt="Running git diff branch-6 main in a terminal showing a diff in the output." width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And here's how the output looks when the full script runs and finds some branches to delete that have been squashed and merged on GitHub:&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%2F7ozas7b5e92xpp7jm7p5.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%2F7ozas7b5e92xpp7jm7p5.png" alt="Running the delete all merged and squashed branches script showing main has been checked out and pulled. Then branch 5 was deleted and branch 6 was skipped because it is not on the remote." width="800" height="710"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Probably don't use this script
&lt;/h2&gt;

&lt;p&gt;You probably shouldn't trust random bash scripts written by random people found on the internet, especially where your precious version-controlled work is concerned, so you probably shouldn't use this. This is my disclaimer. &lt;strong&gt;Use this script with caution!&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
      <category>bash</category>
    </item>
    <item>
      <title>Why is CSS ::first-letter not working?</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Wed, 20 Aug 2025 09:31:56 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/why-is-css-first-letter-not-working-156p</link>
      <guid>https://forem.com/whitep4nth3r/why-is-css-first-letter-not-working-156p</guid>
      <description>&lt;p&gt;I recently had a use for the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/::first-letter" rel="noopener noreferrer"&gt;CSS ::first-letter pseudo element&lt;/a&gt;. I was dealing with some inconsistently formatted strings from the back end, and wanted to make sure that on the front end, all strings were shown with lowercase letters except for the first, which needed to be uppercase. I thought it would be trivial to use the following CSS:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.parentElement&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;lowercase&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.parentElement&lt;/span&gt;&lt;span class="nd"&gt;::first-letter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;text-transform&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;uppercase&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;In my case, however, the first letter was not being uppercased, and I was confused about why. Here is a modified version of the HTML I was attempting to style:&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;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"parentElement"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"child1"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;svg&lt;/span&gt; &lt;span class="na"&gt;width=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt; &lt;span class="na"&gt;height=&lt;/span&gt;&lt;span class="s"&gt;"16"&lt;/span&gt; &lt;span class="na"&gt;xmlns=&lt;/span&gt;&lt;span class="s"&gt;"http://www.w3.org/2000/svg"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="nt"&gt;&amp;lt;path&amp;gt;&lt;/span&gt;...&lt;span class="nt"&gt;&amp;lt;/path&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;/svg&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;span&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"child2"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    inconsistently FormattED string
  &lt;span class="nt"&gt;&amp;lt;/span&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Naïvely, I thought I would be able to apply the styles on the div with the class &lt;code&gt;parentElement&lt;/code&gt;, and the styles would cascade down to the span with the class child2. However, it turns out that the &lt;code&gt;::first-letter&lt;/code&gt; pseudo element selector can only target text under a certain set of conditions.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ::first-letter spec
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;The &lt;strong&gt;::first-letter&lt;/strong&gt; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS" rel="noopener noreferrer"&gt;CSS&lt;/a&gt; pseudo-element applies styles to the first letter of the first line of a &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_display/Visual_formatting_model#block_containers" rel="noopener noreferrer"&gt;block container&lt;/a&gt;, but only when not preceded by other content (such as images or inline tables).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;When drilling down into what exactly defines a “&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_display/Visual_formatting_model#block_boxes" rel="noopener noreferrer"&gt;block container&lt;/a&gt;”, there is definitely some ambiguity across the CSS spec: “In specifications, block boxes, block-level boxes, and block containers are all referred to as &lt;strong&gt;block boxes&lt;/strong&gt; in certain places. These things are somewhat different and the term block box should only be used if there is no ambiguity.” I won’t go deep into the specifics of block boxes and block containers in this post, but I will attempt to provide a summary:&lt;/p&gt;

&lt;p&gt;An element is a block container only if it contains block-level or inline-level boxes. The following values for the CSS display property produce block containers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;block&lt;/li&gt;
&lt;li&gt;inline-block&lt;/li&gt;
&lt;li&gt;list-item&lt;/li&gt;
&lt;li&gt;table-cell&lt;/li&gt;
&lt;li&gt;table-caption&lt;/li&gt;
&lt;li&gt;flow-root&lt;/li&gt;
&lt;li&gt;inline (on one condition: inline elements become block containers when they contain inline text! The &lt;a href="https://www.w3.org/TR/CSS22/visuren.html#inline-boxes" rel="noopener noreferrer"&gt;spec&lt;/a&gt; is difficult to read but I think I got the gist.)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The following values for the CSS display property produce &lt;em&gt;block-level boxes&lt;/em&gt;, but not &lt;em&gt;block containers&lt;/em&gt;, given how their child elements are formatted:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;flex&lt;/li&gt;
&lt;li&gt;grid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key issue in my case was that I was attempting to target a non-block container; the &lt;code&gt;parentElement&lt;/code&gt; class specified a display property of flex and attempting to cascade the styles for &lt;code&gt;::first-letter&lt;/code&gt; down to a child element.&lt;/p&gt;

&lt;h2&gt;
  
  
  The rules of ::first-letter
&lt;/h2&gt;

&lt;p&gt;To summarise, using CSS &lt;code&gt;::first-letter&lt;/code&gt; will not work in the following conditions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The element you are targeting is set to &lt;code&gt;display: flex&lt;/code&gt; or &lt;code&gt;display: grid&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;The element you are targeting is preceded by other content, such as a ::before pseudo element, images or inline tables&lt;/li&gt;
&lt;li&gt;You are attempting to cascade &lt;code&gt;::first-letter&lt;/code&gt; styles from a parent element, even if the elements are block containers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To make sure CSS &lt;code&gt;::first-letter&lt;/code&gt; works for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply the &lt;code&gt;::first-letter&lt;/code&gt; styles directly to a block container (and those block containers are specified above)&lt;/li&gt;
&lt;li&gt;Ensure the content you are attempting to target is not preceded by other content, such as a &lt;code&gt;::before&lt;/code&gt; pseudo element, images or inline tables&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  A note on browser support
&lt;/h2&gt;

&lt;p&gt;CSS ::first-letter may have limited browser support: &lt;a href="https://caniuse.com/?search=initial-letter" rel="noopener noreferrer"&gt;caniuse.com&lt;/a&gt; reports this pseudo element selector is not supported in Firefox, but Baseline reports that "This feature is well established and works across many devices and browser versions. It’s been available across browsers since ⁨July 2015⁩."&lt;/p&gt;

&lt;h2&gt;
  
  
  Using ::first-letter in action
&lt;/h2&gt;

&lt;p&gt;To better understand how &lt;code&gt;::first-letter&lt;/code&gt; works, I threw together some examples of when this pseudo element can be correctly targeted, and when it fails to work. You can view the examples at &lt;a href="https://css_first_letter.toddle.site/" rel="noopener noreferrer"&gt;CSS first-letter demo&lt;/a&gt;, and you can &lt;a href="https://editor.nordcraft.com/projects/css_first_letter/branches/main/components/HomePage" rel="noopener noreferrer"&gt;view the code here&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>css</category>
      <category>webdev</category>
      <category>html</category>
    </item>
    <item>
      <title>Why Women in Tech isn't enough</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Thu, 17 Jul 2025 06:47:18 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/why-women-in-tech-isnt-enough-2cah</link>
      <guid>https://forem.com/whitep4nth3r/why-women-in-tech-isnt-enough-2cah</guid>
      <description>&lt;h2&gt;
  
  
  Disclaimer
&lt;/h2&gt;

&lt;p&gt;This article is based entirely on my personal experience as a woman in the technology industry. I have no doubt that there are organisations and initiatives that are putting in incredible work to improve experiences and opportunities for "non-men" in the industry, and genuinely helping to improve equity in hiring pipelines in tech. If you’ve found safety and opportunity in such spaces as described below, I am truly happy for you.&lt;/p&gt;

&lt;p&gt;This article does not intend to belittle the efforts of such initiatives, but highlight that they may not be working for everyone as intended. I am most certainly not advocating for funding cuts or erasure around DEI initiatives, but only that we rethink what is not working.&lt;/p&gt;




&lt;p&gt;The technology industry (and beyond) is performative, often offering shallow solutions to deeper problems, shifting the responsibility of change onto those that bear the brunt of the dire consequences the world has created for itself. &lt;em&gt;Want to prevent climate change?&lt;/em&gt; Use paper straws instead of holding corporations accountable for their increasing carbon emissions. &lt;em&gt;Want to protect your mental health online?&lt;/em&gt; Limit your screen time using app-blocking tools instead of questioning why social media platforms have been deliberately engineered to be addictive. &lt;em&gt;Want to create equal opportunities in the technology industry?&lt;/em&gt; Segregate all the women, non-binary, intersex, LGBTQIA+ identifying and trans folk under the banner “Women in Tech” and hope they figure it all out.&lt;/p&gt;

&lt;p&gt;At most of the tech companies I have worked, there have been dedicated spaces for “non-men” to get together, including Slack channels, informal meet-ups, and formal discussion panels. “Non-men” in this context has been used to discount “non-heterosexual-cis-men”, and to include women, non-binary, intersex, trans women, trans men and those identifying as LGBTQIA+ all at once. The people spanning the very wide spectrum of this group have probably, and unfortunately, all experienced some kind of discrimination in the workplace, and so it seems sensible for a company to put us all together to share our experiences in a safe and enclosed space, right? It helps, but I'm not so sure it offers a full solution.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with “non-men” spaces
&lt;/h2&gt;

&lt;p&gt;Reports on gender statistics in the technology industry have consistently published figures of around 17-25% of women and non-binary people working in this industry since the early 2000s (this varies by geographical location), and not much has changed over the last 25 years. A recent &lt;a href="https://spacelift.io/blog/women-in-tech-statistics" rel="noopener noreferrer"&gt;statistics dump by Spacelift&lt;/a&gt; reports that “half of all women who work in tech have left the industry by age 35”, and “none of the biggest US tech companies report women occupying more than a quarter of all technical roles”. Furthermore, “the proportion of undergraduate computer science degrees awarded to women has fallen from 37% in 1985 to about 20% today.”&lt;/p&gt;

&lt;p&gt;Why are the statistics not showing much improvement despite countless initiatives surrounding diversity being created, and in particular events, awards, and “safe” spaces for “Women in Tech”? I have a hypothesis: all of these initiatives are operating in closed and exclusive spaces, which is sending a strong signal to the male majority with the power to affect real change that they are not welcome here, and it &lt;em&gt;is not their problem to solve&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;A few years ago I was nominated for a “Women in Tech” award by an anonymous party. Not only did I have to confirm my nomination by writing a number of time-consuming essays about my achievements and eligibility for the award, I also couldn’t shake the weird feeling that I was nominated only on the basis that I am a woman. I understand the need to celebrate and lift up “non-men” in tech, and to provide a platform for representation to young and less experienced people entering the industry, but I wasn’t comfortable with demonstrating that if you want to succeed in the tech industry you need special awards and events under the banner of your gender. I did not accept the nomination; I want to win awards that the men are eligible for, too. Because I can, and I have.&lt;/p&gt;

&lt;p&gt;These enclosed “non-men” spaces are also not without their specific problems. At one company I worked for, I was asked to participate in a “Senior Women in Tech Panel”, where I was invited to share my experiences and career progression in tech to an audience of women, non-binary, and trans men and women. This event was not moderated well, and descended into a chaotic discussion about how many children each of the panel members had, and negative remarks about the ethnicity and representation of the panel speakers. This may have been a one-off, but at that point I decided to leave the closed Slack channel for “non-men”, and chose not to participate in events of this type for the rest of my career.&lt;/p&gt;

&lt;p&gt;What's more, the hard work of ensuring that workplaces are equitable often falls upon the shoulders of underrepresented groups, who are already carrying the burden of discrimination, being overlooked for promotions, and other related issues. A friend reports:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;They've started a women's network at work and I am not a member because I think these initiatives are basically just making female members of staff do extra work to fix organisational problems.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The problem with women-coded labels
&lt;/h2&gt;

&lt;p&gt;Imagine if men described themselves as a “male founder” or “HeTO” (a male CTO), or slapped the #MenInTech label on their social media posts when sharing their achievements? The industry’s obsession with women-coded job titles such as “female founder” (which has descended painfully into “girl boss”) that were conjured up to challenge the male default and demonstrate representation in the industry, does not sit comfortably with me.&lt;/p&gt;

&lt;p&gt;Feminising job titles, in my opinion, belittles success and achievement in the context of a patriarchal default. Just as “Women in Tech” awards and closed spaces for “non-men” segregate underrepresented groups of people from the spaces where people with power make decisions, women-coded labels inherently classify people on a separate, non-default scale of success and achievement.&lt;/p&gt;

&lt;h2&gt;
  
  
  It may work for early career folks, but what's next?
&lt;/h2&gt;

&lt;p&gt;After speaking with many women during writing this article, it looks like "Women in Tech" initiatives work well in the context of those entering the industry, but may not be enough to support getting enough underrepresented groups into leadership positions.&lt;/p&gt;

&lt;p&gt;A friend of mine shared this with me about her experiences:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I joined tech through Rails Girls. It was a really nice space, it made me feel very safe. It also played into this thing that I knew was happening a lot, which is women thinking that they are not capable of doing something because the world is telling them that they cannot. I really loved getting into tech through these female-focused initiatives. It made me feel like there was a group of people who cared about me joining tech, which is such an important thing if you are looking at an industry that is overloaded with a specific default type of guy.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another friend had a similar experience, but once she had established her career, things changed:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;My perspective also changed with age and expertise gathered. I found a lot of “Women in Tech” programs and initiatives incredibly useful as a newbie. I wouldn’t be where I am without codebar and some early speaking opportunities. But as I gained my voice and my knowledge I found it increasingly patronising.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Another &lt;a href="https://www.aiprm.com/women-in-tech-statistics/" rel="noopener noreferrer"&gt;Women in Tech statistics report from AIRPM&lt;/a&gt; reports that in 2025, "around 14% of global tech leaders were female in 2023 – up from 8% in 2015", which is promising. Yet, the Spacelift report also finds that “The so-called Big Five tech companies (Alphabet/Google, Apple, Meta/Facebook, Amazon, Microsoft) have never had a female CEO.” And to couple that with another finding from the Spacelift report mentioned above, that “half of all women who work in tech have left the industry by age 35”, it seems that once we get to a certain level of seniority, age, or experience, something isn't working.&lt;/p&gt;

&lt;p&gt;Rachel-Lee Nabors wrote about this in 2018 in an article titled &lt;a href="https://medium.com/@rachelnabors/a-counterintuitive-way-to-increase-diversity-in-tech-31aea2ce6a50" rel="noopener noreferrer"&gt;A Counterintuitive Way to Increase Diversity in Tech&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I’m mid-career in the web development and design industry. And right now, I’m hearing a lot of the same stories from my fellow mid-career friends from underrepresented groups (women, minorities, LGBTQ, and more): you reach a certain point in your career and you can’t win.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Responses to how you may be feeling right now
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I have benefitted from "Women in Tech" initiatives or other "non-men" initiatives in tech. Are you saying these programmes shouldn't exist?&lt;/p&gt;

&lt;p&gt;I'm a man and I think DEI is terrible. I'm glad to see a woman agreeing with me at last!&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As stated in the disclaimer, this is absolutely not the point of this article. Diversity, equity and inclusion initiatives are absolutely needed in this industry. However, the current landscape has seemingly affected little change in statistics on the whole, especially at leadership levels. I don't think we can continue to segregate ourselves if we want to make progress. Personally, I have worked with some excellent men. And men who have worked with me have said I am also excellent; we have all benefitted from working with each other. To that end, we absolutely need these initiatives: but the men must be invested as well. They must not be excluded from the conversation about how they can help affect change, especially in the context of leadership, given it's mostly the men who hold those positions today.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I am a man and consider myself an ally. Do I need to do something?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I remember speaking on a panel of all women, which was organised by a man. I requested that he not promote the event as an "all-women" event to avoid focussing on gender. He did it anyway. Celebrate underrepresented groups in tech, but do not focus on their gender identity. Celebrate their achievements, use your privilege to lift them up, share their work, make their voice heard: not because they are not men, but because their work is worth celebrating. If you are a man in a leadership position, you can absolutely do more to bring more underrepresented groups into leadership with you. To take another quote from Rachel-Lee's article:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You should be a mouthpiece when someone isn’t heard, an advocate when people are unable to be represented, a shield bearer when folks are under attack, an elevator for the stuck, a signal booster for the unnoticed. Wherever possible, let them do the work, and be heard and understood, and represent themselves. You’re the back up, the path carver, the taker of the brunt of the negative impact, always asking, “How can I help?” Always pushing others up, even over yourself.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  We’re focussing on the wrong thing
&lt;/h2&gt;

&lt;p&gt;I think that purely gender-based initiatives are shallow solutions to the deeper problems of male-dominated industries and society as a whole, that focus solely on surface-level optics of inclusion rather than addressing the root cause of inequality and imbalance on a larger scale. So, how do we address the root cause of inequality and imbalance?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We invite those with power to have a seat at the women’s table (and the underrepresented table as a whole): men _must _be part of the conversation to help affect change, especially at higher seniority levels.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Women, non-binary, intersex and trans folk are in tech, have always been in tech, and will (hopefully) always be in tech. There is a problem, in that these underrepresented groups are often discriminated against and overlooked. The solution? Men in tech can lead the change in how men represent themselves and their gender as a whole in the industry. A bandaid? Groups where "non-men" can feel safe. Both are important, but only one will affect real change.&lt;/p&gt;

</description>
      <category>womenintech</category>
      <category>careerdevelopment</category>
      <category>inclusion</category>
      <category>fullstack</category>
    </item>
    <item>
      <title>The promise that wasn’t kept</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Thu, 29 May 2025 14:08:13 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/the-promise-that-wasnt-kept-3554</link>
      <guid>https://forem.com/whitep4nth3r/the-promise-that-wasnt-kept-3554</guid>
      <description>&lt;p&gt;I recently wrote about &lt;a href="https://whitep4nth3r.com/blog/does-ai-really-make-you-more-productive/" rel="noopener noreferrer"&gt;AI and productivity&lt;/a&gt;, and how data from the &lt;a href="https://cloud.google.com/devops/state-of-devops" rel="noopener noreferrer"&gt;2024 Accelerate State of DevOps Report&lt;/a&gt; shows that widespread AI adoption in the software industry is contributing to a real and meaningful decline in software delivery performance. Approximately 76% of developers use AI tools in daily tasks such as coding, debugging, and documentation.&lt;/p&gt;

&lt;p&gt;This week I posted a &lt;a href="https://bsky.app/profile/whitep4nth3r.com/post/3lq7ls2rgz22p" rel="noopener noreferrer"&gt;silly and whimsical post on Bluesky&lt;/a&gt;, which seemed to resonate with a lot of you out there, and it reminded me of a section in the DORA report about valuable work.&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%2Fafibo34zobpqdhjwt7wc.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%2Fafibo34zobpqdhjwt7wc.png" alt="i was born to make websites, fun websites, silly websites, curious websites, websites that bend, delight, amuse and entertain, websites for people on planet earth, and there will be no shareholder value, but the websites will be built, and they will be enjoyed" width="800" height="455"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;AI has always promised to “help people spend more time doing valuable work” by “automating the manual, repetitive, toilsome tasks” so that software developers can be “free to use their time on ‘something better.’” Despite this, the report states that “individuals are reporting a decrease in the amount of time they spend doing valuable work as AI adoption increases”. The maths isn’t mathsing.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is valuable work, actually?
&lt;/h2&gt;

&lt;p&gt;I have observed a growing trend of developers focussing solely on the tools used to make software, rather than what the software actually &lt;strong&gt;does&lt;/strong&gt;. Many people are sharing their new apps on social media, attempting to provide context for their creations by listing the databases, runtimes, frameworks, UI libraries and AI code generation tools they used. But what does your app actually &lt;strong&gt;do&lt;/strong&gt;? What problems does it solve? &lt;strong&gt;Tell me about the value you just created!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Valuable work and meaning is not derived from what AI makes us (apparently) faster at: generating code. Meaning and value in software development is actually created through the impact of building things that makes human lives &lt;strong&gt;better&lt;/strong&gt;, or &lt;strong&gt;easier&lt;/strong&gt;, or &lt;strong&gt;slightly less bad&lt;/strong&gt;. Now, it can be argued that much of the work in the technology industry in 2025 is not centred on making things better for humans whatsoever, but that’s a discussion for another day.&lt;/p&gt;

&lt;p&gt;What’s becoming clear is that the mass adoption of AI is shifting the focus away from human-centred software solutions that provide meaningful value, and is reducing the entire industry to just the tools at its disposal. &lt;strong&gt;Just generate the code, bro. Just ship one more app, bro.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The new kitchen metaphor
&lt;/h2&gt;

&lt;p&gt;If I employ someone to build a new kitchen for me, I really don’t care what drills, hammers, nails, or sandpaper they use to get the job done. I just want a valuable end result: a fancy-looking and functional kitchen that makes good use of the available space, enabling me to cook delicious food in a delightful and comfortable environment. Ultimately, a great kitchen is created with vision, creativity, and by solving existing problems the old kitchen presented. The same is true for software.&lt;/p&gt;

&lt;p&gt;Value in software development cannot be determined by how many lines of code you can bash out in any working day, and especially whether or not you are using AI to do so. Real value is delivered through vision, creativity, experimentation, and using human brains to solve human-centred problems. The report backs this up:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;[T]here is also an art and empathy underlying a great product. This might be difficult to believe for people who think everything is a problem to be resolved through computation, but certain elements of product development, such as creativity or user experience design, may still (or forever) heavily rely on human intuition and expertise.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And what’s even more interesting, is that while seemingly “high-performing teams and organizations use AI”, the report finds that “products don’t seem to benefit”. We’re all just churning out AI generated code, moving those tickets, making meaningless graphs go up, but to what end? Real software is actually not moving forward. We're all just cranking out the same broken software with the same stupid bugs. In fact, as I was editing this post whilst sitting with a fresh batch of black hair dye on my head at the hairdressers, one wrong tap of a button on my phone deleted half of the article. I attempted to use the three-finger gesture to bring up the undo button on my iPhone, which, not surprisingly, did not restore what was deleted. I ended up having to find a deploy preview of this post (that I fortunately deployed before I left the house), copy and paste half of the article back into the CMS, and reformat the headings, being very careful to not make a single wrong move.&lt;/p&gt;

&lt;p&gt;All the new kitchens and silly add-ons are shit. There’s no value in that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Tools do not determine value created
&lt;/h2&gt;

&lt;p&gt;The tools someone uses to build a kitchen are only as good as the skills of the person using them. A skilled craftsperson can probably use any old tool and produce a great result that holds up for years to come. A less experienced craftsperson who doesn’t understand the fundamental concepts of space, structure and value-based utility might be able to make a single kitchen cabinet &lt;strong&gt;look good&lt;/strong&gt; to the untrained eye, only for the shelves to be at the wrong height so I can't store my stuff. The same can be said for software.&lt;/p&gt;

&lt;p&gt;There’s nothing wrong with being inexperienced; we all have to start from somewhere. But we can’t rely on tools as a shortcut to &lt;strong&gt;gain&lt;/strong&gt; valuable experience. Experience takes time to develop, and your tools are only as good as your fundamental knowledge and skills. If you skip the knowledge and skills part, and if you fail to &lt;strong&gt;learn&lt;/strong&gt; about what you’re doing and the implications of &lt;strong&gt;how you’re doing it&lt;/strong&gt; and the human value you have the potential to deliver, then you have little hope of building human value into your software. Because for the most part, &lt;strong&gt;humans use software&lt;/strong&gt;. Andreas Møller said it better in &lt;a href="https://blog.nordcraft.com/they-lied-to-you-building-software-is-really-hard" rel="noopener noreferrer"&gt;They lied to you. Building software is really hard&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The true value of a software engineer is in our ability to analyze problems as well as design and implement creative solutions. To get good at these skills you need to understand not just the tools at your disposal but also the technologies you are building on top of. If you don’t understand how an application works then you have no chance of fixing its bugs and issues.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In the report, “respondents also reported expectations that AI will have net-negative impacts on their careers, the environment, and society, as a whole”. Whilst AI has empowered anyone to build and ship web and mobile apps, the tangible negative impact of the soulless, valueless software released on a daily basis across the industry cannot be underestimated.&lt;/p&gt;

&lt;p&gt;And no, I do not want to use your new AI tool to summarise an email (?) or summarise a document (?) or summarise a meeting (?) or anything else. I want to use my brain so I can comprehend and learn and connect with what is in front of me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Productivity ≠ value
&lt;/h2&gt;

&lt;p&gt;Returning to the topic of the previous article, I want to touch again on the topic of productivity. Productivity as a measure of value is extremely misleading. The very notion of productivity has been conjured up by Big Capitalism™️ to keep us busy, and to misdirect our attention so that we forget to question the broken system in which we have no choice but to participate. All of this prevents us from real growth, and moves us further and further away from the pursuit of real value.&lt;/p&gt;

&lt;p&gt;You could argue there is space for both approaches in software development. Build the hard, compelling stuff using your human brain, and use AI to generate the code for some of the more boring parts of your apps. Take form validation, for example, scaffolding out a new project, or setting up all the boilerplate to make some API calls. But those boring parts are only boring &lt;strong&gt;because you wrote the code to do the same thing before&lt;/strong&gt;! You already learned how to do it without AI.&lt;/p&gt;

&lt;p&gt;But unfortunately, too many of us are getting sucked into the productivity hype cycle and engaging in daily conversations with energy-sapping computer machines that vomit out thousands of lines of code based on probability and existing mistakes that the Large Language Models themselves are trained on. It's absurd. We have a whole new cohort of inexperienced kitchen builders who have invested in the latest must-have drills, hammers, nails and sandpaper, but have no idea how to build real value into what they are using those tools to create. And so we're seeing an influx of infinite inferior kitchens that offer no human value. They may look good when you walk into the room, but will inevitably fall to pieces as soon as you put the kettle on to make a cup of tea.&lt;/p&gt;

&lt;p&gt;The data speaks for itself. Vibe coders are reporting &lt;a href="https://www.techrepublic.com/article/ai-generated-code-outages/" rel="noopener noreferrer"&gt;outages and critical security vulnerabilities in their apps&lt;/a&gt;, &lt;a href="https://www.reddit.com/r/cursor/comments/1inoryp/cursor_fck_up_my_4_months_of_works/" rel="noopener noreferrer"&gt;losing months of work that didn’t use version control&lt;/a&gt;, and the &lt;a href="https://varunraghu.com/why-i-wont-be-vibe-coding-anymore/" rel="noopener noreferrer"&gt;inability to truly learn new things&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The world is already cooked, and yet, we’re cooking it more
&lt;/h2&gt;

&lt;p&gt;What’s more, there’s the environmental impacts of AI, which are only just beginning to emerge. An MIT article titled &lt;a href="https://news.mit.edu/2025/explained-generative-ai-environmental-impact-0117" rel="noopener noreferrer"&gt;Explained: Generative AI’s environmental impact&lt;/a&gt; outlines how the rapid expansion of generative AI presents significant sustainability challenges, including electricity and water overuse, hardware-related emissions, and increasing pressure on power grids.&lt;/p&gt;

&lt;p&gt;The world is already cooked. And yet, we’re cooking it more — literally, and figuratively — by shipping insecure software into the void that we have no idea how to debug, scale, or extend. In the not-so-distant future, LLMs will be trained purely on LLM-generated software, and the world will eat itself.&lt;/p&gt;

&lt;p&gt;I challenge you to find the value in that.&lt;/p&gt;

</description>
      <category>ai</category>
    </item>
    <item>
      <title>It wasn’t the idea that failed: it was the execution</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Fri, 09 May 2025 13:37:58 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/it-wasnt-the-idea-that-failed-it-was-the-execution-406l</link>
      <guid>https://forem.com/whitep4nth3r/it-wasnt-the-idea-that-failed-it-was-the-execution-406l</guid>
      <description>&lt;p&gt;Since writing my new talk, &lt;em&gt;An Introduction to the World Wide Web for Very Senior Programmers&lt;/em&gt;, in which I transport the audience back to the year 1995, I’ve become somewhat of a proud and nerdy Internet historian. So much happened on the web in 1995. HTML 2.0 was released in September and saw the introduction of the HTML &lt;a href="" class="article-body-image-wrapper"&gt;&lt;img&gt;&lt;/a&gt; tag, transitioning the online experience from something that resembled reading books and formal documents, to flicking through colorful magazines or photo albums. JavaScript was released in December 1995, which moved the web from a read-only medium to an interactive experience. Multimedia tools like &lt;a href="https://macromedia.fandom.com/wiki/Macromedia_Shockwave_Player" rel="noopener noreferrer"&gt;Macromedia Shockwave Player&lt;/a&gt; and &lt;a href="https://www.webdesignmuseum.org/software/futuresplash-animator-in-1996" rel="noopener noreferrer"&gt;FutureWave FutureSplash Animator&lt;/a&gt; were created in 1995 out of a desire to bring exciting and interactive CD-ROM-like experiences to the browser.&lt;/p&gt;

&lt;p&gt;While the end-user experience was evolving, new tools to support web developers who were building websites were also being invented. The World Wide Web Consortium (W3C) was formed in 1995. And, whilst the first version of CSS was not released until 1996, the &lt;a href="https://www.w3.org/People/howcome/p/cascade.html" rel="noopener noreferrer"&gt;1994 proposal for Cascading HTML Style Sheets&lt;/a&gt; was being developed by the W3C. This would give web developers &lt;strong&gt;full control&lt;/strong&gt; over the design of their websites, instead of allowing end-users to enhance the visuals of their internet-surfing experience using proprietary browser configurations. And, whilst the web was becoming more visual, so were the tools used to &lt;em&gt;build&lt;/em&gt; websites.&lt;/p&gt;

&lt;h2&gt;
  
  
  It all started with Visual Basic
&lt;/h2&gt;

&lt;p&gt;In 1991, Visual Basic was launched for Windows software application development. Visual Basic was a graphical user interface (GUI) that provided a visual abstraction layer on top of C/C++ and the Win32 API. Ryan Lucas describes this historical release in detail in &lt;a href="https://retool.com/visual-basic" rel="noopener noreferrer"&gt;The history and legacy of Visual Basic&lt;/a&gt;, and pays particular attention to how it saved the careers of “millions of mainframe COBOL programmers who were looking with terror at the microcomputer invasion,” as recalled by the creator of Visual Basic, Alan Cooper.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;To design their UI, developers could drag and drop out components onto a WYSIWYG canvas. To add behavior to a UI element, they could simply select it and choose a click event handler from a dropdown. Mainframe programmers were suddenly empowered to quickly get up to speed writing Windows apps.&lt;/p&gt;
&lt;/blockquote&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%2F9orio2p99j3omu8a0nrt.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%2F9orio2p99j3omu8a0nrt.png" alt="The Visual Basic user interface in 1995." width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Whilst application developers were embracing a more visual way of working in the early 90s, developers on the web were still confined to the command line, Notepad, and MS-DOS Editor on Windows. That is, until FrontPage 1.0 was released in November 1995.&lt;/p&gt;

&lt;p&gt;FrontPage was developed by Vermeer Technologies, and was categorised as a “World Wide Web publishing and site management tool”. Like Visual Basic, FrontPage was a WYSIWYG (what you see is what you get) visual interface, and this tool built HTML. It also provided a personal web server, which allowed you to preview your website on your local machine as you built it. It also included templates, automated scripts, and more. FrontPage was acquired by Microsoft just two months later in January 1996, and was rebranded to Microsoft FrontPage in June 1996 to coincide with the release of version 1.1.&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%2F2t7sv3jsw56ik8ch1pzn.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%2F2t7sv3jsw56ik8ch1pzn.png" alt="Microsoft FrontPage 1.0, showing a home page made for the web as text and a list of links, all within the FrontPage GUI." width="600" height="525"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Around the same time, a company called iBand worked on a similar visual tool to FrontPage called Backstage Designer. And, as is seemingly standard practice in this industry, iBand was acquired by Macromedia in 1996, and soon rebranded the Backstage Designer product as &lt;a href="https://macromedia.fandom.com/wiki/Macromedia_Backstage_Desktop_Studio" rel="noopener noreferrer"&gt;Macromedia Backstage Desktop Studio&lt;/a&gt;, which in 1998 became a web development GUI you may be more familiar with: &lt;a href="https://macromedia.fandom.com/wiki/Macromedia_Dreamweaver" rel="noopener noreferrer"&gt;DreamWeaver&lt;/a&gt;.&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%2Flj32h9d7716h1maw9un6.webp" 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%2Flj32h9d7716h1maw9un6.webp" alt="Screenshot of iBand backstage designer in 1996. It resembles Microsoft FrontPage." width="400" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Development tools for building games were also evolving in the same way at the same time. &lt;a href="https://en.wikipedia.org/wiki/Unreal_Engine_1" rel="noopener noreferrer"&gt;Unreal Engine 1&lt;/a&gt;, a GUI built in Visual Basic, was also released in 1995.&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%2Fpb091jhzwuigonhqf7ym.jpg" 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%2Fpb091jhzwuigonhqf7ym.jpg" alt="A screenshot released by Epic of the first version of UnrealEd, displaying a graphical user interface written in Visual Basic," width="364" height="273"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And what’s very interesting to note at this point, is that while game development has largely adopted visual development tools across the industry, web development seemingly abandoned the visual tools of the mid-late 90s. Thirty years later, most of us are still building websites and web applications using text editors. Why is that?&lt;/p&gt;

&lt;h2&gt;
  
  
  Why didn’t we adopt visual website tools in the 90s?
&lt;/h2&gt;

&lt;p&gt;The bottom line is that visual website tools in the 90s (and beyond) produced terrible HTML markup, and therefore, pretty terrible websites. I remember fondly using the Apple website builder &lt;a href="https://www.apple.com/welcomescreen/ilife/iweb-3/" rel="noopener noreferrer"&gt;iWeb&lt;/a&gt; in the early 2000s. In fact, it wasn’t very long ago that a website I built for a client in 2008 using iWeb was still up and running. The text-based CMS I built for them, which displayed a text file in an iframe that they uploaded via FTP, really stood the test of time. But now I have professional knowledge and experience of building things for the web, I know that the HTML markup that iWeb produced was &lt;em&gt;absolute filthy garbage&lt;/em&gt;. And if the HTML markup is garbage, then your site is not accessible to those who use assistive technology, such as screen readers.&lt;/p&gt;

&lt;p&gt;In 1986, &lt;a href="https://www.afb.org/aw/5/2/14760#:~:text=The%20PC%20was%20in%20its,DOS%2C%20called%20IBM%20Screen%20Reader" rel="noopener noreferrer"&gt;IBM announced the first screen reader&lt;/a&gt;, but it wasn’t until the mid 90s that screen readers started to become a little more accessible themselves, when &lt;a href="https://abilitynet.org.uk/factsheets/introduction-screen-readers#simple-table-of-contents-6" rel="noopener noreferrer"&gt;JAWS was released for Windows 1.0&lt;/a&gt; in 1995. The first web accessibility guidelines, later branded as the &lt;a href="https://en.wikipedia.org/wiki/Web_Content_Accessibility_Guidelines" rel="noopener noreferrer"&gt;Web Content Accessibility Guidelines&lt;/a&gt; or WCAG, were published in January 1995. Yet, despite this, tools that were created to build websites were not ever seemingly built with these official standards in mind. This goes for tools built in 1995, and astonishingly, 2025.&lt;/p&gt;

&lt;p&gt;This week on May 7th 2025, Figma announced &lt;a href="https://www.figma.com/sites/" rel="noopener noreferrer"&gt;Figma Sites&lt;/a&gt;, a tool to publish your designs built in Figma directly to the web. But this new product has not been well received. Adrian Roselli warns us: &lt;a href="https://adrianroselli.com/2025/05/do-not-publish-your-designs-on-the-web-with-figma-sites.html" rel="noopener noreferrer"&gt;Do not publish your designs on the web with Figma Sites&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“…Unless you want to fail all the WCAGs, create litigation risk, close off opportunities in Europe, engage in reputational harm, and oh yeah, throw up barriers to your customers and users.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s no surprise we weren’t getting it right in 1995, if we &lt;em&gt;still&lt;/em&gt; can’t get it right 30 years later with all of this knowledge, experience, and empathy under our belts. And I’m not even going to mention at this point how AI can’t get this right, either. Of course it can’t; it doesn’t possess the capacity for empathy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers want control
&lt;/h2&gt;

&lt;p&gt;Developers want complete control over their HTML, CSS and JavaScript: and rightly so. If visual web development tools can’t generate clean and semantic HTML, organized and debuggable CSS, or performant JavaScript, it really is a no-brainer to continue to build websites and web applications using text-based web frameworks, or rolling your own.&lt;/p&gt;

&lt;p&gt;It is no secret that I am writing all of these things on the &lt;a href="https://nordcraft.com" rel="noopener noreferrer"&gt;Nordcraft&lt;/a&gt; blog, and that Nordcraft is an open-source Web Development Engine which combines a web framework with a suite of advanced visual tools that let designers and developers collaborate to build high performance web applications, and that I work at Nordcraft. And you might think that Nordcraft is just another visual website builder that produces the same old garbage that all the other visual tools do. But speaking as someone who has been building websites and writing code for over 20 years, and as someone who likes complete control over said websites and code, I can say for a fact that Nordcraft is very, very, different.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nordcraft actually gives you control
&lt;/h2&gt;

&lt;p&gt;In Nordcraft, your HTML markup is yours to control. Using the Nordcraft editor, you build your HTML structure in the same way you build HTML with text, using semantic element tags of your choosing, with full access to adding attributes and other web platform-based functionality. Nordcraft does not prescribe how to build your HTML markup: you do. The only difference (and advantage) is that you are building your HTML on a WYSIWYG canvas, where designers can collaborate with you and add design flair &lt;em&gt;as part of the process&lt;/em&gt;, not as some preliminary task that sees designs in Figma thrown over the fence in a developer’s general direction (which is, all too often, the case). CSS and JavaScript work in the same way: you have complete control over what you ship to the browser, without any unexpected nonsense.&lt;/p&gt;

&lt;p&gt;It’s 2025, and we can do better than what has come before us, and what is, unfortunately, currently unfolding in this visual web development landscape. By giving you, as developers and designers, full control over the end result you envision, I am confident that Nordcraft won’t suffer the same fate of the early visual tools of the 90s, or Figma Sites in 2025.&lt;/p&gt;

&lt;p&gt;Your fate is in your own hands, as well as the fate of your websites.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>history</category>
      <category>programming</category>
    </item>
    <item>
      <title>Does AI really make you more productive?</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Fri, 28 Mar 2025 09:04:33 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/does-ai-really-make-you-more-productive-pn1</link>
      <guid>https://forem.com/whitep4nth3r/does-ai-really-make-you-more-productive-pn1</guid>
      <description>&lt;p&gt;In October 2024, the DORA research programme published the &lt;a href="https://cloud.google.com/devops/state-of-devops" rel="noopener noreferrer"&gt;2024 Accelerate State of DevOps Report&lt;/a&gt;, which for the first time, included a section on how AI adoption is affecting software development at an individual, team and product level. With the recent emergence of the new “&lt;a href="https://en.wikipedia.org/wiki/Vibe_coding" rel="noopener noreferrer"&gt;vibe coding&lt;/a&gt;” meta, a term introduced by &lt;a href="https://karpathy.ai/" rel="noopener noreferrer"&gt;Andrej Karpathy&lt;/a&gt; in February 2025, where AI is is enabling people to ship apps from idea to production in record time, I wanted to take the time to reflect on the report and discuss whether AI is &lt;em&gt;really&lt;/em&gt; making us more productive as software developers.&lt;/p&gt;

&lt;h2&gt;
  
  
  Most developers are relying on AI
&lt;/h2&gt;

&lt;p&gt;The report found that almost 76% of participants are “relying on” some form of AI tooling in their daily responsibilities as a software developer. This can include writing, optimising, documenting and debugging code, explaining unfamiliar code, writing tests, data analysis, and summarising information. “[D]evelopers who trust gen AI use it more”, but almost 40% of participants “reported having little or no trust in AI”.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I do not trust AI.&lt;/strong&gt; I have over 11 years of professional industry experience, and have been making websites in some form or another for almost 30 years. With all this considered, AI code generation has only ever made me feel &lt;em&gt;less&lt;/em&gt; productive. I prefer to understand every single line of code I ship in my applications: it makes everything easier to debug, fix, and extend. I have found that AI-generated code is often sloppy, unnecessarily complex, and a lot of the time, just plain wrong. For me, AI code generation is akin to mindlessly copy-pasting code snippets from Stack Overflow, and we all know how that goes. It usually takes me longer to understand AI generated code than write my own.&lt;/p&gt;

&lt;h2&gt;
  
  
  You may be sacrificing software delivery metrics by relying on AI
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://dora.dev/guides/dora-metrics-four-keys/" rel="noopener noreferrer"&gt;DORA’s software delivery metrics&lt;/a&gt; provide an effective way of measuring outcomes of software delivery processes. They are split into two categories: throughput and stability. The report found that “AI adoption is negatively impacting software delivery performance”, and the “negative impact on delivery stability is larger”.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sacrificing throughput with AI
&lt;/h3&gt;

&lt;p&gt;Throughput measures the velocity of changes in software that are being made, that is, how quickly and how frequently software teams can ship changes to production. Throughput is all about how efficient and responsive a team can be.&lt;/p&gt;

&lt;p&gt;The report hypothesises that “the fundamental paradigm shift that AI has produced in terms of respondent productivity and code generation speed may have caused the field to forget one of DORA’s most basic principles — the importance of small batch sizes.” Since AI code generation will often spit out huge batches of code in one fell swoop, pull requests are getting larger. Larger pull requests and changes are much more difficult and time-consuming to review thoroughly for edge-cases and potential issues.&lt;/p&gt;

&lt;p&gt;Speaking from experience, code reviewers are more likely to skim over large changes and miss important details; walls of impenetrable code are much more difficult to process and interpret by a real human brain than smaller changes, amidst an already busy work-day. Whilst combing through that &lt;code&gt;+11456 -7892&lt;/code&gt; code review, you’re probably thinking about all those lines of code &lt;em&gt;you need to write yourself&lt;/em&gt; in order to stay “productive”.&lt;/p&gt;

&lt;p&gt;Of course, there are tools that provide AI-assisted code reviews. But if we, as developers, do not trust AI to produce maintainable and reviewable code, why should we trust AI to review it? If you find yourself constantly reviewing large pull requests with a lot of AI generated code, you’re probably sacrificing throughput. You might not be shipping as fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  Sacrificing stability with AI
&lt;/h3&gt;

&lt;p&gt;Stability measures the quality of software changes delivered, and the team’s ability to fix bugs. Stability is measured using a combination of change fail percentage, which is the percentage of deployments to production that require hot-fixes or rollbacks, and failed deployment recovery time. A lower change fail percentage means the team has a reliable delivery process, and a lower recovery time indicates more resilient and responsive systems.&lt;/p&gt;

&lt;p&gt;The report suggests that it’s “possible that we’re gaining speed through an over-reliance on AI for assisting in the process or trusting code generated by AI a bit too much.” I would argue that &lt;em&gt;speed&lt;/em&gt; here is the &lt;em&gt;illusion of speed&lt;/em&gt;, and the concept of “over-reliance” is key here, especially in the context of the new vibe coding meta. Vibe coding is about being dependent on AI code generation. Describe the app or code you want, and let an LLM take care of it for you. Ask it for a few edits. Ship it.&lt;/p&gt;

&lt;p&gt;The report states that a developer’s productivity “is likely to increase by approximately 2.1% when an individual’s AI adoption is increased by 25%”. Vibe coding and any sort of AI adoption is attractive because it &lt;em&gt;feels&lt;/em&gt; fast; it &lt;em&gt;feels&lt;/em&gt; more productive. Now, I’m not proposing that professional software developers are going all-in on vibe coding, but increased adoption of AI and reported productivity increases poses a risk to software stability. We think we’re going faster, but we may be shipping poorer quality software and more broken changes, because we’re putting our trust in AI generated code too much.&lt;/p&gt;

&lt;p&gt;Data from the industry is proving that vibe coders are shipping unstable applications, reporting &lt;a href="https://www.techrepublic.com/article/ai-generated-code-outages/" rel="noopener noreferrer"&gt;outages and critical security vulnerabilities in their apps&lt;/a&gt;, &lt;a href="https://www.reddit.com/r/cursor/comments/1inoryp/cursor_fck_up_my_4_months_of_works/" rel="noopener noreferrer"&gt;losing months of work that didn’t use version control&lt;/a&gt;, and the anecdotal &lt;a href="https://discord.com/channels/972416966683926538/972416966683926541/1349174629268197387" rel="noopener noreferrer"&gt;struggle to finish vibe-coded apps&lt;/a&gt;. If professional software development teams do not stay vigilant with their use of AI, they run the risk of sacrificing stability.&lt;/p&gt;

&lt;p&gt;Plus, if you’re moving fast, but always having to pick up the pieces caused by over-zealous AI code generation, are you really being more productive?&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Is this the next step in the evolution of front end dev?</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Mon, 03 Mar 2025 11:54:27 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/is-this-the-next-step-in-the-evolution-of-front-end-dev-32en</link>
      <guid>https://forem.com/whitep4nth3r/is-this-the-next-step-in-the-evolution-of-front-end-dev-32en</guid>
      <description>&lt;p&gt;In 2025, setting up new web development projects is still really, really annoying. And honestly, it’s one of the reasons I either prototype a new project in a single HTML file, or don’t manage to find the energy to prototype a new fun idea at all. Starting a new front end project involves a never-ending list of administrative tasks and decisions to be made, when all you want to do is get building. Your list of setup tasks might look something like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set up a new development environment (install e.g. correct version of node, npm, yarn, pnpm, bun)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set up a new project (create directory, choose framework, choose starter project or boilerplate, install dependencies, ensure they are compatible with each other)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define a file structure and component library approach&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Define a base style guide and CSS resets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Write boilerplate code to connect to APIs and databases&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure a build and deploy pipeline&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Configure Webpack???&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And, if you’re working with a designer, you’ve also got the back and forth handover and sign-off processes to go through, which in a busy team or multi-project agency, can really hold things up. &lt;strong&gt;You just want to get building!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There are some alternatives to the time-consuming, decision-heavy setup process. You could use virtual machines or environments that enable faster time-to-setup through scripts and automated processes. But still, even this requires some effort and “onboarding". I remember at one job, I went through a “tried and tested” vagrant virtual machine setup process that didn’t actually work correctly with my version of MacOS at the time. Now, granted this wasn’t a brand new project, but it took me a full working week to configure my development environment so that I could be productive. So what are the alternative approaches? Recently, I’ve become curious about &lt;em&gt;visual development frameworks.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a visual development framework?
&lt;/h2&gt;

&lt;p&gt;When you use a visual development framework, you're working in an environment where you don't need to think about — or do — any of the relentless admin and project configuration tasks described above. Everything is taken care of from the beginning, and you're ready to start making components, fetching data from APIs, adding custom code, and watching your ideas come to life straight away. Visual development also removes the need to translate designs from design software to code: the design of the user interface is baked in to how you build it. No more handovers between teams!&lt;/p&gt;

&lt;p&gt;In summary, visual development solves two key problems in front end development: it abstracts away the repetitive administrative setup work, and removes the inconvenience of separate design and dev environments.&lt;/p&gt;

&lt;p&gt;Here's how working with HTML, CSS and data from an API looks inside visual development framework, Nordcraft. You’ve got a document tree of HTML elements on the left, CSS styling and API connections on the right, and the visual result in the middle. In traditional text-based development, this weather widget might be powered by a collection of files dotted around a codebase. In visual development, it’s all right there.&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%2Fe8jgc14xo97azaa2z2vr.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%2Fe8jgc14xo97azaa2z2vr.png" alt="A weather widget in the centre of the screen showing the current temperature, location and weather icon. But what's most interesting is that on the left side there is a tree of HTML elements that make up this widget that kind of looks like an accessibility tree, and on the right, there is an API panel showing that a GET request is being made to a weather API url, and the data is formatted in JSON, which is the data we are using in the HTML generated. We don't see any code here, just visual building blocks and data." width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Is this the next big step for front end development?
&lt;/h2&gt;

&lt;p&gt;A common sentiment among the terminally-online community is that if you’re not writing actual lines of code, then you’re not a real developer; often the industry treats the process of development as the outcome, rather than the actual website or app produced. But when you think about how every evolutionary step of computer science has centred on abstracting away things that no longer make sense for a human to do, then visual development frameworks are the logical next step in the evolution of front end development.&lt;/p&gt;

&lt;p&gt;For example, hardly anyone is coding in &lt;a href="https://en.wikipedia.org/wiki/Assembly_language" rel="noopener noreferrer"&gt;Assembly&lt;/a&gt; in 2025, and we don’t shun people for not being &lt;em&gt;real programmers&lt;/em&gt; just because they don’t write instructions to add memory data to a register in a x86-family processor in original Intel syntax, or know the equivalent in AT&amp;amp;T syntax used by the GNU Assembler. Most of us don’t need to worry about this anymore.&lt;/p&gt;

&lt;p&gt;Whilst everything is a set of binary instructions at its core, we also don’t need to worry about writing code in binary, thanks to &lt;a href="https://en.wikipedia.org/wiki/Grace_Hopper" rel="noopener noreferrer"&gt;Grace Hopper&lt;/a&gt; who released the A-O compiler in 1949, which used symbolic mathematical code to represent binary code. And we don’t even need to worry about writing code in mathematical symbols, because soon after A-O, Hopper released B-O, or “Flow-Matic”, which is considered the first English language data-processing compiler. Each advancement removes another layer of machine-to-human obscurity.&lt;/p&gt;

&lt;p&gt;What’s important to note, however, is that the evolution of programming languages was based on computation itself, not human-computer interaction (HCI). In the mid-latter part of the 20th century, there weren’t that many people using computers, and so HCI wasn’t a priority to be optimised for. But in 2025, we live our whole lives through HCI (for better or worse), and what has constantly been overlooked and under-prioritised is the actual experience of this human-computer interaction, both from the point of view as an end-user experiencing something on a device, and as someone who is crafting that end-user experience on a device.&lt;/p&gt;

&lt;p&gt;I speak from experience that as a web developer, it can be challenging to create really great experiences and human-computer interactions when you’re constantly moving between different layers of abstraction and relative obscurity (e.g. design → code as text → user interfaces). Visual development frameworks are a tool to help us get the same outcomes as writing traditional text-based code, without the slow up-front time-costs.&lt;/p&gt;

&lt;h2&gt;
  
  
  My next step
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;I'm excited to announce that I have joined Nordcraft.com Head of Developer Education.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://nordcraft.com/" rel="noopener noreferrer"&gt;Nordcraft&lt;/a&gt; is a Web Development Engine. Using Nordcraft, you can create fully-interactive front end websites and apps with any APIs, all via an in-browser visual interface. Nordcraft puts human-computer interaction at the front and centre of what you’re building, for both you as a web developer and your end users. And I'd like to go so far as to say that programming in a &lt;em&gt;different&lt;/em&gt; way might actually help you understand some programming concepts in a deeper way. Plus, you’ll never have to configure Webpack again.&lt;/p&gt;

&lt;p&gt;The team at Nordcraft is also working hard to make Nordcraft fully open source in 2025 and you can &lt;a href="https://github.com/nordcraftengine/nordcraft" rel="noopener noreferrer"&gt;check out the progress towards this on GitHub&lt;/a&gt;.&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%2Fj8grbq0lnzbhoo43ndbl.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%2Fj8grbq0lnzbhoo43ndbl.png" alt="The Nordcraft home page. The main headline is: Craft AAA web apps that delight your users, with a green CTA button that says start building. There is a video to the left of this main section that shows the Nordcraft editor in action." width="800" height="517"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It’s early days, but I’m incredibly excited to help shape the future of Nordcraft, and to help you build the best human-computer interactions on the web you possibly can. If you want to keep up with what we’re working on at Nordcraft, subscribe to the &lt;a href="https://www.youtube.com/@nordcraftengine" rel="noopener noreferrer"&gt;Nordcraft Engine&lt;/a&gt; channel on YouTube and &lt;a href="https://discord.com/invite/svBKYZf3UR" rel="noopener noreferrer"&gt;join the Discord&lt;/a&gt; (it’s very active!), and I can't wait to build more silly websites using Nordcraft, for your entertainment.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>html</category>
      <category>javascript</category>
    </item>
    <item>
      <title>You are more than the tools you use: tell your story</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Wed, 12 Feb 2025 12:55:55 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/you-are-more-than-the-tools-you-use-tell-your-story-epi</link>
      <guid>https://forem.com/whitep4nth3r/you-are-more-than-the-tools-you-use-tell-your-story-epi</guid>
      <description>&lt;p&gt;How many times have you seen someone introduce themselves via the tools they use? Maybe this looks familiar:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi, my name is Salma! I’m currently building an app with Express, Nuxt, and the Twitch API. Let’s connect! 🚀👩🏻‍💻🌐&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I understand the need to find shared interests with the online community to make genuine connections, I really do, but statements like this don’t tell people anything about what you actually do. Last year I did exactly what I described above. But what does it even mean? Take the following non-tech examples:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi, my name is Salma! I’m currently making music with a piano, guitar, and synthesisers. Let’s connect! 🎹🎸🎵&lt;/p&gt;

&lt;p&gt;Hi, my name is Salma! I’m currently making food with pasta, onions, and seasonings. Let’s connect! 🍝🧅🌶️&lt;/p&gt;

&lt;p&gt;Hi, my name is Salma! I’m currently making clothes with fabric, thread, and needles. Let’s connect! 👗🧵🪡&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You get the idea. The above statements tell people about what you’re using, but not about what you are doing. Let’s reframe the above non-tech examples.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi, my name is Salma! I’m currently working on an experimental EP that pushes the boundaries of the human perception of sound through the blending of acoustic instruments and digital noise to produce ethereal and meditative soundscapes. 🎹🎸🎵&lt;/p&gt;

&lt;p&gt;Hi, my name is Salma! I really love making unique pasta sauces that combine culinary influences from around the world. This week I’m trying to perfect a Japanese-inspired pasta sauce that takes inspiration from ramen and blends it with the traditional Italian concept of bolognese. 🍝🧅🍜&lt;/p&gt;

&lt;p&gt;Hi, my name is Salma! I’m currently making all my clothes from old furniture fabric and thrifted offcuts to prove that fashion doesn’t have to be fast to be exciting and innovative. I recently made a dress from my grandma’s old bedspread and I can’t wait to wear it to a party this week! 👗🧵🪡&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The above examples may be a little contrived, to say the least, but they tell a story; they reveal a little more about your personality; and they communicate more about who you are. Now, what about that technical example?&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Hi, my name is Salma, and I write code for your entertainment. Last year I built a text-based game for my Twitch stream that blurred the lines between me being online and offline, allowing viewers to interact with my stream 24/7. I love to find ways to help people truly connect through unexpected and fun applications of technology. 💖🔥📺&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You are more than the tools you use: tell your story. And your people will find you.&lt;/p&gt;

</description>
      <category>beginners</category>
    </item>
    <item>
      <title>3 reasons you should tour a conference talk</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Tue, 11 Feb 2025 13:49:16 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/3-reasons-you-should-tour-a-conference-talk-3n94</link>
      <guid>https://forem.com/whitep4nth3r/3-reasons-you-should-tour-a-conference-talk-3n94</guid>
      <description>&lt;p&gt;In 2023-2024, I gave my conference talk &lt;em&gt;Entertainment as Code&lt;/em&gt; six times. It should have been eight times, but you know, life happens. Writing a full-length conference is no trivial matter; it can take weeks of full-time work to craft a captivating story around your chosen topic, and even longer to build technical and/or representative real-world examples to support your narrative. All of this hard work should not go to waste. I want to share my experience of touring a conference talk, and why you should be touring a conference talk, too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Each talk is the same, but different
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://whitep4nth3r.com/talks/entertainment-as-code-premier/" rel="noopener noreferrer"&gt;first performance&lt;/a&gt; of Entertainment as Code was very different to the &lt;a href="https://whitep4nth3r.com/talks/entertainment-as-code-finale/" rel="noopener noreferrer"&gt;last&lt;/a&gt;. This was mainly because this talk centred on a new and evolving project I was working on throughout 2024, but also because the very notion of this conference talk inspired the project itself. Entertainment as Code became kind of an ouroboros; the more I gave the talk and spoke to attendees about how they enjoyed it, the more inspiration I received to evolve the project and the talk into its final form.&lt;/p&gt;

&lt;p&gt;By giving a conference talk multiple times, you also learn what works and what doesn’t work about your talk. As a (former) comedian, I learned a lot of hard lessons about what works and what doesn’t work for particular audiences in particular venues. I will never forget the time I referred to a fictional seven year old as the c-word to rapturous applause from an audience of twenty-somethings in Camden (trust me, it was funny), whilst repeating the same to a room full of middle-aged people in Blackburn almost ended up with me getting booed off the stage.&lt;/p&gt;

&lt;p&gt;I like to weave in jokes to my conference talks, and telling these jokes multiple times gives me the opportunity to iterate and land them as well as possible. The same goes for the content of the talk. In my opinion, no talk should be given in the same way any two times. On the one hand, as the speaker you will get bored. And on the other hand, conference attendees may attend multiple events and end up seeing you give the talk more than once (this definitely happened to me) and so you owe it to them to give them just a little bit more fun, insight, and technical depth than before. They’ll remember you for that.&lt;/p&gt;

&lt;h2&gt;
  
  
  You get better at giving the talk
&lt;/h2&gt;

&lt;p&gt;Speaking from experience, musicians, and comedians especially, never give the same performance twice. They also never give a performance just once. Each performance is a practice to make the next one better. As a performer, you have a duty to adapt your material to the room in which you’re in and the audience that is before you. A conference talk is also a performance, and it should be no different. And in intentionally adapting and iterating on your conference talk as you tour it, you learn more about public speaking, how to tell a really compelling story, and the content of the talk itself.&lt;/p&gt;

&lt;p&gt;My conference talks usually start with a strict script. As time goes on and I give the talk more times, I know the material more, my confidence grows, and as a result I’m able to improvise and go off-script, adapting the material to the audience and the room with little effort. It is incredibly satisfying for both the speaker and the audience to deliver the material in a way that resonates particularly with that room of people on a particular day.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your talk reaches more people
&lt;/h2&gt;

&lt;p&gt;According to a quick internet search for “average tech conference attendee numbers”, &lt;a href="https://www.imagovenues.co.uk/go-perform/50-stats-every-uk-conference-organiser-should-know/" rel="noopener noreferrer"&gt;the average number of attendees at a UK conference is 100&lt;/a&gt;. Giving your talk to just 100 people and calling it a day is not a good return on investment for potentially weeks of work. After putting in that work, you owe it to yourself to submit those CFPs, and get yourself an audience. The more people you reach, the more opportunities you may get in the future. And the cycle continues. You become the ouroboros. And the cycle is complete. And if you enjoyed the process, write a new talk, and do it all again.&lt;/p&gt;

</description>
      <category>techtalks</category>
    </item>
    <item>
      <title>How I created a newsletter I actually enjoy writing</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Thu, 06 Feb 2025 13:09:21 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/how-i-created-a-newsletter-i-actually-enjoy-writing-539</link>
      <guid>https://forem.com/whitep4nth3r/how-i-created-a-newsletter-i-actually-enjoy-writing-539</guid>
      <description>&lt;p&gt;Lots of developers send newsletters, and as I thrust myself into the online technology space in 2020, it was an item I added to my to do list straight away. Given the incessant algorithmic curation of content on the web, a newsletter is a crucial tool in being able to reach an audience consistently; someone giving you their email address is a powerful indicator of trust. But it took me three more years to actually start sending a newsletter because it felt like such a huge effort amidst everything else I had to do for work and for life.&lt;/p&gt;

&lt;p&gt;It turns out I was over-engineering the concept of sending a newsletter in my head. And it really can be as simple as you want to make it. Since January 2024, I’ve sent 56 weekly issues of my newsletter, and I’ve enjoyed writing and sending every single one. Here’s how I approached creating and sending my newsletter, &lt;a href="https://buttondown.com/weirdwidewebhole" rel="noopener noreferrer"&gt;weird wide web hole&lt;/a&gt;, to make each issue easy to write, and delightful to send.&lt;/p&gt;

&lt;h2&gt;
  
  
  Send what you would like to receive
&lt;/h2&gt;

&lt;p&gt;I am a huge fan of weird things and obscure things, intriguing experiences, and things that don’t always appear to be what they seem. Since the early days of the internet, I have always been fascinated with strange websites, curious applications of technology, the vastness of the universe, and unexpected collaborative online experiences. I am always thrilled to discover a non-standard, and perhaps unknown website written by a stranger, because I get to peek inside their head and explore the inner qualities of their soul and expression, and the human condition itself.&lt;/p&gt;

&lt;p&gt;I created weird wide web hole to satisfy my own desires to explore the weird side of the web. I send what I would be excited to receive: obscure descriptions of strange and intriguing websites and incantations of wonder and curiosity. Every word I send and every link I collect is intended to make you pause, appreciate, and explore things differently to how we’ve become accustomed on this vast world wide web.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make it easy for yourself
&lt;/h2&gt;

&lt;p&gt;Lots of newsletters contain lots of words. As a consumer of newsletters, I often find I can’t make the time to read so many words. Newsletters often sit unread in my inbox for days, until I have the time and space to enjoy them. The attention span of the world is disintegrating before our very eyes, and so I purposefully choose to write just a few words. Yet every word I write is written intentionally, and for you to consume deeply and deliberately. I write few words because I mindful of your time and of my own time. And writing fewer words makes approaching each newsletter cognitively easy. Each issue takes around five minutes to put together.&lt;/p&gt;

&lt;p&gt;Additionally, each newsletter contains just four links, which I collect throughout the week. Four is a very achievable number, and often I have a collection of links that are lined up for one or two future issues. I write the foreword to each issue on the day I send it, purely inspired by how the links in the newsletter made me feel, or what’s going on in my head that day. I don’t think too hard about what I write, I just let it happen.&lt;/p&gt;

&lt;h2&gt;
  
  
  Do it for the love, not the numbers
&lt;/h2&gt;

&lt;p&gt;At the time of writing, I have 346 active subscribers to my newsletter. That may seem like a small number compared to the number of people who know me on Bluesky or Twitch or even Youtube, but if you visualise that number of people in a room, it’s actually quite wonderful. I have the attention of almost 350 people, every Thursday.&lt;/p&gt;

&lt;p&gt;I know weird wide web hole may not appeal to a vast audience, and I actually kind of like that. I’m not going to sign off this blog post with a call to action to subscribe, because if you wanted to enter the weird wide web hole, you’d already be in there.&lt;/p&gt;

&lt;p&gt;goodbye&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>community</category>
    </item>
    <item>
      <title>How I learned to code with my voice</title>
      <dc:creator>Salma Alam-Naylor</dc:creator>
      <pubDate>Tue, 04 Feb 2025 15:22:33 +0000</pubDate>
      <link>https://forem.com/whitep4nth3r/from-pain-to-productivity-how-i-learned-to-code-with-my-voice-3099</link>
      <guid>https://forem.com/whitep4nth3r/from-pain-to-productivity-how-i-learned-to-code-with-my-voice-3099</guid>
      <description>&lt;p&gt;In January 2025, I developed excruciating pain and pins and needles in my hands, which made it very difficult to type and use my trackpad. I panicked. I couldn’t work. And if I couldn’t work, I couldn’t earn money. And if I couldn’t earn money, I couldn’t afford to eat or pay my mortgage. I was actually really, really, scared.&lt;/p&gt;

&lt;p&gt;After ruling out potentially genetically inherited rheumatoid arthritis with x-rays and blood tests, I deduced that probably I had carpal tunnel syndrome (which, coincidentally, my mother also suffered with). The most recent development, after seeing a physiotherapist, is that my symptoms don’t actually align with carpal tunnel syndrome, but instead, abnormal pressure on the radial nerve, primarily in my right arm. I’m doing some prescribed daily exercises that are alleviating symptoms somewhat, but the bottom line is that rest is the best medicine in this case: physical rest &lt;em&gt;and mental rest&lt;/em&gt;. My physical pain is real, but given the personal events I have endured over the last two years, I also believe that this manifestation of pain has been exacerbated by a combination of a series of emotionally traumatic events. I may write about this at a later date, but in this post I want to talk about how I learned to work and code using my voice, and offer some advice if you, too, find yourself in this extremely difficult situation.&lt;/p&gt;

&lt;h2&gt;
  
  
  Getting started is challenging
&lt;/h2&gt;

&lt;p&gt;I knew I had to do something to ease the pain to enable me to work, but I had no idea where to start. And so I turned to &lt;a href="https://bsky.app/profile/whitep4nth3r.com/post/3lfanag5si22c" rel="noopener noreferrer"&gt;Bluesky to ask if anyone had any advice&lt;/a&gt;. The advice was overwhelming, actually. Ergonomics, exercises, meditation, alternative keyboard layouts, and voice control. And when I asked for advice on &lt;a href="https://bsky.app/profile/whitep4nth3r.com/post/3lfcdlegln225" rel="noopener noreferrer"&gt;how to approach voice control and coding by voice&lt;/a&gt;, the advice was even more overwhelming. Everyone was very generous with their advice, but whilst dealing with debilitating pain, I was surrounded by a seemingly endless list of tools, plugins, apps, custom setups, and confusing options that left me feeling incredibly afraid for my short term future. How was I supposed to learn all of this to work effectively &lt;em&gt;right now&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Initially I made the mistake of trying to use all the tools at once. The result? Complete and utter confusion. I felt like I had reached the limits of what my brain was capable of, and this felt devastating. But, I did what every good software engineer does when dealing with a difficult bug: I stripped everything down and pieced the tools and functionality back together, one by one. Next, I’ll detail the tools that worked for me, and I’ll follow with some important advice that I wish I’d found or that someone had given me when I was at the start of my journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  My voice coding tools
&lt;/h2&gt;

&lt;p&gt;I found success in just two weeks with just four tools. &lt;/p&gt;

&lt;h3&gt;
  
  
  Talon
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://talonvoice.com/docs/#" rel="noopener noreferrer"&gt;Talon&lt;/a&gt; enables you to write code, play games, and control your computer with &lt;strong&gt;&lt;em&gt;voice&lt;/em&gt;&lt;/strong&gt;, eye tracking, or noises. It is certainly a powerful piece of software — but it is a heavy lift to set up. I was fortunate that I was able to afford some light use of my hands whilst installing and configuring my Talon setup, but it probably would have been impossible if I had zero hands to work with. &lt;/p&gt;

&lt;p&gt;Talon is entirely geared towards software engineers. So much so, that setting up Talon requires being able to navigate your terminal, and write or install script files before you can even use any type of voice control effectively. Fortunately, the Talon community gives you a much-needed head start by providing a selection of useful scripts in the &lt;a href="https://github.com/talonhub/community" rel="noopener noreferrer"&gt;community repository on GitHub&lt;/a&gt;, which you can clone directly inside your &lt;code&gt;.talon&lt;/code&gt; directory created on installation. This repository of Talon scripts allows you to get started relatively quickly in using VSCode and other IDEs, web browsers, email programs, work-based chat programs such as Slack, and even kubectl. Without this community repository, I would have been completely lost.&lt;/p&gt;

&lt;p&gt;You can also fork the community repository, make some changes according to your needs, and clone that to your &lt;code&gt;.talon&lt;/code&gt; directory. The current recommendation is not to modify too many files in the community repository, and to add your own files to make modifications where possible, to avoid any merge conflicts when pulling in new changes to the community maintained repository.&lt;/p&gt;

&lt;p&gt;I also wrote a few of my own Talon scripts to make running commands in my terminal a lot easier, such as &lt;code&gt;npm run dev&lt;/code&gt; (rather than having to spell them out), and you can view these in my &lt;a href="https://github.com/whitep4nth3r/talon-custom" rel="noopener noreferrer"&gt;talon-custom&lt;/a&gt; repository on GitHub. I also modified many of the default spellings from American to British English versions. Talon also has a very helpful Slack community, which is a bonus.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cursorless
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://www.cursorless.org/" rel="noopener noreferrer"&gt;Cursorless&lt;/a&gt; is a tool to use in conjunction with Talon, to help speed up the way you navigate and interact with code in VSCode. The main superpower I have so far unlocked with Cursorless is instead of having to ask Talon to move the cursor down a few lines, or left a couple words, and then select some text and/or delete it, you can do all of that in one Cursorless command. Now, it is clearly far more powerful than that, but with Cursorless you need to start slowly, and you need to have learned the Talon alphabet before any of this is possible. More on that later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Apple Voice Control
&lt;/h3&gt;

&lt;p&gt;Whilst trying to get to grips with Talon, I found that Apple Voice Control was a good option for being able to use my mobile devices effectively, and for being able to complete basic tasks on my MacBook such as window switching, natural voice dictation and web browsing. I was particularly impressed with the ease of targeting clickable elements using the “show numbers” command, which assigns each clickable element on a screen a number that you can select with your voice. The way that the functionality of Apple Voice Control is mirrored across different MacOS and iOS devices is really well thought out, and I can see it working well for the most part for people who don’t need to code with their voice.&lt;/p&gt;

&lt;p&gt;I will mention, however, that a number of web apps do not yet respond well to the text editing commands provided by Apple Voice Control, in particular Notion, which I use on a daily basis. Bear this in mind if you need to rely on Apple Voice Control for longer periods of time; it might just ruin your day. I had much better success using Talon with Notion when I had learned more of the Talon-specific commands.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rango
&lt;/h3&gt;

&lt;p&gt;With Talon on its own, navigating the web is still a challenge at first. Often I found myself switching between using Talon and Apple Voice Control so that I didn’t have to use the mouse functions in Talon to click on buttons and other clickable elements, because saying tab over and over again to reach my desired click target was time consuming and frustrating (not to mention that tab orders often suck on web pages, and click targets do not always have clear focus indicators) and I found it difficult to learn the Talon mouse commands. The &lt;a href="https://github.com/david-tejada/rango-talon#js-repo-pjax-container" rel="noopener noreferrer"&gt;Rango browser extension&lt;/a&gt; in conjunction with the &lt;a href="https://github.com/david-tejada/rango-talon#js-repo-pjax-container" rel="noopener noreferrer"&gt;rango-talon&lt;/a&gt; user file set gave me the same functionality of the “show numbers” command from Apple Voice Control, but without having to use the command itself, allowing me to click on any clickable target effectively using letters from the Talon alphabet, without having to say “tab” 100 times. &lt;/p&gt;

&lt;h2&gt;
  
  
  Other tools I tried with less success
&lt;/h2&gt;

&lt;p&gt;Given that learning how to use my voice to work was frustrating, I fell into the trap of trying to find a tool that would give me back the power of typing code as quickly as possible. I tried two more approaches that I currently do not recommend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serenade
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://serenade.ai/" rel="noopener noreferrer"&gt;Serenade&lt;/a&gt; claims to offer you the ability to write code using natural speech, which sounds incredibly enticing, but I had limited to no success with this product. The tutorials gave promising results, but I have a feeling that Serenade is geared entirely towards React and Python apps, as when trying to write code inside a Vue/Nuxt app, Serenade didn’t understand at all how to do what it claimed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Voice dictation to direct AI code generation
&lt;/h3&gt;

&lt;p&gt;An interesting suggestion I received was to use voice dictation as a way to prompt AI code generation tools to write the code for me. I tried this using Claude inside Cursor and hated it. My end goal was to be able to use my voice to work in the way I was accustomed to, rather than switching to an entirely unfamiliar AI-codegen-based workflow. &lt;/p&gt;

&lt;h2&gt;
  
  
  Important advice for learning to code with your voice
&lt;/h2&gt;

&lt;p&gt;Here are some of the things I wish I had known before learning to work with my voice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Take it slowly
&lt;/h3&gt;

&lt;p&gt;The one thing I wish that had been communicated to me from the beginning of my journey is that &lt;em&gt;you have to start slowly&lt;/em&gt;. Really slowly. Using a computer and coding with voice is an entirely new, and let’s face it, alien skill. And with any new skill, you can’t be expected to go from zero to 100 in a day. The dissonance I felt with this though, is that I could already code, and I was frustrated that I couldn’t reach my typing levels of productivity faster. I had ideas I wanted to get into my IDE, I had a vision for an app that I wanted to build, and I hated the fact that my body wasn’t letting me do it. &lt;/p&gt;

&lt;p&gt;Initially I installed Talon and Cursorless, watched two tutorial videos, and wanted to get to work. But I couldn’t; the landscape was entirely unfamiliar. I felt stuck. And then I had to force myself to do what any teacher would tell you when you got stuck: take it slowly. And start from the start.&lt;/p&gt;

&lt;h3&gt;
  
  
  Start from the start
&lt;/h3&gt;

&lt;p&gt;When learning anything, it can be tempting to try and dive right into the deep end to get a head start. But if you can’t swim, you’ll drown. When learning to use Talon, you have to start from the start: the Talon alphabet. &lt;/p&gt;

&lt;p&gt;Talon uses its own proprietary alphabet which allows you to dictate single letters. A common concern is why Talon doesn’t use the NATO phonetic alphabet to avoid needing to learn a whole different map of words to single letters. The answer is that the NATO phonetic alphabet uses a collection of words that are two or three syllables in length, whereas each Talon letter name uses just &lt;strong&gt;one syllable&lt;/strong&gt;. This means that in using the Talon alphabet, you’ll be uttering less than half of the syllables needed compared to the NATO phonetic alphabet in order to be productive.&lt;/p&gt;

&lt;p&gt;I learned the Talon alphabet fluently with around one hour of dedicated practise time on a Sunday evening, and this website in particular, which uses a flashcard system, was incredibly helpful: &lt;a href="https://visualjerk.github.io/talon-learn-alphabet/#/" rel="noopener noreferrer"&gt;LearnTalon&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ramp up gradually before trying to code
&lt;/h3&gt;

&lt;p&gt;Before attempting to code, I would recommend learning a few more skills in using Talon to navigate and edit text (rather than jumping straight to Cursorless). This will also help you with general prose writing and navigating the web and your machine. &lt;a href="https://chaosparrot.github.io/talon_practice/" rel="noopener noreferrer"&gt;Talon Practise&lt;/a&gt; was incredibly useful for this, giving you the opportunity to practise particular skills in small, focussed exercises. My favourite exercise which I was very excited to master was the &lt;a href="https://chaosparrot.github.io/talon_practice/lessons/selection.html" rel="noopener noreferrer"&gt;copying, pasting and selection exercise&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Before using Cursorless, try using just Talon to edit some code. This will make the usefulness of Cursorless much more obvious if and when you decide to use it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Try small coding tasks before big ones
&lt;/h3&gt;

&lt;p&gt;We’ve all got jobs to do, and you’ve probably got quite a few big tickets looming over you on that project board. But you have to start small. Completing a small coding task with your voice, and committing and pushing the code in the terminal using your new-found Talon alphabet skills (&lt;em&gt;gust sit trap space say commit space dash made space quote say completed small task quote slap&lt;/em&gt;), will give you a feeling of accomplishment like no other. &lt;/p&gt;

&lt;p&gt;My first all-voice code change and commit was commenting out a function in my Twitch bot which I no longer needed, and committing and pushing that change in the terminal. &lt;a href="https://www.twitch.tv/whitep4nth3r/clip/DreamyNastyTroutPMSTwin-N_UdpsyTHdmj7JlG" rel="noopener noreferrer"&gt;Watch the clip on Twitch&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  You will get better
&lt;/h3&gt;

&lt;p&gt;After two weeks of using my voice to work and code for around 80% of the time, I was able to successfully (yet slowly) use Talon and Cursorless to add a whole new feature to my website, and I wrote about it here: &lt;a href="https://whitep4nth3r.com/blog/how-to-build-a-copy-code-snippet-button/" rel="noopener noreferrer"&gt;How to build a copy code snippet button and why it matters&lt;/a&gt;. You will get better at this, but it will take time and practice. Make sure to take regular breaks, because using your voice so much will be exhausting, not to mention the new cognitive overheads of trying to do your job in such a different way.&lt;/p&gt;

&lt;p&gt;Fortunately for me, my pain is also getting better and so I’ve been able to use my keyboard and trackpad more than I was able to over the last few weeks. That being said, given I have become comfortable with using my voice to code, write, and navigate the internet, I find myself switching between using my hands and voice throughout the day. Maybe it’s because I feel like I don’t want to lose this new skill that I had the necessity to learn, or maybe it serves as a cool party trick to demonstrate when live streaming. But more importantly, it hammers home the fact that one day we all might succumb to a temporary or permanent disability, and as web developers we have an important responsibility to build empathy and accessibility into our professional practice at all times.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>a11y</category>
    </item>
  </channel>
</rss>
