<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Full Stack Web Developement]]></title><description><![CDATA[This publication shares my Full-Stack Development journey, the challenges faced, and the solutions that helped. Join me in reflecting on the lessons learned and]]></description><link>https://blog.abdultalha.tech</link><generator>RSS for Node</generator><lastBuildDate>Thu, 09 Apr 2026 08:29:43 GMT</lastBuildDate><atom:link href="https://blog.abdultalha.tech/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Notes on Finding Remote Jobs]]></title><description><![CDATA[Introduction
This post shares my notes and reflections on how to find remote jobs, based on what I have learned by observing others, reading, and exploring different approaches.
I am writing this as someone who is still learning and experimenting, no...]]></description><link>https://blog.abdultalha.tech/notes-on-finding-remote-jobs</link><guid isPermaLink="true">https://blog.abdultalha.tech/notes-on-finding-remote-jobs</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[remote]]></category><category><![CDATA[remote work]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 19 Jan 2026 05:30:38 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768800549483/a9761e9d-feb4-4df5-b1f8-f102126ed2b4.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>This post shares my notes and reflections on <strong>how to find remote jobs</strong>, based on what I have learned by observing others, reading, and exploring different approaches.</p>
<p>I am writing this as someone who is still learning and experimenting, not as an expert.</p>
<p>If you are early in your career and trying to understand remote job opportunities, this might be helpful.</p>
<h2 id="heading-why-i-looked-into-remote-jobs">Why I Looked Into Remote Jobs</h2>
<p>I wanted to understand how people actually get remote jobs, beyond just applying on job portals.</p>
<p>I had heard about networking, building profiles, and open source before, but I wanted clearer direction on how these pieces fit together.</p>
<h2 id="heading-what-this-learning-focused-on">What This Learning Focused On</h2>
<p>The main focus was on two ways to find remote jobs:</p>
<ul>
<li><p>Applying to existing opportunities</p>
</li>
<li><p>Creating opportunities by building credibility</p>
</li>
</ul>
<p>It also highlighted common mistakes people make while searching for remote roles.</p>
<h2 id="heading-key-learnings">Key Learnings</h2>
<h3 id="heading-two-clear-ways-to-find-remote-jobs">Two Clear Ways to Find Remote Jobs</h3>
<p>Remote jobs can be approached in two main ways.</p>
<p>The first is applying directly by checking:</p>
<ul>
<li><p>Company career pages</p>
</li>
<li><p>Social media</p>
</li>
<li><p>Platforms like LinkedIn and X</p>
</li>
</ul>
<p>You can also reach out to company employees through LinkedIn messages, X, or cold emails and clearly express your interest.</p>
<p><strong>Why this matters:</strong><br />Many roles are filled through direct outreach and early visibility, not just job boards.</p>
<h3 id="heading-creating-opportunities-by-building-credibility">Creating Opportunities by Building Credibility</h3>
<p>The second approach is long-term but powerful.</p>
<p>Instead of only applying, you build a strong online presence through:</p>
<ul>
<li><p>A clear LinkedIn profile</p>
</li>
<li><p>Regular posts on X</p>
</li>
<li><p>A portfolio or blog</p>
</li>
<li><p>Sharing what you learn in public</p>
</li>
</ul>
<p><strong>Why this matters:</strong><br />When your work is visible, opportunities often come to you.</p>
<h3 id="heading-learning-in-public-and-networking">Learning in Public and Networking</h3>
<p>Learning in public means sharing progress, not perfection.</p>
<p>This includes:</p>
<ul>
<li><p>Posting what you are learning</p>
</li>
<li><p>Sharing small wins and lessons</p>
</li>
<li><p>Writing simple blogs on platforms like Hashnode</p>
</li>
</ul>
<p>Networking here is about conversations, not asking for jobs.</p>
<p><strong>Why this matters:</strong><br />People trust and remember consistent learners.</p>
<h3 id="heading-open-source-as-a-career-signal">Open Source as a Career Signal</h3>
<p>Contributing to open source shows real skills.</p>
<p>It helps others see:</p>
<ul>
<li><p>How you work</p>
</li>
<li><p>What you know</p>
</li>
<li><p>How consistent you are</p>
</li>
</ul>
<p><strong>Why this matters:</strong><br />Open source becomes proof of work without needing explanations.</p>
<h2 id="heading-common-mistakes-to-avoid">Common Mistakes to Avoid</h2>
<h3 id="heading-lack-of-clarity">Lack of Clarity</h3>
<p>Not knowing what role you want slows everything down.<br />Explore different fields, then choose one direction.</p>
<h3 id="heading-chasing-numbers-instead-of-credibility">Chasing Numbers Instead of Credibility</h3>
<p>Followers do not matter if your profile has no substance.<br />Skills and consistency matter more.</p>
<h3 id="heading-giving-up-too-early">Giving Up Too Early</h3>
<p>Remote jobs take time.<br />Stopping too soon is a common mistake.</p>
<h3 id="heading-taking-rejection-personally">Taking Rejection Personally</h3>
<p>Rejections are part of the process.<br />They help you improve if you stay patient.</p>
<h3 id="heading-lack-of-patience">Lack of Patience</h3>
<p>Remote hiring moves slowly.<br />Consistency matters more than speed.</p>
<h2 id="heading-things-that-made-me-think">Things That Made Me Think</h2>
<ol>
<li><p>Clarity matters more than applying everywhere</p>
</li>
<li><p>Visibility builds trust over time</p>
</li>
<li><p>Open work speaks louder than resumes</p>
</li>
<li><p>Patience is a real skill in remote job search</p>
</li>
</ol>
<h2 id="heading-my-reflections">My Reflections</h2>
<p>This learning made me realize that remote jobs are not about shortcuts.</p>
<p>They are about clarity, steady effort, and showing your work openly.</p>
<h2 id="heading-what-im-taking-forward">What I’m Taking Forward</h2>
<ol>
<li><p>Be clear about what I want</p>
</li>
<li><p>Build credibility step by step</p>
</li>
<li><p>Share learning without pressure</p>
</li>
<li><p>Stay patient and consistent</p>
</li>
</ol>
<h2 id="heading-reference">Reference</h2>
<p>A <a target="_blank" href="https://www.youtube.com/watch?v=Hi8FCUYZhMk">Conversation</a> on finding remote jobs.</p>
]]></content:encoded></item><item><title><![CDATA[Notes on Getting Remote Jobs Through Open Source and Learning in Public]]></title><description><![CDATA[Introduction
This post shares my notes and reflections after watching a conversation on getting remote jobs through open source and learning in public.
I am writing this as someone who is still learning and exploring these ideas, not as an expert.
If...]]></description><link>https://blog.abdultalha.tech/notes-on-getting-remote-jobs-through-open-source-and-learning-in-public</link><guid isPermaLink="true">https://blog.abdultalha.tech/notes-on-getting-remote-jobs-through-open-source-and-learning-in-public</guid><category><![CDATA[Open Source]]></category><category><![CDATA[remote work]]></category><category><![CDATA[learning]]></category><category><![CDATA[Technical writing ]]></category><category><![CDATA[Career]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 12 Jan 2026 08:46:53 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1768207269427/35a467e4-7eb1-4543-850c-234410dd3363.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>This post shares my notes and reflections after watching a conversation on getting remote jobs through open source and learning in public.</p>
<p>I am writing this as someone who is still learning and exploring these ideas, not as an expert.</p>
<p>If you’re early in your career and curious about remote opportunities and open source, this might be useful.</p>
<h2 id="heading-why-i-watched-this-conversation">Why I Watched This Conversation</h2>
<p>I wanted to understand how people actually find remote jobs through open source and how learning in public fits into that journey.</p>
<p>I had heard these ideas before, but this conversation helped connect them more clearly through real experiences.</p>
<h2 id="heading-what-the-conversation-focused-on">What the Conversation Focused On</h2>
<p>The discussion covered open source contributions, consistency, building projects in public, technical writing, and how these efforts can gradually lead to remote opportunities.</p>
<h2 id="heading-key-learnings-from-the-conversation">Key Learnings from the Conversation</h2>
<h3 id="heading-its-never-too-late-to-start-open-source">It’s Never Too Late to Start Open Source</h3>
<p>A key point was that timing and age do not matter in open source.</p>
<p>What matters is starting and staying consistent.</p>
<p><strong>Why this matters:</strong><br />Waiting for the “right time” often delays growth more than lack of skills.</p>
<h3 id="heading-consistency-matters-more-than-speed">Consistency Matters More Than Speed</h3>
<p>Regular contributions help people notice your work over time.</p>
<p>This naturally helps in building a network and trust.</p>
<p><strong>Why this matters:</strong><br />Most meaningful opportunities come from consistent effort, not quick results.</p>
<h3 id="heading-open-source-projects-act-as-proof-of-work">Open Source Projects Act as Proof of Work</h3>
<p>Building projects in public and keeping them open makes your work visible.</p>
<p>You don’t need to explain everything repeatedly your work speaks for itself.</p>
<p><strong>Why this matters:</strong></p>
<p>Open work becomes real proof of learning and capability.</p>
<h3 id="heading-learning-in-public-through-technical-writing">Learning in Public Through Technical Writing</h3>
<p>Technical writing was discussed as a simple way to learn in public.</p>
<p>Platforms like Hashnode allow you to convert raw notes into clear articles, which can sometimes reach wider developer communities.</p>
<p><strong>Why this matters:</strong></p>
<p>Writing helps you learn better while sharing value with others.</p>
<h3 id="heading-focus-on-sharing-not-immediate-outcomes">Focus on Sharing, Not Immediate Outcomes</h3>
<p>A strong message was to avoid focusing on what you’ll get in return.</p>
<p>Instead, focus on contributing, learning, and sharing honestly.</p>
<p><strong>Why this matters:</strong><br />When contribution is the goal, outcomes often follow naturally.</p>
<h2 id="heading-things-that-made-me-think">Things That Made Me Think</h2>
<ul>
<li><p>Age and timing matter less than consistency</p>
</li>
<li><p>Open source quietly builds strong networks</p>
</li>
<li><p>Writing is a powerful learning tool</p>
</li>
<li><p>Growth doesn’t need to be fast or loud</p>
</li>
</ul>
<h2 id="heading-my-reflections">My Reflections</h2>
<p>This conversation reinforced the importance of sharing what I’m learning and learning from others’ experiences.</p>
<p>It reminded me that steady contribution and openness matter more than chasing quick results.</p>
<h2 id="heading-what-im-taking-forward">What I’m Taking Forward</h2>
<ul>
<li><p>Start and stay consistent with open source</p>
</li>
<li><p>Share learning without pressure</p>
</li>
<li><p>Focus on community and clarity</p>
</li>
<li><p>Use writing as a thinking tool</p>
</li>
</ul>
<h2 id="heading-reference">Reference</h2>
<p>A <a target="_blank" href="https://www.youtube.com/watch?v=933PZFO56P0&amp;t=12s">conversation</a> on open source, remote jobs, and learning in public featuring <strong>Kunal Kushwaha</strong>.</p>
]]></content:encoded></item><item><title><![CDATA[Notes from a Video on Remote Jobs and Learning in Public]]></title><description><![CDATA[I recently watched a conversation between Kunal Kushwaha and Francisco about remote work, learning in public, and finding opportunities while growing in your career.
While watching the video, I wrote down a few points that stood out to me. This post ...]]></description><link>https://blog.abdultalha.tech/notes-from-a-video-on-remote-jobs-and-learning-in-public</link><guid isPermaLink="true">https://blog.abdultalha.tech/notes-from-a-video-on-remote-jobs-and-learning-in-public</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[remote work]]></category><category><![CDATA[BlogsWithCC]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 05 Jan 2026 09:10:47 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767604168887/0d3c3ecc-fc42-4f78-88a7-f9551d38b30d.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I recently watched a conversation between Kunal Kushwaha and Francisco about remote work, learning in public, and finding opportunities while growing in your career.</p>
<p>While watching the video, I wrote down a few points that stood out to me. This post is simply me organising those notes and sharing my reflections.</p>
<h2 id="heading-why-i-watched-this-video">Why I Watched This Video</h2>
<p>I wanted to understand how people actually find remote jobs and how learning in public plays a role in that journey.</p>
<p>I’ve heard these ideas mentioned before, but this conversation helped me connect them more clearly with real experiences.</p>
<h2 id="heading-key-learnings-from-the-video">Key Learnings from the Video</h2>
<h3 id="heading-remote-work-removes-daily-travel-stress">Remote Work Removes Daily Travel Stress</h3>
<p>One of the first things discussed was how remote work eliminates travel time.</p>
<p>If your office is far away, commuting can take up a big part of your day and add unnecessary stress.<br />With remote work, you start your day fresh, without that mental and physical exhaustion.</p>
<p>That alone changes how you show up at work.</p>
<h3 id="heading-remote-work-encourages-better-communication">Remote Work Encourages Better Communication</h3>
<p>In remote jobs, most communication happens through video calls.</p>
<p>Because of this, you naturally start getting more comfortable being on camera.<br />Over time, this helps reduce hesitation and awkwardness when speaking online.</p>
<p>This comfort doesn’t stay limited to work it slowly extends to other areas like social media and public communication.</p>
<h3 id="heading-company-offsites-help-build-real-connections">Company Offsites Help Build Real Connections</h3>
<p>Even in remote companies, offsites play an important role.</p>
<p>Meeting teammates in person, even occasionally, helps you understand people better beyond screens.<br />It strengthens relationships and makes collaboration feel more human.</p>
<h3 id="heading-learning-in-public-builds-credibility">Learning in Public Builds Credibility</h3>
<p>A major point from the conversation was about <em>learning in public</em>.</p>
<p>Sharing what you’re learning helps build:</p>
<ul>
<li><p>Credibility</p>
</li>
<li><p>Proof of work</p>
</li>
<li><p>Visibility over time</p>
</li>
</ul>
<p>This doesn’t mean pretending to be an expert.<br />It simply means documenting your learning honestly.</p>
<p>Over time, this can naturally lead to opportunities including job offers.</p>
<h3 id="heading-ways-to-learn-in-public">Ways to Learn in Public</h3>
<p>Some ways mentioned in the video:</p>
<ul>
<li><p>Writing posts on Twitter or LinkedIn</p>
</li>
<li><p>Writing blogs on platforms like Hashnode or Medium</p>
</li>
<li><p>Sharing small learnings, not polished tutorials</p>
</li>
</ul>
<p>The idea is consistency, not perfection.</p>
<h3 id="heading-for-introverts-start-small">For Introverts: Start Small</h3>
<p>The conversation also touched on introverts and how they can get started.</p>
<p>You don’t need to force yourself into big meetups or conferences immediately.<br />It’s okay to take things step by step.</p>
<p>Start small:</p>
<ul>
<li><p>Write a short post</p>
</li>
<li><p>Share a simple thought</p>
</li>
<li><p>Slowly build confidence</p>
</li>
</ul>
<p>There’s no need to put too much pressure on yourself.</p>
<h2 id="heading-things-that-made-me-think">Things That Made Me Think</h2>
<ul>
<li><p>Comfort with the camera is becoming an important skill</p>
</li>
<li><p>Communication matters as much as technical ability</p>
</li>
<li><p>Growth doesn’t need to be loud or fast</p>
</li>
</ul>
<p>The video made it clear that improvement happens gradually.</p>
<h2 id="heading-my-reflections">My Reflections</h2>
<p>One strong takeaway for me was the importance of being comfortable on camera.</p>
<p>If you are comfortable speaking on camera:</p>
<ul>
<li><p>You can join remote meetings confidently</p>
</li>
<li><p>You can create video content if you want</p>
</li>
<li><p>You open yourself up to more future opportunities</p>
</li>
</ul>
<p>It’s not about becoming a content creator overnight.<br />It’s about reducing fear and being open to showing up.</p>
<p>This video made me realise that many future opportunities come from being visible and comfortable expressing yourself.</p>
<h2 id="heading-what-im-taking-forward">What I’m Taking Forward</h2>
<p>I don’t feel the need to rush anything.</p>
<p>For now, I want to focus on:</p>
<ul>
<li><p>Improving one step at a time</p>
</li>
<li><p>Being more comfortable communicating</p>
</li>
<li><p>Sharing my learning honestly, without pressure</p>
</li>
</ul>
<p>This post itself is part of that process.</p>
<h2 id="heading-reference">Reference</h2>
<ul>
<li><p>Conversation between Kunal Kushwaha and Francisco</p>
</li>
<li><p>Topic: <a target="_blank" href="https://www.youtube.com/watch?v=3YafUJUqj6s&amp;t=38s">Remote jobs and learning in public</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How I thought Resume Building After Watching a Conversation with Kunal Kushwaha and Matt van Itallie]]></title><description><![CDATA[Introduction
I watched this conversation to understand how resumes actually work in the tech industry. I wasn’t looking for templates or formatting tricks. I wanted clarity on how resumes signal value, especially for someone early in their career.
In...]]></description><link>https://blog.abdultalha.tech/how-i-thought-resume-building-after-watching-a-conversation-with-kunal-kushwaha-and-matt-van-itallie</link><guid isPermaLink="true">https://blog.abdultalha.tech/how-i-thought-resume-building-after-watching-a-conversation-with-kunal-kushwaha-and-matt-van-itallie</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[resume]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 29 Dec 2025 17:05:39 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1767015665818/877b6a18-02d0-4044-9394-bc0e9b87d209.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I watched this conversation to understand how resumes actually work in the tech industry. I wasn’t looking for templates or formatting tricks. I wanted clarity on how resumes signal value, especially for someone early in their career.</p>
<p>Instead of focusing on design or keywords, the discussion centred on <strong>thinking systems,</strong> how to observe your work, document it, and translate it into evidence. That perspective made me revisit how I was building my own resume.</p>
<h2 id="heading-key-learnings">Key Learnings</h2>
<h3 id="heading-1-accomplishments-matter-more-than-responsibilities">1. Accomplishments matter more than responsibilities</h3>
<p>A resume should highlight outcomes, not task lists. Instead of describing what I did, I should show what changed because of my work and what I learned from it.</p>
<h3 id="heading-2-comparative-analysis-helps-identify-the-right-work">2. Comparative analysis helps identify the right work</h3>
<p>By listing every meaningful experience and separating what I liked from what I didn’t, patterns emerge. These patterns reveal the intersection between my personality and the type of work I should pursue in the future.</p>
<h3 id="heading-3-maintaining-an-accomplishment-journal-is-essential">3. Maintaining an accomplishment journal is essential</h3>
<p>An accomplishment journal helps track:</p>
<ul>
<li><p>Moments of success</p>
</li>
<li><p>Situations where I worked hard</p>
</li>
<li><p>New skills I learned</p>
</li>
<li><p>Instances where I helped or taught others</p>
</li>
</ul>
<p>This makes resume writing concrete instead of relying on memory.</p>
<h3 id="heading-4-accomplishment-journals-improve-interview-readiness">4. Accomplishment journals improve interview readiness</h3>
<p>By documenting experiences clearly, I can frame them as stories during interviews. Specific stories are easier to remember and explain than vague claims.</p>
<h3 id="heading-5-feedback-is-evidence-not-validation">5. Feedback is evidence, not validation</h3>
<p>Recording compliments or positive feedback from teachers, peers, or managers helps identify strengths objectively. These entries act as external proof of impact.</p>
<h3 id="heading-6-the-logical-model-clarifies-resume-bullet-points">6. The logical model clarifies resume bullet points</h3>
<p>Each experience can be structured using:</p>
<ul>
<li><p>Resources available</p>
</li>
<li><p>Activities performed</p>
</li>
<li><p>Outputs produced</p>
</li>
<li><p>Outcomes achieved</p>
</li>
</ul>
<p>This approach forces clarity and removes ambiguity from resume content.</p>
<h3 id="heading-7-resume-structure-should-prioritise-clarity-over-design">7. Resume structure should prioritise clarity over design</h3>
<p>For early-career professionals:</p>
<ul>
<li><p>Keep the resume to one page</p>
</li>
<li><p>Avoid visuals, colours, or decorative elements</p>
</li>
<li><p>Use margins between 0.5 and 1 inch</p>
</li>
<li><p>Fill about 80–85% of the page to allow breathing space</p>
</li>
</ul>
<p>Structure and content matter more than appearance.</p>
<h3 id="heading-8-removing-the-summary-section-improves-focus">8. Removing the summary section improves focus</h3>
<p>Early in a career, summaries often repeat claims without evidence. Removing them creates space for concrete accomplishments instead.</p>
<h3 id="heading-9-the-50-hour-rule-defines-what-belongs-on-a-resume">9. The 50-hour rule defines what belongs on a resume</h3>
<p>Any meaningful work done for at least 50 hours (sometimes even 25) is worth mentioning. This includes projects, features built, code reviews, and quality improvements.</p>
<h3 id="heading-10-reflection-matters-more-than-frequent-updates">10. Reflection matters more than frequent updates</h3>
<p>The hardest part of resume building is not writing, it’s remembering. Spending one hour each week reflecting and updating an accomplishment journal solves this problem.</p>
<h3 id="heading-11-numbers-turn-effort-into-evidence">11. Numbers turn effort into evidence</h3>
<p>Adding numbers wherever possible transforms normal statements into measurable impact. Numbers make contributions easier to understand and evaluate.</p>
<h2 id="heading-my-reflection">My Reflection</h2>
<ul>
<li><p>This video gave me a new perspective on building a resume beyond formatting and templates.</p>
</li>
<li><p>I understood the importance of maintaining an accomplishment journal to document meaningful work consistently.</p>
</li>
<li><p>I learned how to structure a resume with a clear focus on layout, visuals, and content, without depending on design elements.</p>
</li>
</ul>
<h2 id="heading-behind-the-scenes"><strong>Behind the Scenes</strong></h2>
<p>While watching this video, I wrote all my notes in my <strong>physical notebook</strong>. Writing by hand helps me slow down and think clearly. Later, I convert those raw notes into a structured blog.</p>
<p>This process helps me:</p>
<ul>
<li><p>understand ideas deeply</p>
</li>
<li><p>reflect on what I learn</p>
</li>
<li><p>track my progress over time</p>
</li>
</ul>
<p>This is a core part of my Learn in Public journey.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>This conversation opened a different way to think about resumes, rooted in observation, evidence, and clarity. Instead of chasing perfection in formatting, I learned to focus on documenting meaningful work consistently.</p>
<p>For me, resume building is no longer a one-time task. It’s a habit.</p>
]]></content:encoded></item><item><title><![CDATA[Utilising Open Source for Career Advancement]]></title><description><![CDATA[Introduction
Recently, I watched a conversation between Matt van Itallie and Kunal Kushwaha about utilising open source for career advancement. Matt shared insights from his experience working at a company that builds code quality tools and actively ...]]></description><link>https://blog.abdultalha.tech/utilising-open-source-for-career-advancement</link><guid isPermaLink="true">https://blog.abdultalha.tech/utilising-open-source-for-career-advancement</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[learning]]></category><category><![CDATA[Learning Journey]]></category><category><![CDATA[contribution to open source]]></category><category><![CDATA[remote]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 22 Dec 2025 06:50:06 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1766386003278/123ff0bb-1d11-4d48-8045-7e542d8c139c.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>Recently, I watched a <a target="_blank" href="https://youtu.be/NAWAY5awdM8?si=kA_8Jx5waULfPFko">conversation</a> between <strong>Matt van Itallie</strong> and <strong>Kunal Kushwaha</strong> about utilising open source for career advancement. Matt shared insights from his experience working at a company that builds code quality tools and actively contributes to open source.</p>
<p>At this stage of my journey, I am actively contributing to open source and trying to understand which tech paths suit me best. This video helped me see how open source can be used not just for learning, but also for skill growth, career exploration, and long term direction.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<h3 id="heading-about-sema"><strong>About Sema</strong></h3>
<p>Sema is a company that builds tools to improve code quality and code releases. They work closely with open source projects, where anyone can read the code, copy it, and raise issues. Maintainers review contributions and guide contributors to keep the project healthy.</p>
<p>This shows how companies rely on open source not only to build products, but also to grow strong communities.</p>
<h3 id="heading-what-is-open-source"><strong>What Is Open Source</strong></h3>
<p>Open source means software whose code is publicly available. Anyone can:</p>
<ul>
<li><p>view the code</p>
</li>
<li><p>report issues</p>
</li>
<li><p>suggest improvements</p>
</li>
<li><p>contribute changes</p>
</li>
</ul>
<p>This open model allows people across the world to build software together and learn from real systems.</p>
<h3 id="heading-how-contribution-helps"><strong>How Contribution Helps</strong></h3>
<p>Contributing to open source helps in many ways:</p>
<ol>
<li><p><strong>Skilling up</strong><br /> You improve your skills through real code reviews and practical feedback.</p>
</li>
<li><p><strong>Mentorship</strong><br /> You learn from maintainers and experienced contributors who guide you.</p>
</li>
<li><p><strong>Resume building</strong><br /> Your contributions act as proof of work and show what you can actually do.</p>
</li>
<li><p><strong>Networking</strong><br /> You connect with people working in the same domain and build professional relationships.</p>
</li>
<li><p><strong>Self exploration</strong><br /> You can test whether a tech stack or role suits you before committing to it.</p>
</li>
</ol>
<p>This matters because learning through real work is far more effective than only studying theory.</p>
<h3 id="heading-roadmap-for-beginners"><strong>Roadmap for Beginners</strong></h3>
<p>A simple roadmap for beginners is:</p>
<ul>
<li><p>Pick one organisation</p>
</li>
<li><p>Choose an active community</p>
</li>
<li><p>observe communication for one week</p>
</li>
<li><p>start with small issues</p>
</li>
<li><p>move to bigger contributions slowly</p>
</li>
</ul>
<p>This approach helps beginners avoid confusion and build confidence step by step.</p>
<h3 id="heading-how-to-contribute-and-reach-out-to-companies"><strong>How to Contribute and Reach Out to Companies</strong></h3>
<p>Instead of asking directly for jobs:</p>
<ul>
<li><p>contribute consistently</p>
</li>
<li><p>help solve real problems</p>
</li>
<li><p>show learning through your work</p>
</li>
</ul>
<p>When your contributions create value, companies notice naturally. Conversations start based on trust, not requests.</p>
<h3 id="heading-five-rules-of-a-great-contributor"><strong>Five Rules of a Great Contributor</strong></h3>
<p>Some important rules to follow are:</p>
<ul>
<li><p>Focus on a few things and do them well</p>
</li>
<li><p>be consistent</p>
</li>
<li><p>respect maintainers’ time</p>
</li>
<li><p>communicate clearly</p>
</li>
<li><p>be empathetic and helpful</p>
</li>
</ul>
<p>These habits make collaboration smoother and build long-term trust.</p>
<h3 id="heading-getting-hired"><strong>Getting Hired</strong></h3>
<p>Open source helps with hiring because:</p>
<ul>
<li><p>Your work is visible</p>
</li>
<li><p>Your contributions show real skills</p>
</li>
<li><p>Recruiters can see your growth over time</p>
</li>
</ul>
<p>This matters because proof of work builds more trust than resumes alone.</p>
<h3 id="heading-best-tech-stack-to-contribute"><strong>Best Tech Stack to Contribute</strong></h3>
<p>There is no single best tech stack. The right stack is one that:</p>
<ul>
<li><p>genuinely interests you</p>
</li>
<li><p>has active maintainers</p>
</li>
<li><p>offers beginner-friendly issues</p>
</li>
</ul>
<p>Enjoyment and consistency matter more than choosing a popular stack.</p>
<h3 id="heading-learn-in-public"><strong>Learn in Public</strong></h3>
<p>Learning in public means:</p>
<ul>
<li><p>asking questions openly</p>
</li>
<li><p>sharing progress</p>
</li>
<li><p>discussing challenges</p>
</li>
</ul>
<p>This helps others learn and slowly builds your credibility through consistency.</p>
<h3 id="heading-which-contributions-look-good"><strong>Which Contributions Look Good</strong></h3>
<p>Good contributions are:</p>
<ul>
<li><p>consistent</p>
</li>
<li><p>useful to the project</p>
</li>
<li><p>well documented</p>
</li>
<li><p>respectful in communication</p>
</li>
</ul>
<p>Quality matters more than the number of contributions.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>My biggest learning from this video is:</p>
<ul>
<li><p><strong>Safe exploration</strong><br />  Open source allows me to explore whether a particular tech stack or role suits me without long-term commitment.</p>
</li>
<li><p><strong>Choosing the right organisation</strong><br />  Selecting an active and supportive organisation matters for learning and growth.</p>
</li>
<li><p><strong>Good contribution practices</strong><br />  Following contribution guidelines and asking questions in public channels helps build trust and visibility.</p>
</li>
</ul>
<h2 id="heading-behind-the-scenes"><strong>Behind the Scenes</strong></h2>
<p>While watching this video, I wrote all my notes in my <strong>physical notebook</strong>. Writing by hand helps me slow down and think clearly. Later, I convert those raw notes into a structured blog.</p>
<p>This process helps me:</p>
<ul>
<li><p>understand ideas deeply</p>
</li>
<li><p>reflect on what I learn</p>
</li>
<li><p>track my progress over time</p>
</li>
</ul>
<p>This is a core part of my Learn in Public journey.</p>
<p>(This is where I add images of my handwritten notes.)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1766386427807/78679026-b058-474f-bf4f-ddf9066258cc.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>Open source is not just about writing code. It helps with learning, networking, career exploration, and building trust.</p>
<p>This conversation reminded me that consistent and thoughtful contributions can quietly shape a strong career over time.</p>
]]></content:encoded></item><item><title><![CDATA[My First Contribution to Zulip: Fixing Empty Topic Display in Email Notifications (#36689)]]></title><description><![CDATA[1. Introduction – Why Zulip, Why This Issue
After contributing to Ghost's open-source codebase and learning the process of distributed collaboration, I wanted to explore a different type of project. Zulip caught my attention because of its unique app...]]></description><link>https://blog.abdultalha.tech/my-first-contribution-to-zulip-fixing-empty-topic-display-in-email-notifications-36689</link><guid isPermaLink="true">https://blog.abdultalha.tech/my-first-contribution-to-zulip-fixing-empty-topic-display-in-email-notifications-36689</guid><category><![CDATA[Open Source]]></category><category><![CDATA[Git]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Python]]></category><category><![CDATA[Django]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 15 Dec 2025 17:00:10 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765797855365/a808bb0d-27ab-4f86-bda1-e3a48b54cd60.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-1-introduction-why-zulip-why-this-issue">1. Introduction – Why Zulip, Why This Issue</h2>
<p>After contributing to Ghost's open-source codebase and learning the process of distributed collaboration, I wanted to explore a different type of project. Zulip caught my attention because of its unique approach to team communication and its well-documented, beginner-friendly contribution process.</p>
<p>What attracted me to Zulip was its thoughtful architecture – a Django backend with modern frontend tooling, comprehensive testing, and a strong focus on code quality. The project felt mature yet welcoming to newcomers.</p>
<p>I picked issue <a target="_blank" href="https://github.com/zulip/zulip/pull/37059">#36689</a> because it was labelled as a help-wanted issue and involved email notifications – a feature that directly impacts user experience. The problem was clear: empty topics in digest emails were showing raw HTML instead of the expected "general chat" display.</p>
<h2 id="heading-2-understanding-the-problem">2. Understanding the Problem</h2>
<p>The issue affected users receiving email digest notifications when:</p>
<ul>
<li><p>Messages were posted to topics with empty names</p>
</li>
<li><p>The digest email would display raw HTML like <code>&lt;span class="empty-topic-display"&gt;general chat&lt;/span&gt;</code></p>
</li>
<li><p>Instead of the clean, localised "general chat" text</p>
</li>
</ul>
<p>This created a poor user experience and made Zulip look unprofessional in email clients. The problem occurred specifically in digest emails, not in the web interface, where empty topics displayed correctly.</p>
<p><strong>Expected behaviour</strong>: Clean "general chat" text.</p>
<p><strong>Actual behaviour</strong>: Raw HTML markup visible to users</p>
<h2 id="heading-3-reproducing-the-issue-locally">3. Reproducing the Issue Locally</h2>
<p>I set up my local Zulip development environment following their excellent documentation:</p>
<pre><code class="lang-bash">./tools/provision
./tools/run-dev
</code></pre>
<p>To reproduce the issue, I:</p>
<ul>
<li><p>Created messages in topics with empty names</p>
</li>
<li><p>Navigated to <a target="_blank" href="http://localhost:9991/digest/"><code>http://localhost:9991/digest/</code></a> to preview digest emails</p>
</li>
<li><p>Confirmed the raw HTML was visible in the email preview</p>
</li>
<li><p>Checked both HTML and plain text versions of the digest</p>
</li>
</ul>
<p>The issue was clearly visible in the digest preview, making it easy to verify the problem and later test the fix.</p>
<h2 id="heading-4-visual-evidence-before-and-after">4. Visual Evidence: Before and After</h2>
<h3 id="heading-before-fix-raw-html-displayed">Before Fix - Raw HTML Displayed</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Email Preview</td><td>Issue</td></tr>
</thead>
<tbody>
<tr>
<td></td><td>Raw HTML <code>&lt;span class="empty-topic-display"&gt;general chat&lt;/span&gt;</code> visible to users</td></tr>
</tbody>
</table>
</div><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765798113848/0222897c-786f-4830-bc91-86c4a3719e1e.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765798129478/419f45a9-2766-4cc4-9c8c-e0a16888eb0e.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-after-fix-clean-display">After Fix - Clean Display</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Email Preview</td><td>Fixed</td></tr>
</thead>
<tbody>
<tr>
<td></td><td>Clean "general chat" text properly rendered</td></tr>
</tbody>
</table>
</div><p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765798155030/c8809222-8dd2-4033-9fb1-612970934723.png" alt class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765798169726/8849f0c0-a347-4917-9379-5de887efbba8.png" alt class="image--center mx-auto" /></p>
<p>The difference is immediately apparent - users now see professional, clean email formatting instead of confusing HTML markup.</p>
<h2 id="heading-5-tracing-the-root-cause">5. Tracing the Root Cause</h2>
<p>At first, I thought this was a simple templating issue in the email templates. I spent time looking through the digest email templates, expecting to find incorrect HTML escaping.</p>
<p>After reading through the codebase more carefully, I realised the issue was deeper in the email notification logic. The problem was in <code>zerver/lib/email_</code><a target="_blank" href="http://notifications.py"><code>notifications.py</code></a> in the <code>digest_block_header</code> function.</p>
<p>The actual root cause was a type annotation issue. The code was creating <code>Markup</code> objects inconsistently:</p>
<ul>
<li><p>For empty topics: using <code>Markup().format()</code> with proper escaping</p>
</li>
<li><p>For non-empty topics: directly wrapping in <code>Markup()</code> without escaping</p>
</li>
</ul>
<p>This inconsistency meant the type checker couldn't properly validate the code, and the HTML rendering behaved differently for empty vs non-empty topics.</p>
<h2 id="heading-6-the-fix-what-i-changed-and-why">6. The Fix (What I Changed and Why)</h2>
<p>I needed to ensure both empty and non-empty topics were created <code>Markup</code> objects consistently while maintaining proper HTML escaping.</p>
<p>The solution was to:</p>
<ol>
<li><p>Use <code>escape()</code> to safely handle user input for topic names</p>
</li>
<li><p>Create <code>Markup</code> objects consistently for both cases</p>
</li>
<li><p>Maintain the special styling for empty topics with the CSS class</p>
</li>
</ol>
<p>I chose this approach because:</p>
<ul>
<li><p>It maintains security by properly escaping user input</p>
</li>
<li><p>It fixes the type annotation issues</p>
</li>
<li><p>It keeps the existing functionality for empty topic styling</p>
</li>
<li><p>It's minimal and doesn't change the overall architecture</p>
</li>
</ul>
<p>The key insight was that <code>Markup().format()</code> auto-escapes parameters, but directly wrapping strings in <code>Markup()</code> bypasses escaping – a potential XSS vulnerability.</p>
<h2 id="heading-7-testing-the-fix">7. Testing the Fix</h2>
<p>I tested the fix thoroughly:</p>
<p><strong>Manual testing:</strong></p>
<ul>
<li><p>Verified digest preview at <a target="_blank" href="http://localhost:9991/digest/"><code>http://localhost:9991/digest/</code></a> displayed correctly</p>
</li>
<li><p>Checked both HTML and plain text versions</p>
</li>
<li><p>Tested with various topic names, including edge cases</p>
</li>
</ul>
<p><strong>Automated testing:</strong></p>
<pre><code class="lang-bash">./tools/lint --skip=gitlint zerver/lib/email_notifications.py
./tools/test-backend zerver/tests/test_email_notifications.py
./tools/run-mypy
</code></pre>
<p>I also added a specific test case <code>test_empty_topic_display_in_digest_email</code> to ensure this regression wouldn't happen again.</p>
<p><strong>Edge cases verified:</strong></p>
<ul>
<li><p>Empty topic names</p>
</li>
<li><p>Topics with special characters</p>
</li>
<li><p>Topics with potential HTML content</p>
</li>
</ul>
<h2 id="heading-8-submitting-the-pull-request">8. Submitting the Pull Request</h2>
<p>I submitted <a target="_blank" href="https://github.com/zulip/zulip/pull/37059"><strong>PR #37059</strong></a> with a clear description following Zulip's guidelines:</p>
<ul>
<li><p>Explained the problem and solution</p>
</li>
<li><p>Included testing steps</p>
</li>
<li><p>Referenced the original issue #36689</p>
</li>
</ul>
<p>The PR went through Zulip's automated checks:</p>
<ul>
<li><p>Linting passed</p>
</li>
<li><p>Type checking passed</p>
</li>
<li><p>All tests passed</p>
</li>
<li><p>Security review flagged an initial XSS concern</p>
</li>
</ul>
<p>I quickly addressed the security feedback with a second commit, properly escaping the user input before wrapping it in <code>Markup()</code>.</p>
<p><strong>Pull Request Link</strong>: <a target="_blank" href="https://github.com/zulip/zulip/pull/37059">https://github.com/zulip/zulip/pull/37059</a></p>
<h2 id="heading-9-what-i-learned">9. What I Learned</h2>
<p><strong>Technical Learnings:</strong></p>
<ul>
<li><p>How Django's <code>Markup</code> class works and its security implications</p>
</li>
<li><p>The importance of consistent type annotations in large codebases</p>
</li>
<li><p>Zulip's comprehensive testing approach and tooling</p>
</li>
<li><p>The difference between auto-escaping and manual escaping in templates</p>
</li>
</ul>
<p><strong>Non-Technical Learnings:</strong></p>
<ul>
<li><p>How to read and understand large, well-organised codebases</p>
</li>
<li><p>The value of thorough local testing before submitting</p>
</li>
<li><p>How security-conscious open source projects operate</p>
</li>
<li><p>The importance of clear, focused commits and PR descriptions</p>
</li>
</ul>
<p>The most valuable lesson was understanding that good open source contributions aren't just about fixing bugs – they're about maintaining code quality, security, and consistency across the entire project.</p>
<h2 id="heading-10-final-thoughts">10. Final Thoughts</h2>
<p>This contribution gave me confidence that I can meaningfully contribute to large, complex projects. The Zulip community's focus on mentoring new contributors and maintaining high standards created an excellent learning environment.</p>
<p>I'm excited to continue contributing to Zulip, potentially tackling more complex issues as I become more familiar with the codebase. The experience reinforced that open source contribution is as much about learning and collaboration as it is about coding.</p>
<p>For anyone considering their first Zulip contribution: the documentation is excellent, the community is welcoming, and the codebase is well-organised. Don't hesitate to dive in!</p>
<h2 id="heading-11-resources">11. Resources</h2>
<ul>
<li><p><strong>Zulip Repository</strong>: <a target="_blank" href="https://github.com/zulip/zulip">https://github.com/zulip/zulip</a></p>
</li>
<li><p><strong>Original Issue</strong>: <a target="_blank" href="https://github.com/zulip/zulip/issues/36689">https://github.com/zulip/zulip/issues/36689</a></p>
</li>
<li><p><strong>My Pull Request</strong>: <a target="_blank" href="https://github.com/zulip/zulip/pull/37059">https://github.com/zulip/zulip/pull/37059</a></p>
</li>
<li><p><strong>Zulip Development Documentation</strong>: <a target="_blank" href="https://zulip.readthedocs.io/en/latest/development/overview.html">https://zulip.readthedocs.io/en/latest/development/overview.html</a></p>
</li>
<li><p><strong>Zulip Contributing Guide</strong>: <a target="_blank" href="https://github.com/zulip/zulip/blob/main/CONTRIBUTING.md">https://github.com/zulip/zulip/blob/main/CONTRIBUTING.md</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[From Ghost to Zulip: Setting Up My Local Development Environment]]></title><description><![CDATA[Introduction
Setting up Zulip locally is not a typical Django setup.
After contributing to Ghost, I wanted to challenge myself with a larger backend system, one that reflects real-world complexity. Zulip stood out because of its scale, architecture, ...]]></description><link>https://blog.abdultalha.tech/from-ghost-to-zulip-setting-up-my-local-development-environment</link><guid isPermaLink="true">https://blog.abdultalha.tech/from-ghost-to-zulip-setting-up-my-local-development-environment</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[zulip]]></category><category><![CDATA[Python]]></category><category><![CDATA[Django]]></category><category><![CDATA[WSL]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 15 Dec 2025 10:14:22 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765105622943/d98545a8-9068-4e84-9318-a234e8e3bbfc.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Setting up <strong>Zulip locally</strong> is not a typical Django setup.</p>
<p>After contributing to <strong>Ghost</strong>, I wanted to challenge myself with a <strong>larger backend system,</strong> one that reflects real-world complexity. Zulip stood out because of its scale, architecture, and active open-source community.</p>
<p>Zulip is built using:</p>
<ul>
<li><p>Django</p>
</li>
<li><p>Tornado</p>
</li>
<li><p>PostgreSQL</p>
</li>
<li><p>RabbitMQ</p>
</li>
</ul>
<p>While the setup process is well-documented, I still faced some issues, especially around Python virtual environments and WSL configuration.</p>
<p>In this post, I’ll walk through:</p>
<ul>
<li><p>How I set up Zulip locally on WSL2</p>
</li>
<li><p>The issues I faced during setup</p>
</li>
<li><p>How I fixed them, including the tricky <code>activate_this.py</code> problem</p>
</li>
</ul>
<p>If you’re setting up Zulip for the first time, this guide should save you time and effort.</p>
<h2 id="heading-who-this-post-is-for">Who This Post Is For</h2>
<p>This post is helpful if you are:</p>
<ul>
<li><p>Contributing to <strong>Zulip</strong> for the first time</p>
</li>
<li><p>Moving from smaller projects to <strong>large backend systems</strong></p>
</li>
<li><p>Using <strong>WSL2 on Windows</strong></p>
</li>
<li><p>Facing Python 3.12 or <code>activate_this.py</code> issues during setup</p>
</li>
</ul>
<h2 id="heading-prerequisites-for-zulip-local-setup">Prerequisites for Zulip Local Setup</h2>
<p>Before starting, make sure your system meets these requirements.</p>
<h3 id="heading-general-requirements">General Requirements</h3>
<ul>
<li><p>2GB or more RAM</p>
</li>
<li><p>Stable internet connection</p>
</li>
<li><p>GitHub account</p>
</li>
</ul>
<h3 id="heading-windows-requirements">Windows Requirements</h3>
<ul>
<li><p>Windows 10 or 11 (64-bit)</p>
</li>
<li><p>Virtualisation enabled (VT-x / AMD-V)</p>
</li>
<li><p>Administrator access</p>
</li>
</ul>
<h2 id="heading-git-and-github-setup">Git and GitHub Setup</h2>
<p>If Git is already configured, you can skip this step.</p>
<p>Generate an SSH key:</p>
<pre><code class="lang-bash">ssh-keygen -t ed25519 -C <span class="hljs-string">"your_email@example.com"</span>
</code></pre>
<p>Copy the public key:</p>
<pre><code class="lang-bash">cat ~/.ssh/id_ed25519.pub
</code></pre>
<p>Add it to:<br /><strong>GitHub → Settings → SSH and GPG Keys</strong></p>
<p>This allows you to clone Zulip securely.</p>
<h2 id="heading-setting-up-wsl2-for-zulip-development">Setting Up WSL2 for Zulip Development</h2>
<blockquote>
<p>If you’re already using native Ubuntu or WSL2, you can skip this section.</p>
</blockquote>
<h3 id="heading-enable-virtualization">Enable Virtualization</h3>
<p>Enable <strong>VT-x / AMD-V</strong> in your BIOS.</p>
<h3 id="heading-install-wsl2">Install WSL2</h3>
<pre><code class="lang-bash">wsl --install
</code></pre>
<p>This installs Ubuntu automatically.</p>
<h3 id="heading-use-a-fresh-wsl-instance">Use a Fresh WSL Instance</h3>
<p>A clean WSL setup helps avoid conflicts with existing Python or Node installations.</p>
<h3 id="heading-enable-systemd-important">Enable systemd (Important)</h3>
<p>Zulip relies on system services like PostgreSQL, Redis, and RabbitMQ.</p>
<p>Edit the config file:</p>
<pre><code class="lang-bash">sudo nano /etc/wsl.conf
</code></pre>
<p>Add:</p>
<pre><code class="lang-ini"><span class="hljs-section">[boot]</span>
<span class="hljs-attr">systemd</span>=<span class="hljs-literal">true</span>
</code></pre>
<p>Restart WSL:</p>
<pre><code class="lang-bash">wsl --shutdown
</code></pre>
<h2 id="heading-install-required-services">Install Required Services</h2>
<p>Update your system:</p>
<pre><code class="lang-bash">sudo apt update &amp;&amp; sudo apt upgrade
</code></pre>
<p>Install required services:</p>
<pre><code class="lang-bash">sudo apt install rabbitmq-server memcached redis-server postgresql
</code></pre>
<h3 id="heading-configure-rabbitmq">Configure RabbitMQ</h3>
<p>Edit the config file:</p>
<pre><code class="lang-bash">sudo nano /etc/rabbitmq/rabbitmq-env.conf
</code></pre>
<p>Add:</p>
<pre><code class="lang-ini"><span class="hljs-attr">NODE_IP_ADDRESS</span>=<span class="hljs-number">127.0</span>.<span class="hljs-number">0.1</span>
<span class="hljs-attr">NODE_PORT</span>=<span class="hljs-number">5672</span>
</code></pre>
<h2 id="heading-important-wsl-tips">Important WSL Tips</h2>
<h3 id="heading-use-wsls-native-disk">Use WSL’s Native Disk</h3>
<p>Avoid working inside <code>/mnt/c/...</code>.</p>
<p>Always work from:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ~
</code></pre>
<h3 id="heading-generate-ssh-key-inside-wsl">Generate SSH Key Inside WSL</h3>
<pre><code class="lang-bash">ssh-keygen -t ed25519 -C <span class="hljs-string">"your_email@example.com"</span>
cat ~/.ssh/id_ed25519.pub
</code></pre>
<p>Add this key to GitHub as well.</p>
<h2 id="heading-cloning-the-zulip-repository">Cloning the Zulip Repository</h2>
<h3 id="heading-fork-zulip">Fork Zulip</h3>
<p>Go to:<br /><a target="_blank" href="https://github.com/zulip/zulip">https://github.com/zulip/zulip</a><br />Click <strong>Fork</strong>.</p>
<h3 id="heading-clone-your-fork">Clone Your Fork</h3>
<pre><code class="lang-bash">git <span class="hljs-built_in">clone</span> --config pull.rebase git@github.com:YOURUSERNAME/zulip.git
<span class="hljs-built_in">cd</span> zulip
git remote add -f upstream https://github.com/zulip/zulip.git
</code></pre>
<h2 id="heading-running-zulip-locally">Running Zulip Locally</h2>
<h3 id="heading-install-dependencies">Install Dependencies</h3>
<p>This step installs all required dependencies and may take 5–10 minutes.</p>
<pre><code class="lang-bash">./tools/provision
</code></pre>
<h3 id="heading-activate-the-virtual-environment">Activate the Virtual Environment</h3>
<pre><code class="lang-bash"><span class="hljs-built_in">source</span> .venv/bin/activate
</code></pre>
<h3 id="heading-start-the-development-server">Start the Development Server</h3>
<pre><code class="lang-bash">./tools/run-dev
</code></pre>
<p>Visit:<br /><a target="_blank" href="http://localhost:9991/">http://localhost:9991</a></p>
<h2 id="heading-common-zulip-setup-issues-and-fixes">Common Zulip Setup Issues (and Fixes)</h2>
<h3 id="heading-issue-1-missing-activatethispy">Issue 1: Missing <code>activate_this.py</code></h3>
<p><strong>Error</strong></p>
<pre><code class="lang-text">FileNotFoundError: No such file or directory ... activate_this.py
</code></pre>
<p><strong>Why This Happens</strong></p>
<p>Zulip now uses <strong>uv</strong>, a modern Python package manager.<br />Unlike <code>virtualenv</code>, it does not automatically create <code>activate_this.py</code>.</p>
<p>Some scripts still expect this file.</p>
<p><strong>Fix</strong></p>
<p>Manually create it:</p>
<pre><code class="lang-bash">cat &gt; .venv/bin/activate_this.py &lt;&lt; <span class="hljs-string">'EOF'</span>
import os
import site
import sys

bin_dir = os.path.dirname(os.path.abspath(__file__))
os.environ[<span class="hljs-string">"PATH"</span>] = os.pathsep.join([bin_dir] + os.environ.get(<span class="hljs-string">"PATH"</span>, <span class="hljs-string">""</span>).split(os.pathsep))

base = os.path.dirname(bin_dir)
os.environ[<span class="hljs-string">"VIRTUAL_ENV"</span>] = base

site_packages = os.path.join(base, <span class="hljs-string">'lib'</span>, <span class="hljs-string">'python{}.{}'</span>.format(*sys.version_info[:2]), <span class="hljs-string">'site-packages'</span>)

prev = <span class="hljs-built_in">set</span>(sys.path)
site.addsitedir(site_packages)
sys.real_prefix = sys.prefix
sys.prefix = base

new = list(sys.path)
sys.path[:] = [i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> new <span class="hljs-keyword">if</span> i not <span class="hljs-keyword">in</span> prev] + [i <span class="hljs-keyword">for</span> i <span class="hljs-keyword">in</span> new <span class="hljs-keyword">if</span> i <span class="hljs-keyword">in</span> prev]
EOF
</code></pre>
<h3 id="heading-issue-2-django-not-found-python-312">Issue 2: Django Not Found (Python 3.12)</h3>
<p><strong>Error</strong></p>
<pre><code class="lang-text">ModuleNotFoundError: No module named 'django'
</code></pre>
<p><strong>Root Cause</strong></p>
<p>Older scripts used:</p>
<pre><code class="lang-python">sys.version[:<span class="hljs-number">3</span>]
</code></pre>
<p>With Python 3.12, this incorrectly returns <code>"3.1"</code>.</p>
<p><strong>Fix</strong></p>
<p>Use:</p>
<pre><code class="lang-python"><span class="hljs-string">'{}.{}'</span>.format(*sys.version_info[:<span class="hljs-number">2</span>])
</code></pre>
<p>Then re-run:</p>
<pre><code class="lang-bash">./tools/provision
</code></pre>
<h2 id="heading-key-learnings-from-setting-up-zulip">Key Learnings from Setting Up Zulip</h2>
<h3 id="heading-technical-learnings">Technical Learnings</h3>
<ul>
<li><p>Modern tools like <strong>UV</strong> change long-standing Python assumptions</p>
</li>
<li><p>Understanding virtual environment internals is useful for debugging</p>
</li>
<li><p>A proper WSL2 + systemd setup is critical for backend services</p>
</li>
</ul>
<h3 id="heading-soft-learnings">Soft Learnings</h3>
<ul>
<li><p>Large codebases require patience</p>
</li>
<li><p>Error messages often point to the real issue</p>
</li>
<li><p>Zulip’s documentation and community are extremely helpful</p>
</li>
</ul>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Moving from Ghost to Zulip has been a rewarding step in my open-source journey.</p>
<p>Zulip’s development environment is complex but well-architected, making it a great project for anyone who wants to grow in <strong>backend engineering</strong>.</p>
<p>If you’re stuck on setup, especially around <code>activate_this.py</code> you’re not alone. Once the environment is running, contributing becomes much smoother.</p>
<h2 id="heading-resources">Resources</h2>
<ul>
<li><p>Zulip GitHub: <a target="_blank" href="https://github.com/zulip/zulip">https://github.com/zulip/zulip</a></p>
</li>
<li><p>Dev Setup Docs: <a target="_blank" href="https://zulip.readthedocs.io/en/latest/development/overview.html">https://zulip.readthedocs.io/en/latest/development/overview.html</a></p>
</li>
<li><p>Zulip Community: <a target="_blank" href="https://chat.zulip.org/">https://chat.zulip.org</a></p>
</li>
<li><p>WSL2 Docs: <a target="_blank" href="https://docs.microsoft.com/en-us/windows/wsl">https://docs.microsoft.com/en-us/windows/wsl</a></p>
</li>
<li><p>UV Package Manager: <a target="_blank" href="https://github.com/astral-sh/uv">https://github.com/astral-sh/uv</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Learning in Public for Career Advancement]]></title><description><![CDATA[Introduction
Recently, I watched a conversation between Kunal Kushwaha and Matt van Itallie about learning in public for career growth.
This discussion helped me understand what learning in public really means and why it is important in today’s tech ...]]></description><link>https://blog.abdultalha.tech/learning-in-public-for-career-advancement</link><guid isPermaLink="true">https://blog.abdultalha.tech/learning-in-public-for-career-advancement</guid><category><![CDATA[Learning Journey]]></category><category><![CDATA[learn in public]]></category><category><![CDATA[Career Growth]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 15 Dec 2025 06:26:57 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765779782153/0b24fc15-714b-4ea1-a2f8-8669c4579422.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>Recently, I watched a <a target="_blank" href="https://youtu.be/02J8HBInsJU?si=wSBeyWX6TFvEwmnr">conversation</a> between <strong>Kunal Kushwaha</strong> and <strong>Matt van Itallie</strong> about learning in public for career growth.</p>
<p>This discussion helped me understand what learning in public really means and why it is important in today’s tech careers.</p>
<p>Earlier, I thought learning was something we should do quietly. This video showed me that sharing learning openly can help not only individuals but also entire communities.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<ol>
<li><h3 id="heading-learning-in-public-means-sharing-progress"><strong>Learning in Public Means Sharing Progress</strong></h3>
</li>
</ol>
<p>Learning in public means sharing your questions, progress, and learnings openly.<br />It is not about showing expertise. It is about showing how you are learning step by step.</p>
<ol start="2">
<li><h3 id="heading-public-questions-help-more-people"><strong>Public Questions Help More People</strong></h3>
</li>
</ol>
<p>When you ask a question publicly, many people benefit from it.<br />Others who have the same question can learn from the answers and discussions.</p>
<ol start="3">
<li><h3 id="heading-psychological-safety-is-important"><strong>Psychological Safety Is Important</strong></h3>
</li>
</ol>
<p>In remote teams and online communities, people should feel safe to ask questions and admit mistakes.<br />There should be no fear of embarrassment.</p>
<p>If a community is rude to beginners, it is better to leave.<br />If a community supports beginners, it is a good place to learn and grow.</p>
<ol start="4">
<li><h3 id="heading-giving-feedback-the-right-way"><strong>Giving Feedback the Right Way</strong></h3>
</li>
</ol>
<p>Feedback should be clear, calm, and useful.<br />Instead of saying “Good job,” it is better to explain what was done well and why.</p>
<p>The same applies to negative feedback. It should clearly explain the issue and how to improve.</p>
<ol start="5">
<li><h3 id="heading-observe-before-giving-feedback"><strong>Observe Before Giving Feedback</strong></h3>
</li>
</ol>
<p>When joining a new community or team, it is good to observe first.<br />Watch how seniors and leaders communicate before sharing your own feedback.</p>
<ol start="6">
<li><h3 id="heading-choosing-the-right-community"><strong>Choosing the Right Community</strong></h3>
</li>
</ol>
<p>Very large communities can feel confusing.<br />Very small communities may not be active.</p>
<p>Medium-sized communities that welcome new members are often the best places to learn.</p>
<ol start="7">
<li><h3 id="heading-imposter-syndrome-is-normal"><strong>Imposter Syndrome Is Normal</strong></h3>
</li>
</ol>
<p>Many people feel imposter syndrome when they start.<br />No one begins as an expert. Skills and confidence grow with time and practice.</p>
<ol start="8">
<li><h3 id="heading-career-benefits-of-learning-in-public"><strong>Career Benefits of Learning in Public</strong></h3>
</li>
</ol>
<p>Learning in public helps build proof of work over time.<br />Your questions, posts, and contributions show your growth and help build credibility.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>My biggest takeaway from this video is that <strong>learning in public builds credibility over time, not by being perfect, but by being consistent</strong>.</p>
<p>You do not need to know everything before you start sharing.<br />Showing up regularly and learning openly matter more than trying to look perfect.</p>
<h2 id="heading-behind-the-scenes"><strong>Behind the Scenes</strong></h2>
<p>While watching this video, I wrote all my notes in my <strong>physical notebook</strong>, as I usually do.<br />Later, I converted those raw notes into this blog.</p>
<p>This process helps me:</p>
<ul>
<li><p>think clearly</p>
</li>
<li><p>remember concepts better</p>
</li>
<li><p>reflect on what I learned</p>
</li>
<li><p>track my progress over time</p>
</li>
</ul>
<p>This is an important part of my Learn in Public journey.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1765779688742/51d8a882-1ed4-4ef8-a695-3d31aa974775.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>Learning in public is not about showing off.<br />It is about learning, sharing, and growing together with the community.</p>
<p>This conversation reminded me that careers grow faster when we learn openly and support each other.</p>
]]></content:encoded></item><item><title><![CDATA[Does a Degree Decide Your Career in Tech?]]></title><description><![CDATA[Introduction
I recently watched a conversation between Kunal Kushwaha and Andy Jeffries, the CTO of Civo. The discussion focused on an important question many people struggle with:
Does having a degree really determine your success in tech?
As someon...]]></description><link>https://blog.abdultalha.tech/does-a-degree-decide-your-career-in-tech</link><guid isPermaLink="true">https://blog.abdultalha.tech/does-a-degree-decide-your-career-in-tech</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[technology]]></category><category><![CDATA[tech ]]></category><category><![CDATA[Technical writing ]]></category><category><![CDATA[#growth]]></category><category><![CDATA[learning]]></category><category><![CDATA[Learning Journey]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Programming Blogs]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 08 Dec 2025 16:27:26 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1765211129910/643ab21d-b810-4ca1-9e2f-913afec95bd8.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>I recently watched a <a target="_blank" href="https://www.youtube.com/watch?v=ktuTK08cigs&amp;t=278s">conversation</a> between <strong>Kunal Kushwaha</strong> and <strong>Andy Jeffries</strong>, the CTO of Civo. The discussion focused on an important question many people struggle with:</p>
<p><strong>Does having a degree really determine your success in tech?</strong></p>
<p>As someone who didn’t come from a traditional tech background, this topic felt very relevant. The conversation gave me a clearer understanding of how the tech industry looks at skills, education, and real-world ability.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<h3 id="heading-1-degree-vs-bootcampboth-have-value"><strong>1. Degree vs Bootcamp—Both Have Value</strong></h3>
<p>Andy explained that both degrees and bootcamps play different roles:</p>
<ul>
<li><p><strong>Bootcamps</strong> help people coming from non-tech backgrounds learn programming fundamentals quickly.</p>
</li>
<li><p><strong>Degrees</strong> provide a deeper understanding of computer science concepts, which can be helpful in certain roles.</p>
</li>
</ul>
<p>But the main point was:</p>
<blockquote>
<p><strong>A degree is useful, but your skills and real work matter more.</strong></p>
</blockquote>
<h3 id="heading-2-what-actually-matters-in-tech"><strong>2. What Actually Matters in Tech</strong></h3>
<p>Companies care less about your background and more about:</p>
<ul>
<li><p>What you can build</p>
</li>
<li><p>How do you solve problems</p>
</li>
<li><p>How you communicate</p>
</li>
<li><p>Your GitHub activity and open-source involvement</p>
</li>
</ul>
<p>If you can do the job well, your degree (or lack of it) becomes much less important.</p>
<h3 id="heading-3-what-companies-look-for-in-candidates"><strong>3. What Companies Look for in Candidates</strong></h3>
<p>Andy shared the qualities he looks for when hiring:</p>
<ul>
<li><p><strong>Self-motivation</strong></p>
</li>
<li><p><strong>Ability to figure things out when stuck</strong></p>
</li>
<li><p><strong>Clear and honest communication</strong></p>
</li>
<li><p><strong>How do you discuss issues and solutions publicly</strong></p>
</li>
</ul>
<p>These qualities show how you think and how you work—both are more important than your degree.</p>
<h3 id="heading-4-what-you-should-look-for-in-a-company"><strong>4. What You Should Look for in a Company</strong></h3>
<p>A good company should offer:</p>
<ul>
<li><p><strong>Growth opportunities</strong></p>
</li>
<li><p><strong>Impactful work</strong></p>
</li>
<li><p><strong>International exposure</strong></p>
</li>
</ul>
<p>Where you choose to work can shape your learning and career direction.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>This conversation made me reflect on my own journey.</p>
<p>I understood that:</p>
<ul>
<li><p>If you don’t have a degree, your <strong>work must speak for you</strong>.</p>
</li>
<li><p>A strong <strong>project portfolio</strong> or <strong>open-source profile</strong> creates more value than a certificate.</p>
</li>
<li><p>Tech changes quickly, so staying <strong>curious, consistent, and self-driven</strong> is essential.</p>
</li>
<li><p>The most important thing is your <strong>ability to learn and solve problems</strong>, not your educational background.</p>
</li>
</ul>
<p>This gives hope to anyone entering tech from a different field.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>A degree can help. A boot camp can help. But neither <em>defines</em> your future. Your skills, consistency, and problem-solving ability matter far more.</p>
<p>This conversation reminded me that tech is one of the few fields where <strong>your work speaks louder than your background</strong>. If you stay focused and keep improving, you can build a successful career, no matter where you started.</p>
]]></content:encoded></item><item><title><![CDATA[I Built a Modern Clinic Management System with React & TypeScript — Here's How]]></title><description><![CDATA[Introduction
I built DocBook – a full-featured clinic management system that streamlines healthcare operations for both patients and administrators. The platform offers real-time appointment booking, live queue management, and a comprehensive admin d...]]></description><link>https://blog.abdultalha.tech/i-built-a-modern-clinic-management-system-with-react-and-typescript-heres-how</link><guid isPermaLink="true">https://blog.abdultalha.tech/i-built-a-modern-clinic-management-system-with-react-and-typescript-heres-how</guid><category><![CDATA[clinic]]></category><category><![CDATA[React]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[full stack]]></category><category><![CDATA[vite]]></category><category><![CDATA[technology]]></category><category><![CDATA[Databases]]></category><category><![CDATA[admin]]></category><category><![CDATA[Testing]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 01 Dec 2025 13:54:12 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764597126868/99e5d011-17c7-466a-a358-97dfc0967c3b.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>I built <strong>DocBook</strong> – a full-featured clinic management system that streamlines healthcare operations for both patients and administrators. The platform offers real-time appointment booking, live queue management, and a comprehensive admin dashboard with emergency case handling.</p>
<p><strong>Role:</strong> Full-Stack Developer (solo)<br /><strong>Timeline:</strong> 2 weeks<br /><strong>Tech:</strong> React 18, TypeScript, Vite, TailwindCSS, shadcn/ui, TanStack Query<br /><strong>Live Demo:</strong> <a target="_blank" href="https://docbook.abdultalha.tech/">https://docbook.abdultalha.tech/</a><br /><strong>GitHub Repo:</strong> <a target="_blank" href="https://github.com/abdultalha0862/docbook">https://github.com/abdultalha0862/docbook</a></p>
<h2 id="heading-the-problem"><strong>The Problem</strong></h2>
<p>Managing clinic appointments is often chaotic:</p>
<ul>
<li><p>Patients wait endlessly without knowing their queue position</p>
</li>
<li><p>No real-time availability for booking slots</p>
</li>
<li><p>Administrators juggle multiple systems for appointments, patients, and emergencies</p>
</li>
<li><p>Emergency cases get lost in the regular queue</p>
</li>
<li><p>No unified dashboard for clinic metrics</p>
</li>
</ul>
<p>I wanted to build a solution that addresses these real healthcare challenges.</p>
<h2 id="heading-the-solution"><strong>The Solution</strong></h2>
<p>A modern clinic management platform with real-time queue tracking, instant booking, and separate portals for patients and administrators.</p>
<h2 id="heading-key-features"><strong>Key Features</strong></h2>
<h3 id="heading-for-patients"><strong>For Patients</strong></h3>
<ul>
<li><p><strong>Instant Slot Booking</strong> – Real-time availability with immediate confirmation</p>
</li>
<li><p><strong>Live Queue Tracking</strong> – Know your exact position with automatic updates</p>
</li>
<li><p><strong>Doctor Discovery</strong> – Browse specialists with ratings and experience</p>
</li>
<li><p><strong>Emergency Priority Booking</strong> – Special handling for urgent medical cases</p>
</li>
<li><p><strong>Appointment History</strong> – Track past and upcoming visits</p>
</li>
</ul>
<h3 id="heading-for-administrators"><strong>For Administrators</strong></h3>
<ul>
<li><p><strong>Real-Time Dashboard</strong> – Live metrics on appointments, doctors, and emergencies</p>
</li>
<li><p><strong>Queue Management</strong> – Control patient flow with status updates</p>
</li>
<li><p><strong>Patient Database</strong> – Comprehensive patient records</p>
</li>
<li><p><strong>Emergency Handling</strong> – Priority workflows for urgent cases</p>
</li>
<li><p><strong>Appointment Lifecycle Control</strong> – Approve, modify, or cancel appointments</p>
</li>
</ul>
<h2 id="heading-technical-architecture"><strong>Technical Architecture</strong></h2>
<h3 id="heading-frontend-stack"><strong>Frontend Stack</strong></h3>
<ul>
<li><p><strong>React 18 + TypeScript:</strong> Type-safe, modular components</p>
</li>
<li><p><strong>Vite:</strong> Lightning-fast development and build</p>
</li>
<li><p><strong>TailwindCSS:</strong> Rapid, responsive UI styling</p>
</li>
<li><p><strong>shadcn/ui + Radix UI:</strong> Accessible, modern component library</p>
</li>
<li><p><strong>TanStack Query:</strong> Efficient server state management</p>
</li>
</ul>
<h3 id="heading-key-engineering-decisions"><strong>Key Engineering Decisions</strong></h3>
<ul>
<li><p><strong>Component-Based Architecture:</strong> 13 core components + 40+ reusable UI components</p>
</li>
<li><p><strong>Custom Hooks Pattern:</strong> Separated data logic from UI (useAppointments, useDoctors, useDepartments)</p>
</li>
<li><p><strong>First-Come-First-Serve Queue System:</strong> Global counter ensures fair appointment ordering</p>
</li>
<li><p><strong>Optimistic Updates:</strong> Instant UI feedback with background sync</p>
</li>
<li><p><strong>Separate Portals:</strong> Distinct user experiences for patients and admins</p>
</li>
</ul>
<h2 id="heading-core-implementations"><strong>Core Implementations</strong></h2>
<h3 id="heading-queue-management-system"><strong>Queue Management System</strong></h3>
<ul>
<li><p>Global queue counter for fair appointment ordering</p>
</li>
<li><p>Real-time status updates (pending → confirmed → in-progress → completed)</p>
</li>
<li><p>Emergency flag for priority handling</p>
</li>
</ul>
<h3 id="heading-appointment-booking-flow"><strong>Appointment Booking Flow</strong></h3>
<ol>
<li><p>Patient authentication (sign in/sign up)</p>
</li>
<li><p>Doctor selection with speciality filtering</p>
</li>
<li><p>Real-time slot availability check</p>
</li>
<li><p>Information collection (symptoms, reason, emergency flag)</p>
</li>
<li><p>Queue number assignment with instant confirmation</p>
</li>
</ol>
<h3 id="heading-admin-dashboard"><strong>Admin Dashboard</strong></h3>
<ul>
<li><p>Live metrics cards showing today's appointments, pending approvals, active doctors, and emergency cases</p>
</li>
<li><p>Categorised appointment views (pending, in-progress, completed)</p>
</li>
<li><p>One-click status updates with toast notifications</p>
</li>
</ul>
<h3 id="heading-state-management"><strong>State Management</strong></h3>
<ul>
<li><p>TanStack Query for data fetching and caching</p>
</li>
<li><p>Query invalidation for real-time updates</p>
</li>
<li><p>Mutation hooks for optimistic updates</p>
</li>
</ul>
<h2 id="heading-testing"><strong>Testing</strong></h2>
<p>Developed a comprehensive test suite with Vitest + React Testing Library:</p>
<ul>
<li><p><strong>Component Tests:</strong> DoctorCard, AppointmentCard UI testing</p>
</li>
<li><p><strong>Hook Tests:</strong> useAppointments data logic validation</p>
</li>
<li><p><strong>Integration Tests:</strong> Full booking form workflow</p>
</li>
<li><p><strong>E2E Tests:</strong> Complete booking flow simulation</p>
</li>
<li><p><strong>Utility Tests:</strong> Mock data validation</p>
</li>
</ul>
<h2 id="heading-challenges-amp-solutions"><strong>Challenges &amp; Solutions</strong></h2>
<p>🔹 <strong>Real-time queue position updates</strong><br />Fix: Implemented query invalidation with TanStack Query for automatic data refresh on status changes.</p>
<p>🔹 <strong>Emergency case prioritisation</strong><br />Fix: Added <code>isEmergency</code> flag with visual indicators and separate admin view sections.</p>
<p>🔹 <strong>Managing complex appointment states</strong><br />Fix: Created typed status enum (pending, confirmed, in-progress, completed, cancelled) with strict state transitions.</p>
<p>🔹 <strong>Responsive admin dashboard</strong><br />Fix: Used CSS Grid with breakpoint-specific layouts (1-col mobile, 2-col tablet, 4-col desktop).</p>
<h2 id="heading-results"><strong>Results</strong></h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Metric</td><td>Outcome</td></tr>
</thead>
<tbody>
<tr>
<td>Core Components</td><td>13</td></tr>
<tr>
<td>UI Components</td><td>40+</td></tr>
<tr>
<td>Custom Hooks</td><td>6</td></tr>
<tr>
<td>Test Categories</td><td>5</td></tr>
<tr>
<td>Appointment States</td><td>5</td></tr>
<tr>
<td>User Portals</td><td>2 (Patient + Admin)</td></tr>
<tr>
<td>Page Load Time</td><td>&lt; 2s</td></tr>
<tr>
<td>Backend Required</td><td>None (demo mode)</td></tr>
</tbody>
</table>
</div><p>The platform provides a complete clinic management experience with minimal setup.</p>
<h2 id="heading-what-i-learned"><strong>What I Learned</strong></h2>
<ul>
<li><p><strong>TanStack Query</strong> simplifies complex data fetching and cache invalidation</p>
</li>
<li><p><strong>Separate portals</strong> improve UX by tailoring interfaces to user roles</p>
</li>
<li><p><strong>Emergency handling</strong> in healthcare apps requires careful visual hierarchy</p>
</li>
<li><p><strong>shadcn/ui + Radix</strong> accelerates development while maintaining accessibility</p>
</li>
<li><p><strong>Comprehensive testing</strong> is essential for healthcare applications where reliability matters</p>
</li>
</ul>
<h2 id="heading-future-enhancements"><strong>Future Enhancements</strong></h2>
<ul>
<li><p>Backend integration with real database (Supabase/PostgreSQL)</p>
</li>
<li><p>SMS/Email notifications for appointment reminders</p>
</li>
<li><p>Multi-doctor scheduling with time slot conflicts</p>
</li>
<li><p>Patient's medical history and records</p>
</li>
<li><p>Analytics dashboard with appointment trends</p>
</li>
<li><p>Payment gateway integration</p>
</li>
<li><p>Mobile app (React Native)</p>
</li>
</ul>
<h2 id="heading-call-to-action-cta"><strong>Call To Action (CTA)</strong></h2>
<p>If you want to:</p>
<ul>
<li><p>Build a modern healthcare or booking application like this</p>
</li>
<li><p>Collaborate on open-source projects</p>
</li>
<li><p>Hire me to create high-performance React applications</p>
</li>
</ul>
<p><strong>Let's connect!</strong></p>
<p>📧 Email: abdul@abdultalha.tech<br />🌐 Portfolio: <a target="_blank" href="https://abdultalha.tech/">https://abdultalha.tech/</a><br />💼 LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/abdul-talha/">https://www.linkedin.com/in/abdul-talha/</a><br />⭐ GitHub: <a target="_blank" href="https://github.com/abdultalha0862">https://github.com/abdultalha0862</a></p>
<p>If you found this project interesting,<br />⭐ <strong>Star the repository on GitHub,</strong> it genuinely helps!</p>
]]></content:encoded></item><item><title><![CDATA[From Open Source to Bloomberg London — Key Takeaways from Sanskar Jethi’s Journey]]></title><description><![CDATA[Introduction
Recently, I watched a conversation between Kunal Kushwaha and Sanskar Jethi about his journey from open source contributions to securing an off-campus role at Bloomberg London. The discussion was simple, honest, and packed with practical...]]></description><link>https://blog.abdultalha.tech/from-open-source-to-bloomberg-london-key-takeaways-from-sanskar-jethis-journey</link><guid isPermaLink="true">https://blog.abdultalha.tech/from-open-source-to-bloomberg-london-key-takeaways-from-sanskar-jethis-journey</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[kunalkushwaha]]></category><category><![CDATA[projects]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 01 Dec 2025 13:35:16 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1764596056802/0d412dd8-70a2-4119-80f6-463256fad701.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>Recently, I watched a conversation between <strong>Kunal Kushwaha</strong> and <strong>Sanskar Jethi</strong> about his journey from open source contributions to securing an off-campus role at <strong>Bloomberg London</strong>. The discussion was simple, honest, and packed with practical insights for developers like me who are growing through open source.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<h3 id="heading-1-open-source-is-collaboration-not-competition"><strong>1. Open Source Is Collaboration, Not Competition</strong></h3>
<p>Sanskar emphasised that open source is about working <em>together</em>.<br />There is no scoreboard, no race, and no rivalry.<br />It’s a collaborative space where developers from different backgrounds unite to solve problems and build something meaningful for the community.</p>
<h3 id="heading-2-impact-comes-from-projects-used-by-real-people"><strong>2. Impact Comes From Projects Used by Real People</strong></h3>
<p>The value of your work increases when it reaches real users.<br />Sanskar highlighted the importance of contributing to projects that people rely on globally.<br />Such projects not only sharpen your skills but also give you visible proof of real-world impact.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>This conversation helped me understand that open source is more than just code—it’s a mindset.<br />Focusing on collaboration, community, and meaningful contributions matters far more than competing for visibility.<br />This shift in perspective motivates me to contribute consistently and work on projects that help real users.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>Thanks to <strong>Kunal</strong> and <strong>Sanskar</strong> for sharing such actionable insights. Their conversation is a reminder that open source can open doors—not just to jobs, but to growth, learning, and impact.</p>
]]></content:encoded></item><item><title><![CDATA[GitHub Profile README Generator - A mini Case Study]]></title><description><![CDATA[Introduction
I built a fully client-side GitHub Profile README Generator to make it easy for developers to create beautiful GitHub profiles without manually writing markdown. The tool includes live preview, categorised skills, export options, and an ...]]></description><link>https://blog.abdultalha.tech/github-profile-readme-generator-a-mini-case-study</link><guid isPermaLink="true">https://blog.abdultalha.tech/github-profile-readme-generator-a-mini-case-study</guid><category><![CDATA[Web Development]]></category><category><![CDATA[webdev]]></category><category><![CDATA[WeMakeDevs]]></category><category><![CDATA[React]]></category><category><![CDATA[TypeScript]]></category><category><![CDATA[vite]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[README]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Sat, 22 Nov 2025 09:06:15 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763802246485/e8da8226-7ad2-4a7a-b27a-f00d151d4ef0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I built a <strong>fully client-side GitHub Profile README Generator</strong> to make it easy for developers to create beautiful GitHub profiles without manually writing markdown. The tool includes live preview, categorised skills, export options, and an intuitive form-based editor.</p>
<p><strong>Role:</strong> Full-Stack Developer (solo)<br /><strong>Timeline:</strong> 1 week<br /><strong>Tech:</strong> React 18, TypeScript, Vite, TailwindCSS, shadcn/ui<br /><strong>Live Demo:</strong> <a target="_blank" href="https://readmegen.abdultalha.tech/">https://readmegen.abdultalha.tech/</a><br /><strong>Github Repo:</strong> <a target="_blank" href="https://github.com/abdultalha0862/github-readme-generator">https://github.com/abdultalha0862/github-readme-generator</a></p>
<h2 id="heading-the-problem">The Problem</h2>
<p>Creating a standout GitHub profile is surprisingly tedious:</p>
<ul>
<li><p>Writing and formatting markdown manually</p>
</li>
<li><p>Finding icons and GitHub stats widgets</p>
</li>
<li><p>No instant preview</p>
</li>
<li><p>No structured way to organise skills or projects</p>
</li>
</ul>
<p>I wanted a tool that solves these real frustrations for developers.</p>
<h2 id="heading-the-solution">The Solution</h2>
<p>A <strong>visual GitHub Profile README Generator</strong> with real-time preview and multi-format export.</p>
<h3 id="heading-key-features">Key Features</h3>
<ul>
<li><p><strong>6 Content Sections:</strong> Basic info, Work, Skills (200+), Stats, Contact, Projects</p>
</li>
<li><p><strong>Live Markdown Preview:</strong> See changes instantly</p>
</li>
<li><p><strong>4 Export Formats:</strong> Markdown, HTML, PDF, Text</p>
</li>
<li><p><strong>Auto-Save:</strong> Saves progress every 3 seconds</p>
</li>
<li><p><strong>Skill Icon Library:</strong> 200+ technology icons across 10 categories</p>
</li>
</ul>
<h2 id="heading-technical-architecture">Technical Architecture</h2>
<h3 id="heading-frontend-stack">Frontend Stack</h3>
<ul>
<li><p><strong>React + TypeScript:</strong> Strong typing and modular components</p>
</li>
<li><p><strong>Vite:</strong> Lightning-fast dev environment</p>
</li>
<li><p><strong>shadcn/ui + Radix:</strong> Accessible, modern UI components</p>
</li>
<li><p><strong>TailwindCSS:</strong> Rapid UI styling</p>
</li>
</ul>
<h3 id="heading-key-engineering-decisions">Key Engineering Decisions</h3>
<ul>
<li><p>100% <strong>client-side</strong> (no backend or server costs)</p>
</li>
<li><p>LocalStorage persistence</p>
</li>
<li><p>Memoised preview for smooth performance</p>
</li>
<li><p>Export pipeline built for Markdown → HTML → PDF</p>
</li>
</ul>
<h2 id="heading-core-implementations">Core Implementations</h2>
<h3 id="heading-real-time-preview">Real-Time Preview</h3>
<p>Optimized with <code>useMemo</code>, <code>useCallback</code>, and controlled components.</p>
<h3 id="heading-skill-categorisation">Skill Categorisation</h3>
<p>200+ skills grouped into 10 categories with Devicons CDN for reliable icons.</p>
<h3 id="heading-export-system">Export System</h3>
<ul>
<li><p>Markdown generator</p>
</li>
<li><p>HTML template</p>
</li>
<li><p>PDF via jsPDF (HTML → PDF)</p>
</li>
<li><p>Clean TXT export</p>
</li>
</ul>
<h3 id="heading-auto-save">Auto-Save</h3>
<p>Saved every 3 seconds using LocalStorage with error handling.</p>
<h2 id="heading-testing">Testing</h2>
<p>Developed a robust test suite with <strong>Vitest + React Testing Library</strong>:</p>
<ul>
<li><p>Unit tests for generators</p>
</li>
<li><p>Component tests for forms and preview</p>
</li>
<li><p>Integration tests for the full edit → preview → export workflow</p>
</li>
</ul>
<h2 id="heading-challenges-amp-solutions">Challenges &amp; Solutions</h2>
<h3 id="heading-performance-with-large-content">🔹 Performance with large content</h3>
<p><strong>Fix:</strong> Memoisation + debouncing + component splitting.</p>
<h3 id="heading-pdf-formatting-issues">🔹 PDF formatting issues</h3>
<p><strong>Fix:</strong> Convert markdown → HTML → jsPDF to maintain structure.</p>
<h3 id="heading-icon-management-for-200-skills">🔹 Icon management for 200+ skills</h3>
<p><strong>Fix:</strong> Dynamic icon mapping with fallback URLs and caching.</p>
<h2 id="heading-results">Results</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Metric</td><td>Outcome</td></tr>
</thead>
<tbody>
<tr>
<td>Page load time</td><td><strong>&lt; 2s</strong></td></tr>
<tr>
<td>Supported skills</td><td><strong>200+</strong></td></tr>
<tr>
<td>Export options</td><td><strong>4 formats</strong></td></tr>
<tr>
<td>UI Components</td><td><strong>26</strong></td></tr>
<tr>
<td>Backend</td><td><strong>None</strong></td></tr>
</tbody>
</table>
</div><p>Users reported saving <strong>20–30 minutes</strong> compared to manual README creation.</p>
<h2 id="heading-what-i-learned">What I Learned</h2>
<ul>
<li><p>High-performance React apps require strategic memoisation</p>
</li>
<li><p>Tailwind + shadcn/ui accelerates UI development without losing control</p>
</li>
<li><p>File export pipelines require careful formatting</p>
</li>
<li><p>Tests are essential for confidently adding new features</p>
</li>
</ul>
<h2 id="heading-future-enhancements">Future Enhancements</h2>
<ul>
<li><p>One-click templates</p>
</li>
<li><p>Undo/redo</p>
</li>
<li><p>Import existing README</p>
</li>
<li><p>Advanced theming</p>
</li>
<li><p>AI-powered content suggestions</p>
</li>
<li><p>GitHub API integration for direct publishing</p>
</li>
</ul>
<h1 id="heading-call-to-action-cta">Call To Action (CTA)</h1>
<p>If you want to:</p>
<ul>
<li><p>build a modern React application like this,</p>
</li>
<li><p>collaborate on open-source developer tools,</p>
</li>
<li><p>or hire me to create high-performance front-end experiences…</p>
</li>
</ul>
<p><strong>Let’s connect!</strong></p>
<p><strong>📧 Email:</strong> <em>abdul@abdultalha.tech</em><br /><strong>🌐 Portfolio:</strong> <a target="_blank" href="https://abdultalha.tech/">https://abdultalha.tech/</a><br /><strong>💼 LinkedIn:</strong> <a target="_blank" href="https://www.linkedin.com/in/abdul-talha/">https://www.linkedin.com/in/abdul-talha/</a><br /><strong>⭐ GitHub:</strong> <a target="_blank" href="https://github.com/abdultalha0862">https://github.com/abdultalha0862</a></p>
<p>If you found this project interesting,<br /><strong>⭐ Star the repository on GitHub</strong> — it genuinely helps!</p>
]]></content:encoded></item><item><title><![CDATA[GSoC Conversation Between Kunal Kushwaha and Logan Kilpatrick]]></title><description><![CDATA[Introduction
As I continue exploring the world of open source and tech, I watched another helpful video, this time a discussion between Kunal Kushwaha and Logan Kilpatrick. I have been trying to understand open source more clearly, and this conversat...]]></description><link>https://blog.abdultalha.tech/gsoc-conversation-between-kunal-kushwaha-and-logan-kilpatrick</link><guid isPermaLink="true">https://blog.abdultalha.tech/gsoc-conversation-between-kunal-kushwaha-and-logan-kilpatrick</guid><category><![CDATA[kunalkushwaha]]></category><category><![CDATA[#logan]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[gsoc]]></category><category><![CDATA[contribution to open source]]></category><category><![CDATA[Collaboration]]></category><category><![CDATA[learning]]></category><category><![CDATA[Learning Journey]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Sat, 22 Nov 2025 04:18:18 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763784847710/490ee9d7-df27-4dd2-88df-25c7c2810df6.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>As I continue exploring the world of open source and tech, I watched another helpful <a target="_blank" href="https://youtu.be/BhaMF1lMgQI?si=Fkq66neN1w3hJMWo">video</a>, this time a discussion between Kunal Kushwaha and Logan Kilpatrick. I have been trying to understand open source more clearly, and this conversation gave me exactly the clarity I needed. They talked about GSoC (Google Summer of Code), how it works, and why it is such a great opportunity for learners and contributors. It felt like listening to two people sharing genuine insights from their own experience because Kunal cracked GSoC three times and Logan has mentored in GSOC.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<h3 id="heading-1-what-is-open-source"><strong>1. What is Open Source?</strong></h3>
<p>Open source simply means companies publicly share their code on GitHub. Anyone from anywhere in the world can look at the code and contribute to it. One point that really stayed with me is how contributions build your proof of work on GitHub. Everything you do stays on your profile, showing your journey and skills.</p>
<h3 id="heading-2-what-is-gsoc"><strong>2. What is GSoC?</strong></h3>
<p>GSoC is a platform where organisations, mentors and students work together. It is not just a program, but a place where beginners get guidance while contributing to real projects. This explanation made GSoC feel more accessible and welcoming.</p>
<h3 id="heading-3-gsoc-timeline"><strong>3. GSoC Timeline</strong></h3>
<p>I learned that the GSoC timeline can change each year. Because of this, it is important to keep checking the official website for updated dates and announcements.</p>
<h3 id="heading-4-tips-to-start-contributing"><strong>4. Tips to Start Contributing</strong></h3>
<p>They shared some very practical tips that made the process feel less overwhelming:</p>
<ul>
<li><p>Check if your chosen organisation is participating in GSoC.</p>
</li>
<li><p>Explore their projects and documentation.</p>
</li>
<li><p>Go through the codebase to understand how things work.</p>
</li>
<li><p>Start with good first issues and then move on to more complex issues.</p>
</li>
</ul>
<p>This advice felt simple and realistic, especially for someone just starting.</p>
<h3 id="heading-5-importance-of-collaboration"><strong>5. Importance of Collaboration</strong></h3>
<p>One thing they highlighted strongly is that GSoC is not a competition. It is a collaborative environment where developers from different parts of the world work together. This idea of learning and contributing as a team is one of the core values of open source.</p>
<h3 id="heading-6-tips-for-proposal"><strong>6. Tips for Proposal</strong></h3>
<p>If you have even a few contributions to open source, it already gives you a big advantage.<br />Your proposal should clearly explain why you are interested in that particular project and why you believe you are a good fit for the organisation.</p>
<h3 id="heading-7-if-you-dont-get-selected"><strong>7. If You Don’t Get Selected</strong></h3>
<p>GSoC has limited slots, so not everyone gets selected. But your contributions still stay on your GitHub profile. And if you keep contributing until next year, your chances of getting selected increase a lot. This part was very encouraging and reminded me that the effort itself is valuable.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>After watching the video, I felt like I had a clear understanding of the entire GSoC process. I understood what open source really means, why the timeline matters and how contributions can help build a strong profile. The biggest takeaway for me was that collaboration is more important than competition. Even if I don’t get selected, the contributions I make will remain on my GitHub profile and continue to represent my work.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>This conversation between Kunal Kushwaha and Logan Kilpatrick helped me see GSoC as more than just a program. It is a journey of learning, contributing and collaborating with the community. Watching this video motivated me to explore more, contribute more and continue growing in the open source world.</p>
]]></content:encoded></item><item><title><![CDATA[DevOps Journey & Getting Remote Jobs Through Open Source]]></title><description><![CDATA[Introduction
Recently, I watched a conversation between Kunal Kushwaha and Alex about DevOps, open source, and how people land remote jobs through their contributions. I documented everything in my physical notebook first and later converted it into ...]]></description><link>https://blog.abdultalha.tech/devops-journey-and-getting-remote-jobs-through-open-source</link><guid isPermaLink="true">https://blog.abdultalha.tech/devops-journey-and-getting-remote-jobs-through-open-source</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[Devops]]></category><category><![CDATA[learning]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[#learning-in-public]]></category><category><![CDATA[community]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Sun, 16 Nov 2025 16:08:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763309194993/50e3fbb1-b6bf-4bf2-9b06-5bb9ffbd4302.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>Recently, I watched a <a target="_blank" href="https://www.youtube.com/watch?v=M2V1xXCl8pw">conversation</a> between <strong>Kunal Kushwaha and Alex</strong> about DevOps, open source, and how people land remote jobs through their contributions. I documented everything in my physical notebook first and later converted it into this blog. This discussion gave me clarity on the role of open source, communities, learning styles, and the structure behind real-world contributions.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<h3 id="heading-1-how-open-source-helps"><strong>1. How Open Source Helps</strong></h3>
<p>Open source isn’t just about sending pull requests; it’s a way to <strong>showcase real proof of work</strong>.<br />By maintaining repositories, writing clear READMEs, and contributing consistently, anyone (including a hiring manager) can see:</p>
<ul>
<li><p>your thought process</p>
</li>
<li><p>the quality of your work</p>
</li>
<li><p>The impact of your contributions</p>
</li>
</ul>
<p>Open source becomes a living portfolio. Instead of telling people what you know, you <strong>show</strong> them.</p>
<h3 id="heading-2-how-to-learn-anything-new"><strong>2. How to Learn Anything New</strong></h3>
<p>Everyone has their own learning style, videos, blogs, docs, building, or hands-on experimenting.<br />The important part is:</p>
<ul>
<li><p><strong>start small</strong></p>
</li>
<li><p>try things on your own</p>
</li>
<li><p>document what you learn</p>
</li>
<li><p>avoid getting stuck in endless tutorials</p>
</li>
</ul>
<p>Hands-on practice + project-based learning always works better than passively consuming content.</p>
<h3 id="heading-3-downsides-of-open-source"><strong>3. Downsides of Open Source</strong></h3>
<p>Open source is powerful, but it also has challenges:</p>
<ul>
<li><p>Maintainers receive huge numbers of PRs and must push hard to review them.</p>
</li>
<li><p>There is a <strong>strict structure</strong> behind contributing, reviewing, and merging code.</p>
</li>
<li><p>Beginners often underestimate the workflow and feel discouraged when PRs are rejected.</p>
</li>
</ul>
<p>But these challenges are part of the learning curve, and they teach how real engineering teams work.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>This video reminded me of the importance of communities. As a full-stack developer, I realised I need to <strong>find and actively engage with communities</strong> related to my field. Participation brings clarity—once you show up, you slowly understand how things work.</p>
<p>I also learned the value of maintaining a proper README or learning file. When I document my learning clearly, it shows my thinking, progress, and structure something that matters to both open-source maintainers and recruiters.</p>
<h2 id="heading-behind-the-scenes-my-raw-notes"><strong>Behind the Scenes: My Raw Notes</strong></h2>
<p>Before writing this blog, I captured everything in my physical notebook while watching the video.<br />Converting raw handwritten thoughts into structured content helps me:</p>
<ul>
<li><p>remember concepts better</p>
</li>
<li><p>reflect deeply</p>
</li>
<li><p>write with clarity</p>
</li>
<li><p>avoid losing ideas</p>
</li>
</ul>
<p>This “raw first, polish later” process makes my learning more intentional and helps me stay consistent.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>This conversation helped me understand that open source is not only about contributing code, but it is also a pathway to remote work, community building, structured learning, and showcasing your real abilities.</p>
<p>It taught me to stay consistent, document my growth, and be active in communities that align with my goals. The journey is long, but with the right process, it becomes meaningful.</p>
]]></content:encoded></item><item><title><![CDATA[From 4 Hours to 20 Seconds: Saving 16+ Hours/Week with a Python Resume Parser]]></title><description><![CDATA[Introduction:
In today's job market, recruiters are drowning in resumes. A recent freelance client was spending 16+ hours every week on a single manual task: sifting through 500+ resumes. The process was slow, error-prone, and a massive bottleneck.
T...]]></description><link>https://blog.abdultalha.tech/from-4-hours-to-20-seconds-saving-16-hoursweek-with-a-python-resume-parser</link><guid isPermaLink="true">https://blog.abdultalha.tech/from-4-hours-to-20-seconds-saving-16-hoursweek-with-a-python-resume-parser</guid><category><![CDATA[Python]]></category><category><![CDATA[automation]]></category><category><![CDATA[Case Study]]></category><category><![CDATA[AI]]></category><category><![CDATA[multiprocessing]]></category><category><![CDATA[Developer]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Thu, 13 Nov 2025 15:24:40 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1763047132845/bac57e02-3628-4585-9517-bd4cc6c39145.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction:</strong></h2>
<p>In today's job market, recruiters are drowning in resumes. A recent freelance client was spending 16+ hours every week on a single manual task: sifting through 500+ resumes. The process was slow, error-prone, and a massive bottleneck.</p>
<p>To solve this, I built a high-performance parsing solution that transformed their workflow. By leveraging Python's <code>multiprocessing</code> library, I built a tool that cut a <strong>4-hour task down to 20 seconds.</strong></p>
<p>This post is a technical deep-dive into how I built it, the challenges of real-world file parsing, and the lessons I learned.</p>
<h2 id="heading-the-challenge">The Challenge</h2>
<p>The client needed a system that could:</p>
<ul>
<li><p>Process large volumes of resumes in multiple formats (PDF, DOC, DOCX)</p>
</li>
<li><p>Extract and analyse text content efficiently</p>
</li>
<li><p>Score resumes based on relevant keywords</p>
</li>
<li><p>Identify top candidates quickly</p>
</li>
<li><p>Handle the workload with optimal performance</p>
</li>
</ul>
<h2 id="heading-technical-architecture">Technical Architecture</h2>
<h3 id="heading-technology-stack">Technology Stack</h3>
<p>I chose Python for this project due to its robust ecosystem of libraries:</p>
<ul>
<li><p><strong>PyPDF2</strong>: For extracting text from PDF files</p>
</li>
<li><p><strong>python-docx</strong>: For processing Word documents</p>
</li>
<li><p><strong>Multiprocessing</strong>: To leverage multiple CPU cores for parallel processing</p>
</li>
</ul>
<h3 id="heading-core-components">Core Components</h3>
<p>The solution consists of three main functional components:</p>
<h4 id="heading-1-text-extraction-engine">1. Text Extraction Engine</h4>
<p>The system handles two primary document formats:</p>
<p>Python</p>
<pre><code class="lang-bash"><span class="hljs-comment"># PDF extraction</span>
def extract_text_from_pdf(pdf_path):
    pass

<span class="hljs-comment"># DOCX extraction  </span>
def extract_text_from_docx(docx_path):
    pass
</code></pre>
<p>Each extractor includes comprehensive error handling to ensure the system doesn't crash when encountering corrupted or malformed files.</p>
<h4 id="heading-2-keyword-matching-algorithm">2. Keyword Matching Algorithm</h4>
<p>The scoring system evaluates resumes based on the presence and frequency of required keywords:</p>
<ul>
<li><p>Case-insensitive matching for flexibility</p>
</li>
<li><p>Frequency counting for better ranking</p>
</li>
<li><p>Detailed reporting of matched terms</p>
</li>
<li><p>Configurable keyword lists for different job roles</p>
</li>
</ul>
<h4 id="heading-3-parallel-processing-pipeline">3. Parallel Processing Pipeline</h4>
<p>The most critical performance feature is the parallel processing implementation:</p>
<p>Python</p>
<pre><code class="lang-bash">from multiprocessing import Pool


with Pool() as pool:
    results = pool.starmap(process_resume, [(resume_file, keywords) 
                                           <span class="hljs-keyword">for</span> resume_file <span class="hljs-keyword">in</span> resume_files])
</code></pre>
<p>This approach distributes resume processing across multiple CPU cores, dramatically reducing processing time.</p>
<h2 id="heading-key-features">Key Features</h2>
<h3 id="heading-1-multi-format-support">1. <strong>Multi-Format Support</strong></h3>
<p>The system seamlessly handles PDF, DOC, and DOCX files, ensuring compatibility with the most common resume formats.</p>
<h3 id="heading-2-intelligent-scoring">2. <strong>Intelligent Scoring</strong></h3>
<p>Resumes are scored based on both the presence and frequency of keywords, providing a nuanced ranking system.</p>
<h3 id="heading-3-top-candidate-identification">3. <strong>Top Candidate Identification</strong></h3>
<p>The system automatically identifies and presents the top 5 candidates, streamlining the initial screening process.</p>
<h3 id="heading-4-performance-optimisation">4. <strong>Performance Optimisation</strong></h3>
<p>By leveraging multiprocessing, the system can process hundreds of resumes in seconds rather than minutes.</p>
<h3 id="heading-5-detailed-match-reporting">5. <strong>Detailed Match Reporting</strong></h3>
<p>For each top candidate, the system shows exactly which keywords were matched and how many times, providing transparency in the ranking process.</p>
<h2 id="heading-challenges-and-solutions">Challenges and Solutions</h2>
<h3 id="heading-challenge-1-handling-various-document-formats">Challenge 1: Handling Various Document Formats</h3>
<p><strong>Problem</strong>: Resumes come in different formats with varying structures and encoding.</p>
<p><strong>Solution</strong>: Implemented separate extraction functions for each format with robust error handling. Files that can't be processed are skipped gracefully without disrupting the entire workflow.</p>
<h3 id="heading-challenge-2-performance-with-large-resume-batches">Challenge 2: Performance with Large Resume Batches</h3>
<p><strong>Problem</strong>: Sequential processing of hundreds of resumes was too slow for practical use.</p>
<p><strong>Solution</strong>: Implemented Python's multiprocessing Pool to distribute workload across CPU cores. This resulted in approximately <strong>3-4x performance improvement</strong> on a quad-core system.</p>
<h3 id="heading-challenge-3-accurate-keyword-matching">Challenge 3: Accurate Keyword Matching</h3>
<p><strong>Problem</strong>: Keyword matching needed to be flexible enough to catch variations but precise enough to avoid false positives.</p>
<p><strong>Solution</strong>: Used case-insensitive matching and counted keyword frequency to provide a more nuanced scoring system.</p>
<h2 id="heading-performance-metrics">Performance Metrics</h2>
<p>The system demonstrates impressive performance characteristics:</p>
<ul>
<li><p><strong>Processing Speed</strong>: Handles 100+ resumes in under 10 seconds (depending on hardware)</p>
</li>
<li><p><strong>Accuracy</strong>: Case-insensitive matching ensures relevant candidates aren't missed</p>
</li>
<li><p><strong>Scalability</strong>: Linear scalability with additional CPU cores</p>
</li>
<li><p><strong>Reliability</strong>: Error handling ensures individual file failures don't crash the system</p>
</li>
</ul>
<h2 id="heading-lessons-learned">Lessons Learned</h2>
<h3 id="heading-1-multiprocessing-is-powerful-but-requires-care">1. Multiprocessing is Powerful but Requires Care</h3>
<p>While multiprocessing significantly improved performance, it required careful consideration of:</p>
<ul>
<li><p>Picklable objects (what can be passed between processes)</p>
</li>
<li><p>Resource management (proper pool cleanup)</p>
</li>
<li><p>Error propagation between processes</p>
</li>
</ul>
<h3 id="heading-2-real-world-resume-parsing-is-messy">2. Real-World Resume Parsing is Messy</h3>
<p>Unlike clean test data, real resumes have:</p>
<ul>
<li><p>Inconsistent formatting</p>
</li>
<li><p>Various encoding schemes</p>
</li>
<li><p>Occasional corruption</p>
</li>
<li><p>Complex layouts with tables and graphics</p>
</li>
</ul>
<p>Robust error handling is essential.</p>
<h3 id="heading-3-simple-solutions-can-be-effective">3. Simple Solutions Can Be Effective</h3>
<p>While advanced NLP techniques exist, a well-implemented keyword matching system proved sufficient for the client's needs. Don't over-engineer when simpler solutions work.</p>
<h2 id="heading-potential-enhancements">Potential Enhancements</h2>
<p>While the current system meets the client's requirements, here are some potential future improvements:</p>
<ol>
<li><p><strong>Machine Learning Integration</strong>: Implement ML models for semantic matching beyond simple keywords</p>
</li>
<li><p><strong>Skills Extraction</strong>: Automatically identify and categorise skills, experience levels, and qualifications</p>
</li>
<li><p><strong>Web Interface</strong>: Add a user-friendly GUI for non-technical users</p>
</li>
<li><p><strong>Database Integration</strong>: Store results for historical analysis and tracking</p>
</li>
<li><p><strong>Custom Weighting</strong>: Allow different keywords to have different importance levels</p>
</li>
<li><p><strong>Fuzzy Matching</strong>: Handle typos and variations in keyword spelling</p>
</li>
</ol>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This project demonstrates how Python's ecosystem and multiprocessing capabilities can create practical, high-performance solutions for real-world business challenges. By focusing on clean code, proper error handling, and performance optimisation, we delivered a tool that significantly improves the resume screening process.</p>
<p>The key takeaway? Sometimes the best solution isn't the most complex one. By leveraging the right tools (PyPDF2, python-docx, multiprocessing) and focusing on the actual requirements, we created an effective system that saves hours of manual work.</p>
<h2 id="heading-technical-specifications">Technical Specifications</h2>
<ul>
<li><p><strong>Language</strong>: Python 3.9</p>
</li>
<li><p><strong>Dependencies</strong>: PyPDF2, python-docx</p>
</li>
<li><p><strong>Architecture</strong>: Parallel processing with multiprocessing Pool</p>
</li>
<li><p><strong>Supported Formats</strong>: PDF, DOC, DOCX</p>
</li>
<li><p><strong>Performance</strong>: O(n/c) where n = number of resumes, c = number of CPU cores</p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[How Open Source Can Unlock Freelancing Opportunities]]></title><description><![CDATA[Introduction
I recently watched a conversation between Kunal Kushwaha and Eddie Jaoude titled “Travel the World While Freelancing.”
It completely changed how I view freelancing and open source. I used to think of open source mainly as a way to learn ...]]></description><link>https://blog.abdultalha.tech/how-open-source-can-unlock-freelancing-opportunities</link><guid isPermaLink="true">https://blog.abdultalha.tech/how-open-source-can-unlock-freelancing-opportunities</guid><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[Freelancing]]></category><category><![CDATA[kunalkushwaha]]></category><category><![CDATA[EddieHub]]></category><category><![CDATA[learning]]></category><category><![CDATA[learn in public]]></category><category><![CDATA[Build In Public]]></category><category><![CDATA[ghost]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Mon, 10 Nov 2025 17:44:44 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762796584170/1b4665f5-7171-49b1-a220-8faa1b4820d0.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>I recently watched a conversation between <strong>Kunal Kushwaha</strong> and <strong>Eddie Jaoude</strong> titled <em>“</em><a target="_blank" href="https://www.youtube.com/watch?v=IHGvLd0JWpQ&amp;t=6s&amp;pp=ygUidHJhdmVsIHRoZSB3b3JsZCB3aGlsZSBmcmVlbGFuZGluZw%3D%3D"><em>Travel the World While Freelancing.</em></a><em>”</em></p>
<p>It completely changed how I view freelancing and open source. I used to think of open source mainly as a way to learn and collaborate, but now I see it as a gateway to real-world opportunities and proof of work that clients can trust.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<ol>
<li><p><strong>Start freelancing through open source.</strong><br /> It’s the best way to showcase your skills and demonstrate your ability to solve real problems, something clients value highly.</p>
</li>
<li><p><strong>Freelancing vs full-time jobs.</strong><br /> Both have pros and cons. Freelancing offers flexibility, but sometimes you might have no clients, so having a backup option helps.</p>
</li>
<li><p><strong>Build in public.</strong><br /> Sharing what you learn, create, or struggle with attracts visibility and builds trust in your work.</p>
</li>
<li><p><strong>Experiment with both paths.</strong><br /> Try freelancing and full-time work to see which aligns best with your goals and lifestyle.</p>
</li>
</ol>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>As an <strong>open-source contributor at Ghost</strong>, I have seen firsthand how contributing to projects helps build credibility. Clients and companies see open-source work as real proof that you can deliver.</p>
<p>I realised that open source not only opens doors for <strong>job opportunities</strong> but also for <strong>freelancing gigs</strong>. By consistently contributing, I am not just learning, I am also building a track record of practical experience that speaks for itself.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>This conversation reminded me that success doesn’t come from choosing one path; it comes from exploring both. I plan to experiment with <strong>freelancing</strong> and <strong>full-time roles</strong> to find what fits me best.</p>
<p>A huge thanks to <strong>Kunal Kushwaha</strong> and <strong>Eddie Jaoude</strong> for sharing these valuable insights.</p>
]]></content:encoded></item><item><title><![CDATA[Fixing Email Preview Scrollbar Accessibility in Ghost CMS (25304)]]></title><description><![CDATA[Introduction
Contributing to Ghost CMS has been a great learning experience for me. I started with small fixes, and now I have a better understanding of how good design and accessibility improve user experiences.
So far, I have solved three issues: #...]]></description><link>https://blog.abdultalha.tech/fixing-email-preview-scrollbar-accessibility-in-ghost-cms-25304</link><guid isPermaLink="true">https://blog.abdultalha.tech/fixing-email-preview-scrollbar-accessibility-in-ghost-cms-25304</guid><category><![CDATA[ghost]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[Accessibility]]></category><category><![CDATA[ghostcms]]></category><category><![CDATA[admin]]></category><category><![CDATA[scrollbar]]></category><category><![CDATA[Ember.js]]></category><category><![CDATA[ember]]></category><category><![CDATA[GitHub]]></category><category><![CDATA[Git]]></category><category><![CDATA[navigation]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Wed, 05 Nov 2025 14:06:34 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1762351403969/a59e6835-ec32-43ac-8ba4-d851850a7b54.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>Contributing to Ghost CMS has been a great learning experience for me. I started with small fixes, and now I have a better understanding of how good design and accessibility improve user experiences.</p>
<p>So far, I have solved three issues: #25050, #24608, and #24706. Each one has taught me more about Ghost’s Ember.js frontend, user interface consistency, and working in open-source projects.</p>
<p>In my fourth contribution, #25304, I addressed an important accessibility issue in the email preview. What appeared to be a simple scrollbar bug turned out to be a practical lesson in focus management, keyboard navigation, and inclusive design.</p>
<h2 id="heading-understanding-the-problem">Understanding the Problem</h2>
<p>When I first looked at issue <a target="_blank" href="https://github.com/TryGhost/Ghost/issues/25304">#25304</a>, it seemed simple: the email preview in Ghost’s post editor didn’t show a visible scrollbar.<br />But as I investigated further, I realised this was more than a visual problem; it was an accessibility issue. Without a scrollbar, users who depend on keyboard navigation or two-button mice couldn't scroll through long email previews.</p>
<p>I tested the issue locally and confirmed that:</p>
<ul>
<li><p>The CSS was hiding the scrollbar.</p>
</li>
<li><p>The iframe couldn’t be focused using the keyboard.</p>
</li>
<li><p>Arrow keys, Page Up/Down, and Tab navigation didn’t work.</p>
</li>
</ul>
<p>This was a small UX gap but had a big impact, especially for users who depend on accessible navigation.</p>
<p>So, I decided to review the email preview component in the Ember.js admin frontend to find out why this was happening and how to fix it.</p>
<h2 id="heading-my-thought-process">My Thought Process</h2>
<p>I started by learning how the email preview works. Since Ghost’s admin panel uses Ember.js, I found the component that shows the preview modal.</p>
<p>I searched the code and located the relevant files at:</p>
<ul>
<li><p>ghost/admin/app/components/editor/modals/preview/email.js</p>
</li>
<li><p>ghost/admin/app/components/editor/modals/preview/email.hbs</p>
</li>
</ul>
<p>Next, I used the browser’s DevTools to check the iframe. I noticed something important: the scrollbar was hidden by CSS:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">html</span><span class="hljs-selector-pseudo">::-webkit-scrollbar</span> {
    <span class="hljs-attribute">display</span>: none;
}
<span class="hljs-selector-tag">html</span> {
    <span class="hljs-attribute">scrollbar-width</span>: none;
}
</code></pre>
<p>This explained why the scrollbar was not visible. However, there was more to the problem: even when using a mouse wheel, the iframe could not be focused, which meant keyboard users couldn’t scroll at all.</p>
<p>I had a clear conclusion: The issue was not just about styling; it was also about focus management and accessibility.</p>
<p>I decided to fix the problem in three steps:</p>
<ol>
<li><p>Allow scrollbars to show again.</p>
</li>
<li><p>Make the iframe keyboard-focusable.</p>
</li>
<li><p>Manage focus properly when users tab into the preview area.</p>
</li>
</ol>
<p>This plan gave me a clear direction; a small UI change could greatly improve accessibility and usability.</p>
<h2 id="heading-the-fix">The Fix</h2>
<p>I focused on improving the email preview to make it easier to use and accessible. I made three key changes that had a big impact.</p>
<h3 id="heading-1-make-scrollbars-visible-again">1. Make Scrollbars Visible Again</h3>
<p>The original code hides the scrollbar completely. I changed it so the scrollbar shows when there is too much content for the screen:</p>
<pre><code class="lang-css"><span class="hljs-selector-tag">const</span> <span class="hljs-selector-tag">INJECTED_CSS</span> = `
<span class="hljs-selector-tag">html</span>,
<span class="hljs-selector-tag">body</span> {
    <span class="hljs-attribute">overflow-y</span>: auto;
}
`;
</code></pre>
<p>Now, users can see the scrollbar whenever needed, making it clear that they can scroll.</p>
<h3 id="heading-2-make-the-iframe-keyboard-focusable">2. Make the Iframe Keyboard-Focusable</h3>
<p>Next, I ensured users can navigate to the iframe using the keyboard by adding a tabindex:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">iframe</span>
    <span class="hljs-attr">class</span>=<span class="hljs-string">"gh-pe-iframe"</span>
    <span class="hljs-attr">title</span>=<span class="hljs-string">"Email preview"</span>
    <span class="hljs-attr">tabindex</span>=<span class="hljs-string">"0"</span>
    <span class="hljs-attr">sandbox</span>=<span class="hljs-string">"allow-same-origin allow-popups allow-popups-to-escape-sandbox"</span>
    {{<span class="hljs-attr">did-insert</span> <span class="hljs-attr">this.renderEmailPreview</span>}}
    {{<span class="hljs-attr">did-update</span> <span class="hljs-attr">this.renderEmailPreview</span> @<span class="hljs-attr">memberSegment</span>}}
    {{<span class="hljs-attr">on</span> "<span class="hljs-attr">focusin</span>" <span class="hljs-attr">this.focusPreviewFrame</span>}}
&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">iframe</span>&gt;</span>
</code></pre>
<p>This change allows users to tab into the preview and use the arrow keys or Page Up/Down to scroll.</p>
<h3 id="heading-3-manage-focus-inside-the-iframe">3. Manage Focus Inside the Iframe</h3>
<p>Finally, I ensured the iframe’s body could receive focus, not just the iframe itself. This is where keyboard navigation works best.</p>
<pre><code class="lang-javascript">@action
focusPreviewFrame(event) {
    <span class="hljs-keyword">const</span> iframe = event?.target;
    <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">const</span> body = iframe.contentDocument?.body;
        <span class="hljs-keyword">if</span> (body &amp;&amp; !body.hasAttribute(<span class="hljs-string">'tabindex'</span>)) {
            body.setAttribute(<span class="hljs-string">'tabindex'</span>, <span class="hljs-string">'-1'</span>);
        }
        body?.focus({<span class="hljs-attr">preventScroll</span>: <span class="hljs-literal">true</span>});
    } <span class="hljs-keyword">catch</span> {
        iframe.contentWindow?.focus();
    }
}
</code></pre>
<p>This change allowed keyboard events to be handled correctly and scrolling to work smoothly.</p>
<p>After making these changes, the email preview modal is now fully scrollable, accessible with a keyboard, and easy to see. This small fix made Ghost’s editor more inclusive and enjoyable to use.</p>
<h2 id="heading-testing-and-verification">Testing and Verification</h2>
<p>After making the fix, I wanted to ensure it improved the experience in real use. I ran Ghost in development mode and launched the email preview. This time, I quickly noticed the difference:</p>
<p>✅ The scrollbar appeared when needed.<br />✅ I could focus on the iframe using the Tab key.<br />✅ The arrow keys, Page Up/Down, and Space/Shift+Space scrolled smoothly.<br />✅ The mouse wheel and scrollbar dragging worked perfectly.</p>
<p>To prevent any future issues, I added a test that checks if the iframe has <code>tabindex="0"</code> and that its body gets focus correctly. This way, upcoming updates won’t undo the accessibility fix.</p>
<p>All tests passed, and the UI worked consistently across different browsers.</p>
<p>This testing reminded me how important it is to check real behaviour, not just the code. Accessibility fixes matter when they help someone use the product more comfortably.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762231521475/1f5b1722-1a4f-483b-b30c-2e377a4c7a02.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-submitting-the-pull-request">Submitting the Pull Request</h2>
<p>After confirming that the fix worked and all tests passed, I submitted a pull request to Ghost’s main branch: <a target="_blank" href="https://github.com/TryGhost/Ghost/pull/25334">Pull Request #<strong>25334</strong></a></p>
<p>The pull request included:</p>
<ul>
<li><p>Visible scrollbars in the email preview.</p>
</li>
<li><p>Added <code>tabindex="0"</code> to the iframe for keyboard access.</p>
</li>
<li><p>A focus handler to ensure the iframe body receives focus.</p>
</li>
<li><p>An acceptance test to prevent future issues.</p>
</li>
</ul>
<h2 id="heading-impact-and-lessons-learned">Impact and Lessons Learned</h2>
<p>This contribution showed me that even small improvements in accessibility can make a big difference. By fixing the email preview scrollbar and improving keyboard navigation:</p>
<ul>
<li><p>Keyboard-only users can navigate and scroll email previews easily.</p>
</li>
<li><p>Mouse users can drag scrollbars instead of just using the wheel.</p>
</li>
<li><p>All users benefit from a clearer and more predictable interface.</p>
</li>
</ul>
<p>Working on this issue also reinforced the importance of patience, attention to detail, and clear communication in open-source projects. Accessibility isn’t just a feature; it’s about making software usable for everyone.</p>
<p>Contributing to Ghost has been a rewarding experience. I look forward to making the platform more inclusive and user-friendly.</p>
<h2 id="heading-after-screenshot">After Screenshot</h2>
<p>Here’s the updated email preview with the scrollbar and keyboard accessibility:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762351350276/ae885bd7-40b0-43df-917f-d71914829805.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-resources">Resources</h2>
<ul>
<li><p><a target="_blank" href="https://github.com/TryGhost/Ghost/blob/main/.github/CONTRIBUTING.md">Ghost Contributing Guide</a></p>
</li>
<li><p><a target="_blank" href="https://emberjs.com/">Ember.js Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://webaim.org/techniques/keyboard/">WebAIM: Keyboard Accessibility</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus">MDN: Focus Management</a></p>
</li>
<li><p><a target="_blank" href="https://www.w3.org/WAI/WCAG21/">WCAG 2.1 Guidelines</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Interview Tips from Google Recruiter: Insights from Kunal Kushwaha’s Conversation with Magali Malkin]]></title><description><![CDATA[Introduction
I recently watched a YouTube video of Kunal Kushwaha talking with Magali Malkin, a recruiter from Google. This conversation changed how I view the interview and hiring process.
Before this, I thought getting shortlisted for a job depende...]]></description><link>https://blog.abdultalha.tech/interview-tips-from-google-recruiter-insights-from-kunal-kushwahas-conversation-with-magali-malkin</link><guid isPermaLink="true">https://blog.abdultalha.tech/interview-tips-from-google-recruiter-insights-from-kunal-kushwahas-conversation-with-magali-malkin</guid><category><![CDATA[Open Source]]></category><category><![CDATA[resume]]></category><category><![CDATA[Google]]></category><category><![CDATA[WeMakeDevs]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Fri, 31 Oct 2025 09:44:56 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761903728659/64fb3e70-65b3-4ab8-8bb4-030031df0bbb.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>I recently watched a <a target="_blank" href="https://www.youtube.com/watch?v=8HVwKVxdPxo">YouTube video</a> of Kunal Kushwaha talking with Magali Malkin, a recruiter from Google. This conversation changed how I view the interview and hiring process.</p>
<p>Before this, I thought getting shortlisted for a job depended only on having a great resume or on sharing success stories during interviews. However, I learned that many factors matter, from resume formatting and timing of applications to communication during the hiring process and handling interview failures.</p>
<h2 id="heading-key-learnings">Key Learnings</h2>
<h3 id="heading-1-how-resumes-get-shortlisted">1. How Resumes Get Shortlisted</h3>
<ul>
<li><p>The resume must be well-formatted and include the skills listed in the job description.</p>
</li>
<li><p>Apply early to increase your chances of being noticed.</p>
</li>
<li><p>Avoid using too many infographics. Choose a simple format that highlights your relevant skills, making it easier for recruiters to focus on what’s important.</p>
</li>
</ul>
<h3 id="heading-2-what-happens-after-the-resume-is-shortlisted">2. What Happens After the Resume Is Shortlisted</h3>
<ul>
<li><p>Once a resume is shortlisted, a long process usually follows. This typically includes a DSA round, a technical round, and an HR round.</p>
</li>
<li><p>Keep in touch with the recruiter and show genuine interest in the role. This reflects professionalism and enthusiasm.</p>
</li>
</ul>
<h3 id="heading-3-how-to-frame-answers-the-star-format">3. How to Frame Answers: The STAR Format</h3>
<ul>
<li><p>Use the STAR format to structure your interview answers:</p>
<ul>
<li><p><strong>S (Situation)</strong>: Clearly explain the situation.</p>
</li>
<li><p><strong>T (Task)</strong>: Describe the task or challenge you had.</p>
</li>
<li><p><strong>A (Action)</strong>: Explain the action you took.</p>
</li>
<li><p><strong>R (Result)</strong>: Share the result.</p>
</li>
</ul>
</li>
<li><p>It's okay if the result is not positive. What matters is explaining what you learned from the experience.</p>
</li>
</ul>
<h3 id="heading-4-importance-of-referrals-and-networking">4. Importance of Referrals and Networking</h3>
<ul>
<li><p>Networking is powerful. Building relationships in the industry can help you get referrals.</p>
</li>
<li><p>Referred candidates often receive more attention, and their process tends to be quicker. Connect with professionals, build genuine relationships, and don’t hesitate to ask for referrals.</p>
</li>
</ul>
<h3 id="heading-5-setting-priorities-instead-of-aiming-for-one-company">5. Setting Priorities Instead of Aiming for One Company</h3>
<ul>
<li><p>Don’t focus on just one company. Instead, determine what matters most to you in a workplace, such as culture, learning opportunities, or job type.</p>
</li>
<li><p>This focus helps you find the right fit instead of just chasing a big name.</p>
</li>
<li><p>Remember, fear of failure and rejection are part of the process. Each rejection teaches you something new and helps you grow.</p>
</li>
</ul>
<h2 id="heading-my-reflection">My Reflection</h2>
<p>I realised I had some misconceptions about interviews. I thought I should only share success stories, but now I know it’s okay to discuss failures as long as I explain what I learned. I also used to have a dream company in mind, but now I want to focus on what I want from a company and find one that aligns with my goals.</p>
<h2 id="heading-final-thoughts">Final Thoughts</h2>
<p>The conversation between Kunal Kushwaha and Magali Malkin taught me more than just interview tips. It helped me see the process differently. A good resume doesn’t need to be fancy; it should be clear and relevant. Interview answers don’t always need a positive ending; honesty and learning are more important. Networking is about creating real connections, not just asking for favours. And remember, rejections aren’t failures; they’re lessons that prepare you for the next opportunity.</p>
<p>I will apply these lessons as I move forward, staying genuine, curious, and open to learning from every experience.</p>
<p>If this story resonates with you, share it with others preparing for interviews. A good conversation can change how we view our career journey.</p>
]]></content:encoded></item><item><title><![CDATA[Fixing Ghost’s Disappearing Tag Bug: A Deep Dive into Issue #25020]]></title><description><![CDATA[1. Introduction
Ghost is an open-source headless CMS built with Node.js, trusted by creators and publishers worldwide.
After resolving two earlier issues (#24608 on dark mode transitions and #24706 on spinner alignment), I felt ready to tackle someth...]]></description><link>https://blog.abdultalha.tech/fixing-ghosts-disappearing-tag-bug-a-deep-dive-into-issue-25020</link><guid isPermaLink="true">https://blog.abdultalha.tech/fixing-ghosts-disappearing-tag-bug-a-deep-dive-into-issue-25020</guid><category><![CDATA[ghost]]></category><category><![CDATA[Open Source]]></category><category><![CDATA[open source]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[Node.js]]></category><category><![CDATA[Web Development]]></category><category><![CDATA[cms]]></category><category><![CDATA[Developer]]></category><category><![CDATA[coding]]></category><category><![CDATA[Open Source Community]]></category><category><![CDATA[Career]]></category><category><![CDATA[Technical writing ]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Tue, 28 Oct 2025 08:42:13 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761640692376/77c7f027-6c30-4494-9b9a-bd2e35d0ae49.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-1-introduction">1. Introduction</h2>
<p>Ghost is an open-source headless CMS built with Node.js, trusted by creators and publishers worldwide.</p>
<p>After resolving two earlier issues (#24608 on dark mode transitions and #24706 on spinner alignment), I felt ready to tackle something more challenging. That’s when I came across Issue #25020:</p>
<blockquote>
<p>“Tag disappears from dropdown after removal.”</p>
</blockquote>
<p>It sounded simple, but JavaScript had other plans. This post is a breakdown of how I investigated, fixed, and learned from a subtle UI bug that made tags vanish from the editor like magic.</p>
<h2 id="heading-2-reproducing-the-issue">2. Reproducing the Issue</h2>
<blockquote>
<p>“When you remove a tag while the dropdown is open, it disappears and doesn’t return until the editor is closed.”</p>
</blockquote>
<p>To confirm, I set up Ghost locally and followed these steps:</p>
<ol>
<li><p>Create a new post.</p>
</li>
<li><p>Open Post Settings → Tags.</p>
</li>
<li><p>Click inside the tags input field to open the dropdown.</p>
</li>
<li><p>Select a tag, say <em>News</em>.</p>
</li>
<li><p>Without closing the dropdown, remove <em>News</em>.</p>
</li>
</ol>
<p>Just as described, <em>News</em> vanished. It didn’t reappear until I closed and reopened the editor. That’s definitely not expected behaviour.</p>
<h2 id="heading-3-root-cause">3. Root Cause</h2>
<p>My first thought was that this wasn’t a backend issue since the tags still existed in the database. It had to be a frontend problem, most likely in Ember’s tag management component. A quick search led me to the file:<br /><code>ghost/admin/app/components/gh-tags-token-input.js</code></p>
<p>Inside, I found this snippet:</p>
<pre><code class="lang-js"><span class="hljs-keyword">get</span> <span class="hljs-title">availableTags</span>() {
    <span class="hljs-keyword">const</span> selectedTags = <span class="hljs-built_in">this</span>.args.selected || [];
    <span class="hljs-keyword">const</span> selectedSet = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(selectedTags);
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>._initialTags.filter(<span class="hljs-function"><span class="hljs-params">tag</span> =&gt;</span> !selectedSet.has(tag));
}
</code></pre>
<p>It looked fine at first. Take the selected tags, store them in a Set, and filter them out from the dropdown list. But something was not right.</p>
<p>JavaScript compares objects <strong>by reference</strong>, not <strong>by value</strong>. That means:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> tag1 = {<span class="hljs-attr">id</span>: <span class="hljs-string">'5'</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'News'</span>};
<span class="hljs-keyword">const</span> tag2 = {<span class="hljs-attr">id</span>: <span class="hljs-string">'5'</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'News'</span>};

tag1 === tag2; <span class="hljs-comment">// false</span>
</code></pre>
<p>They look identical but are stored differently in memory. Ghost was creating new tag objects each time a user interacted with them. So when <code>Set.has(tag)</code> it ran, it compared two different object references even though both represented the same tag.</p>
<p>Result: Ghost thought the tag was still selected and kept it filtered out.</p>
<h3 id="heading-4-the-fix">4. The Fix</h3>
<p>Once I pinpointed the issue, the fix was simple. Instead of comparing entire objects, I compared tag IDs, which are unique and constant across references.</p>
<p><strong>Before:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> selectedSet = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(selectedTags);
<span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>._initialTags.filter(<span class="hljs-function"><span class="hljs-params">tag</span> =&gt;</span> !selectedSet.has(tag));
</code></pre>
<p><strong>After:</strong></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> selectedTagIds = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Set</span>(selectedTags.map(<span class="hljs-function"><span class="hljs-params">tag</span> =&gt;</span> tag.id));
<span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>._initialTags.filter(<span class="hljs-function"><span class="hljs-params">tag</span> =&gt;</span> !selectedTagIds.has(tag.id));
</code></pre>
<p>Just two lines changed, and the disappearing tags were gone for good.</p>
<h3 id="heading-5-testing-the-solution">5. Testing the Solution</h3>
<p>I reloaded Ghost, repeatedly adding and removing tags: “News,” “Tech,” and “Updates.”<br />This time, every tag reappeared instantly in the dropdown. No more vanishing act.</p>
<p>Then I ran:</p>
<pre><code class="lang-bash">yarn lint:js app/components/gh-tags-token-input.js
</code></pre>
<p>✅ No errors.</p>
<p>Followed by:</p>
<pre><code class="lang-bash">yarn <span class="hljs-built_in">test</span>:unit --grep=<span class="hljs-string">"tag"</span>
</code></pre>
<p>✅ All tests passed.</p>
<p>The fix was stable, isolated, and ready for a pull request.</p>
<h2 id="heading-6-pull-request">6. Pull Request</h2>
<p>I created PR <a target="_blank" href="https://github.com/TryGhost/Ghost/pull/25262"><strong>#25262</strong></a> with the following commit:</p>
<blockquote>
<p>🐛 Fixed tag disappearing from dropdown after removal<br />fixes <a target="_blank" href="https://github.com/TryGhost/Ghost/issues/25020">https://github.com/TryGhost/Ghost/issues/25020</a></p>
</blockquote>
<p><strong>Description:</strong><br />When editing a post, removing a tag while the dropdown was open caused it to disappear from available options. This happened because Set was comparing object references instead of tag IDs. Fixed by comparing tag IDs instead.</p>
<p>A clear, minimal, and descriptive PR just the way Ghost prefers.</p>
<h2 id="heading-7-lessons-learned">7. Lessons Learned</h2>
<ol>
<li><p><strong>Reference vs. Value Equality</strong><br /> I’d read about it before, but seeing it break real code made it stick. Objects are compared by reference, primitives by value.</p>
</li>
<li><p><strong>Simple Fixes Can Have Big Impact</strong><br /> It wasn’t a critical bug, but it noticeably improved the editor’s user experience.</p>
</li>
<li><p><strong>Each Contribution Builds Confidence</strong><br /> My previous Ghost fixes helped me debug and navigate much faster this time.</p>
</li>
<li><p><strong>Always Reproduce Before You Fix</strong><br /> Seeing the bug in action provides context no stack trace can match.</p>
</li>
</ol>
<h2 id="heading-8-final-thoughts">8. Final Thoughts</h2>
<p>This was my third contribution to Ghost, the open-source CMS led by John O'Nolan and Hannah Wolfe. Each fix has deepened my understanding of modern web systems:</p>
<ul>
<li><p><strong>#24608</strong> UI transitions</p>
</li>
<li><p><strong>#24706</strong> State and layout consistency</p>
</li>
<li><p><strong>#25020</strong> Object identity and equality</p>
</li>
</ul>
<p>Open source is about learning by doing. Every fix teaches something you can’t get from a tutorial. Somewhere, a writer removed a tag and didn’t have to reload their editor, and that tiny moment of smoothness made it worth it.</p>
<h2 id="heading-9-resources">9. Resources</h2>
<ul>
<li><p><a target="_blank" href="https://github.com/TryGhost/Ghost">Ghost GitHub Repository</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/TryGhost/Ghost/issues/25020">Issue #25020</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/TryGhost/Ghost/pull/25262">Pull Request #25262</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/has">MDN: Set.prototype.has()</a></p>
</li>
<li><p><a target="_blank" href="https://ghost.org/docs/contributing/">Ghost Contributing Guidelines</a></p>
</li>
<li><p>Previous Fixes: #24608 and #24706</p>
</li>
</ul>
<p>Found this helpful? Let’s connect on <a target="_blank" href="https://github.com/abdultalha0862">GitHub</a> or here on <a target="_blank" href="https://www.linkedin.com/in/abdul-talha/">LinkedIn</a>. I love sharing what I learn while building real things.</p>
]]></content:encoded></item><item><title><![CDATA[How to Change Careers into Tech — Lessons from Brian Schuster at IBM]]></title><description><![CDATA[Introduction
I recently watched a YouTube video by Brian Schuster and Kunal Kushwaha from IBM discussing their tech journey. He demonstrated how he viewed change as an opportunity for learning and growth. His experience teaches us that it’s never too...]]></description><link>https://blog.abdultalha.tech/how-to-change-careers-into-tech-lessons-from-brian-schuster-at-ibm</link><guid isPermaLink="true">https://blog.abdultalha.tech/how-to-change-careers-into-tech-lessons-from-brian-schuster-at-ibm</guid><category><![CDATA[Open Source]]></category><category><![CDATA[WeMakeDevs]]></category><category><![CDATA[IBM]]></category><category><![CDATA[Career]]></category><category><![CDATA[learning]]></category><dc:creator><![CDATA[Abdul Talha]]></dc:creator><pubDate>Sat, 25 Oct 2025 10:36:50 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1761388479397/e36dbae6-7efe-4aca-be42-7ab95c309f27.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction"><strong>Introduction</strong></h2>
<p>I recently watched a <a target="_blank" href="https://www.youtube.com/watch?v=IUR5f_1bFaE">YouTube</a> video by Brian Schuster and Kunal Kushwaha from IBM discussing their tech journey. He demonstrated how he viewed change as an opportunity for learning and growth. His experience teaches us that it’s never too late to start over if you have curiosity and the right mindset.</p>
<h2 id="heading-key-learnings"><strong>Key Learnings</strong></h2>
<p>1. <strong>Brian’s Journey</strong>  </p>
<p>Brian explained how he transitioned into tech after attending a boot camp. He learned Python and used his family business experience for roles like Business Analyst and Data Analyst. He eventually became a Cloud Engineer (DevOps) at IBM and began mentoring others who wanted to make similar transitions.</p>
<p>2. <strong>How to Know if Tech Is for You</strong>  </p>
<p>The best way to find out is to try it. If you don’t enjoy it, it's okay to switch to another field. Work on hands-on projects, contribute to open-source, or attend hackathons. If it excites you, keep going. If not, you’ll still gain valuable skills.</p>
<p>3. <strong>How to Get Your First Role in Tech</strong>  </p>
<p>Stay open-minded and eager to learn. You don’t need to know everything at the start. Growth comes from real work experience. Be patient.</p>
<p>4. <strong>How to Decide if It's Time to Move On</strong>  </p>
<p>If you stop growing or if the company culture doesn’t match your values, consider exploring new opportunities. Your career should help you grow, both professionally and personally.</p>
<p>5. <strong>How to Change Careers if You're Already Experienced</strong>  </p>
<p>If you have experience in another field, show your skills through evidence:  </p>
<ol>
<li><p>Write blogs  </p>
</li>
<li><p>Build projects  </p>
</li>
<li><p>Contribute to open-source communities  </p>
</li>
</ol>
<p>These examples say more than your past job titles.</p>
<p>6. <strong>How to Approach the Job Market</strong>  </p>
<p>Focus on one field and create a strong portfolio that includes:  </p>
<ol>
<li><p>Blogs about what you learn  </p>
</li>
<li><p>Projects you’ve built  </p>
</li>
<li><p>LinkedIn posts showing your progress  </p>
</li>
</ol>
<p>Don’t hesitate to ask for referrals. The tech community is often supportive.</p>
<h2 id="heading-my-reflection"><strong>My Reflection</strong></h2>
<p>From this talk, I learned it’s never too late to switch if your current path isn’t right for you. Change doesn’t mean failure; it means growth. I also recognised the importance of asking for referrals, building connections, and sharing your progress. The key is to keep learning, experimenting, and adapting.</p>
<h2 id="heading-final-thoughts"><strong>Final Thoughts</strong></h2>
<p>Brian’s story shows that transitioning into tech isn’t just about learning tools or coding languages. It’s about resilience, curiosity, and ongoing learning. No matter where you start, your journey is valid as long as you keep moving forward. Thanks to Brian Schuster for sharing his insights. This talk reminded me that tech welcomes everyone willing to learn.</p>
<p>What are some other lesser-known roles in tech that more people should explore?</p>
]]></content:encoded></item></channel></rss>