<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Rizwan Saleem</title>
    <description>The latest articles on DEV Community by Rizwan Saleem (@therizwansaleem).</description>
    <link>https://dev.to/therizwansaleem</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3468139%2F9a515018-9f60-4536-ad74-2387da60620f.jpg</url>
      <title>DEV Community: Rizwan Saleem</title>
      <link>https://dev.to/therizwansaleem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/therizwansaleem"/>
    <language>en</language>
    <item>
      <title>TypeScript Unknown States in Open Banking Consent Flows</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 20:40:18 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/typescript-unknown-states-in-open-banking-consent-flows-lb6</link>
      <guid>https://dev.to/therizwansaleem/typescript-unknown-states-in-open-banking-consent-flows-lb6</guid>
      <description>&lt;h1&gt;
  
  
  TypeScript Unknown States in Open Banking Consent Flows
&lt;/h1&gt;

&lt;p&gt;Open banking frontend work is full of states that look small in the UI but carry real product trust consequences.&lt;/p&gt;

&lt;p&gt;A consent journey can move through loading, redirecting, returning, authorising, partially authorised, expired, failed, cancelled, and retryable states. If the frontend treats those states as a loose set of booleans, the experience can quickly become confusing: a spinner that never explains itself, a success message that appears too early, or an error state that makes a recoverable journey feel broken.&lt;/p&gt;

&lt;p&gt;TypeScript is useful here because it encourages the team to name uncertainty.&lt;/p&gt;

&lt;p&gt;Instead of modelling a consent flow as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="nx"&gt;isLoading&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="nx"&gt;hasError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;span class="nx"&gt;isComplete&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;boolean&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I prefer thinking in explicit states:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;type&lt;/span&gt; &lt;span class="nx"&gt;ConsentState&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;idle&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;starting&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;redirecting-to-bank&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;returning-from-bank&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;authorised&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;partially-authorised&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;missingScopes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expired&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;cancelled-by-user&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;retryable-error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;blocked-error&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nl"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This does not solve every product problem, but it changes the engineering conversation. The team is no longer asking only “does the page work?” It can ask better questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What does the user see while they are leaving the app?&lt;/li&gt;
&lt;li&gt;What happens when they come back without completing consent?&lt;/li&gt;
&lt;li&gt;Which errors are safe to retry?&lt;/li&gt;
&lt;li&gt;Which messages need to avoid blame or panic?&lt;/li&gt;
&lt;li&gt;Which state should analytics record?&lt;/li&gt;
&lt;li&gt;Which state should support or operations teams recognise later?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI-assisted coding can speed up the component work, but it should not be allowed to flatten product risk into a generic loading/error/success pattern. In regulated or trust-sensitive journeys, human judgement still needs to review the states, labels, transitions, and fallback paths.&lt;/p&gt;

&lt;p&gt;For React, Next.js, and TypeScript teams, the goal is not to create complicated types for their own sake. The goal is to make uncertainty visible before it becomes user confusion.&lt;/p&gt;

&lt;p&gt;That is the difference between a UI that merely renders data and a frontend system that earns trust.&lt;/p&gt;

&lt;p&gt;— Rizwan Saleem&lt;/p&gt;

&lt;p&gt;Rizwan Saleem is a UK-based Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder.&lt;/p&gt;

&lt;p&gt;Website: &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Internal/backlink suggestions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Link from a future &lt;code&gt;Frontend Engineering&lt;/code&gt; or &lt;code&gt;Open Banking&lt;/code&gt; article hub on rizwansaleem.co.&lt;/li&gt;
&lt;li&gt;If published on DEV.to, Hashnode, Medium, or Substack, include one natural canonical backlink to &lt;code&gt;https://rizwansaleem.co&lt;/code&gt; in the author footer.&lt;/li&gt;
&lt;li&gt;Cross-link later to drafts about accessible loading states, open banking frontend risk, and AI-assisted frontend testing.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Next.js Server and Client Boundaries Are Product Decisions, Not Just Framework Details</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 20:30:18 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/nextjs-server-and-client-boundaries-are-product-decisions-not-just-framework-details-4hf6</link>
      <guid>https://dev.to/therizwansaleem/nextjs-server-and-client-boundaries-are-product-decisions-not-just-framework-details-4hf6</guid>
      <description>&lt;h1&gt;
  
  
  Next.js Server and Client Boundaries Are Product Decisions, Not Just Framework Details
&lt;/h1&gt;

&lt;p&gt;One of the easiest mistakes in modern frontend development is treating server/client boundaries as a technical afterthought.&lt;/p&gt;

&lt;p&gt;In Next.js, the choice between server-side work and client-side interactivity can look like a framework detail. Add a directive, move some state, fetch data in a different place, and the page works.&lt;/p&gt;

&lt;p&gt;But that boundary is rarely neutral.&lt;/p&gt;

&lt;p&gt;It affects performance, privacy, loading states, bundle size, reliability, maintainability, and the way a user experiences trust.&lt;/p&gt;

&lt;p&gt;For engineers working with React, Next.js, TypeScript, AI-assisted workflows, fintech interfaces, or open banking-style products, that distinction matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  A working UI is not always a well-designed boundary
&lt;/h2&gt;

&lt;p&gt;AI tools are good at producing plausible React and Next.js code quickly. They can scaffold a component, suggest a data fetch, wire up state, and create a passable interface.&lt;/p&gt;

&lt;p&gt;That speed is useful.&lt;/p&gt;

&lt;p&gt;But generated code often optimises for completion, not responsibility.&lt;/p&gt;

&lt;p&gt;A component may work locally while still raising important questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is this data being sent to the browser unnecessarily?&lt;/li&gt;
&lt;li&gt;Is the interaction genuinely client-side, or did we make it client-side for convenience?&lt;/li&gt;
&lt;li&gt;Are we increasing JavaScript for users who only need static content?&lt;/li&gt;
&lt;li&gt;Are loading, failure, empty, and retry states clearly represented?&lt;/li&gt;
&lt;li&gt;Are types describing the real contract, or just silencing errors?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A frontend engineer’s job is not only to make the interface render. It is to decide where the logic should live and what trade-offs the product is accepting.&lt;/p&gt;

&lt;h2&gt;
  
  
  The boundary affects user trust
&lt;/h2&gt;

&lt;p&gt;Users do not care whether a component is a server component, client component, route handler, or API response.&lt;/p&gt;

&lt;p&gt;They care whether the product feels fast, clear, safe, and reliable.&lt;/p&gt;

&lt;p&gt;That is especially important in domains where trust matters: fintech, open banking, identity, forms, payments, dashboards, and account flows.&lt;/p&gt;

&lt;p&gt;A small boundary decision can change the experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A server-rendered page may feel faster and more stable.&lt;/li&gt;
&lt;li&gt;A client-heavy flow may support rich interaction, but increase loading cost.&lt;/li&gt;
&lt;li&gt;A poorly placed data fetch may create confusing loading states.&lt;/li&gt;
&lt;li&gt;An unclear error path may make users unsure whether an action succeeded.&lt;/li&gt;
&lt;li&gt;An unnecessary client-side payload may expose data or implementation assumptions that did not need to be there.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are product questions, not only engineering questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical review checklist
&lt;/h2&gt;

&lt;p&gt;When reviewing a Next.js component or AI-generated implementation, I use a simple boundary checklist:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Interaction
&lt;/h3&gt;

&lt;p&gt;Does this component need browser-only behaviour such as local state, event handlers, focus management, drag/drop, or live interaction?&lt;/p&gt;

&lt;p&gt;If not, keep it server-side where possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Data
&lt;/h3&gt;

&lt;p&gt;Does the browser need this data, or only the rendered result?&lt;/p&gt;

&lt;p&gt;Avoid moving data client-side just because it is convenient.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Performance
&lt;/h3&gt;

&lt;p&gt;What is the JavaScript cost of this decision?&lt;/p&gt;

&lt;p&gt;A small component can still pull a larger dependency tree into the client bundle.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Failure states
&lt;/h3&gt;

&lt;p&gt;What does the user see when the request fails, times out, returns empty data, or needs retry?&lt;/p&gt;

&lt;p&gt;The boundary should not hide failure. It should make recovery clear.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Types
&lt;/h3&gt;

&lt;p&gt;Do TypeScript types explain the contract between server, client, API, and UI?&lt;/p&gt;

&lt;p&gt;Good types help future engineers understand what is allowed, optional, delayed, or unsafe.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. AI review
&lt;/h3&gt;

&lt;p&gt;If AI generated the code, ask it to critique the boundary decision, not only the syntax.&lt;/p&gt;

&lt;p&gt;Useful prompts include:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review this Next.js component for unnecessary client-side state, avoidable bundle cost, unclear data boundaries, missing loading/error states, and TypeScript contract weaknesses.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Suggest which parts of this implementation should remain server-side and which parts genuinely need client-side interactivity. Explain the trade-offs.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The engineer still owns the judgement
&lt;/h2&gt;

&lt;p&gt;AI can speed up implementation, comparison, refactoring, and review.&lt;/p&gt;

&lt;p&gt;It can suggest alternatives and expose edge cases.&lt;/p&gt;

&lt;p&gt;But it cannot take responsibility for the product boundary.&lt;/p&gt;

&lt;p&gt;That responsibility sits with the engineer and the team.&lt;/p&gt;

&lt;p&gt;For me, frontend engineering is where system decisions become visible to users. React, Next.js, TypeScript, AI tools, and product thinking all meet at that edge.&lt;/p&gt;

&lt;p&gt;A good boundary is not just technically valid.&lt;/p&gt;

&lt;p&gt;It is clear, intentional, maintainable, and respectful of the user’s time and trust.&lt;/p&gt;

&lt;p&gt;That is the work.&lt;/p&gt;




&lt;p&gt;Rizwan Saleem — &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Frontend Release Notes as Product Trust Work | Rizwan Saleem</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 20:20:33 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/frontend-release-notes-as-product-trust-work-rizwan-saleem-3k81</link>
      <guid>https://dev.to/therizwansaleem/frontend-release-notes-as-product-trust-work-rizwan-saleem-3k81</guid>
      <description>&lt;h1&gt;
  
  
  Frontend release notes as product trust work
&lt;/h1&gt;

&lt;p&gt;Release notes are often treated as an afterthought: a short line at the end of a sprint, a ticket number, or a vague message like “improvements and bug fixes.”&lt;/p&gt;

&lt;p&gt;For frontend teams, that is a missed opportunity.&lt;/p&gt;

&lt;p&gt;A useful release note is not only a marketing update. It is a small public contract between the product and the people using it. It tells users what changed, why it changed, and what kind of engineering judgement sits behind the interface.&lt;/p&gt;

&lt;p&gt;That matters in ordinary software. It matters even more in fintech, open banking, and AI-assisted software engineering.&lt;/p&gt;

&lt;h2&gt;
  
  
  What good frontend release notes should explain
&lt;/h2&gt;

&lt;p&gt;A practical frontend release note should usually answer five questions:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What changed in the interface?&lt;/li&gt;
&lt;li&gt;Why does the change matter to users?&lt;/li&gt;
&lt;li&gt;Which states were considered — loading, empty, error, retry, disabled, success?&lt;/li&gt;
&lt;li&gt;Did accessibility, validation, or copy change?&lt;/li&gt;
&lt;li&gt;What is still intentionally limited or being improved?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That level of clarity helps avoid vague claims. It also gives product, design, engineering, support, and compliance-minded teams a shared record of what was actually shipped.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters for React, Next.js, and TypeScript teams
&lt;/h2&gt;

&lt;p&gt;Frontend work is full of decisions that can look small from the outside:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;moving a boundary between server and client components&lt;/li&gt;
&lt;li&gt;changing a form validation rule&lt;/li&gt;
&lt;li&gt;adding a retry state&lt;/li&gt;
&lt;li&gt;tightening a TypeScript type&lt;/li&gt;
&lt;li&gt;changing an error message&lt;/li&gt;
&lt;li&gt;making a loading state more accessible&lt;/li&gt;
&lt;li&gt;making an AI-assisted refactor safer before merge&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of those decisions can affect user trust.&lt;/p&gt;

&lt;p&gt;When teams document them clearly, they build a better engineering memory. When they hide them behind generic release notes, the product loses context.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI-assisted engineering makes this more important, not less
&lt;/h2&gt;

&lt;p&gt;AI tools can help teams draft code, explore alternatives, and speed up review. But they do not remove the need for human judgement.&lt;/p&gt;

&lt;p&gt;If anything, AI-assisted work makes release notes more important because teams need to be clearer about product intent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what was changed by design&lt;/li&gt;
&lt;li&gt;what was preserved deliberately&lt;/li&gt;
&lt;li&gt;which edge cases were reviewed&lt;/li&gt;
&lt;li&gt;where human judgement overruled a generated suggestion&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal is not to mention AI for attention. The goal is to keep ownership of the user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple release-note template
&lt;/h2&gt;

&lt;p&gt;For frontend changes, I like a simple structure:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Changed:&lt;/strong&gt; What changed in plain language.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why:&lt;/strong&gt; The product or user reason.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;User impact:&lt;/strong&gt; What users may notice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Engineering note:&lt;/strong&gt; Relevant React, Next.js, TypeScript, accessibility, performance, or state-management detail.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known limits:&lt;/strong&gt; What is not solved yet.&lt;/p&gt;

&lt;p&gt;This keeps the note practical without turning it into a long essay.&lt;/p&gt;

&lt;h2&gt;
  
  
  Credibility compounds through small decisions
&lt;/h2&gt;

&lt;p&gt;My core line is: “I was not born with a way out, so I built one.”&lt;/p&gt;

&lt;p&gt;That applies to more than career growth. It also shapes how I think about software. Credibility is rarely built through one dramatic announcement. It compounds through small, honest decisions: clearer states, safer types, better wording, cleaner boundaries, and transparent notes about what shipped.&lt;/p&gt;

&lt;p&gt;Frontend release notes are one of those small decisions.&lt;/p&gt;

&lt;p&gt;They tell users and teams: we are paying attention.&lt;/p&gt;

&lt;p&gt;— Rizwan Saleem&lt;br&gt;&lt;br&gt;
UK-based Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder.&lt;br&gt;&lt;br&gt;
&lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI-assisted refactoring without losing product intent | Rizwan Saleem</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 20:10:19 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/ai-assisted-refactoring-without-losing-product-intent-rizwan-saleem-11mm</link>
      <guid>https://dev.to/therizwansaleem/ai-assisted-refactoring-without-losing-product-intent-rizwan-saleem-11mm</guid>
      <description>&lt;h3&gt;
  
  
  AI-assisted refactoring without losing product intent
&lt;/h3&gt;

&lt;p&gt;Refactoring is not only a code-cleanliness exercise. In frontend engineering, refactoring can change how people experience a product: how quickly a screen becomes useful, how a form explains failure, how a loading state reduces uncertainty, and how accessible the interface remains when something unexpected happens.&lt;/p&gt;

&lt;p&gt;That is why AI-assisted refactoring needs more than a prompt that says “make this cleaner”.&lt;/p&gt;

&lt;p&gt;Cleaner code is useful, but not if the new version silently removes product intent.&lt;/p&gt;

&lt;p&gt;A component usually contains more context than its syntax shows. Some of that context is obvious: props, state, validation, API calls, and rendering branches. Some of it is hidden in the history of the product: a condition added because real users got confused, a loading state added because a financial action felt risky, an error message added because support saw the same issue repeatedly.&lt;/p&gt;

&lt;p&gt;AI can help with structure, naming, simplification, test ideas, and alternative implementations. But the engineer still has to protect the things the model cannot fully know.&lt;/p&gt;

&lt;p&gt;Before asking AI to refactor frontend code, I like to make the intent explicit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What user problem does this component or flow solve?&lt;/li&gt;
&lt;li&gt;Which states are business-critical?&lt;/li&gt;
&lt;li&gt;What can fail?&lt;/li&gt;
&lt;li&gt;What should be visible to screen readers?&lt;/li&gt;
&lt;li&gt;What should happen while data is loading?&lt;/li&gt;
&lt;li&gt;Which behaviours are relied on by users, support, or compliance-heavy product flows?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is especially important in fintech and open banking interfaces, where frontend decisions are often trust decisions. Consent screens, transaction states, permissions, error recovery, and account-connection flows should not be treated as visual details. They are part of the product contract.&lt;/p&gt;

&lt;p&gt;A safer AI-assisted workflow looks like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Document the current intent.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Write a short summary of what the code is supposed to protect before asking for changes.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask for options, not one rewrite.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
A few alternatives make trade-offs easier to compare.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Review the diff against behaviour.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Do not only ask whether the code is shorter. Ask whether loading, error, empty, disabled, and accessibility states survived.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Add or update tests around user outcomes.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
TypeScript can catch many mistakes, but product trust also needs behavioural tests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep the final decision human-owned.&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
AI can accelerate mechanical work, but the engineer owns the context, risk, and release decision.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Used well, AI can make frontend refactoring faster and more deliberate. Used carelessly, it can make teams overconfident while removing the small behaviours that made a product reliable.&lt;/p&gt;

&lt;p&gt;The goal is not to avoid AI. The goal is to use it with engineering judgement.&lt;/p&gt;

&lt;p&gt;I am Rizwan Saleem, a UK-based Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder. My core line is: “I was not born with a way out, so I built one.”&lt;/p&gt;

&lt;p&gt;More about my work: &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>AI-Assisted Frontend Testing: A Practical Contract for React and TypeScript Teams</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 20:00:19 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/ai-assisted-frontend-testing-a-practical-contract-for-react-and-typescript-teams-3lf4</link>
      <guid>https://dev.to/therizwansaleem/ai-assisted-frontend-testing-a-practical-contract-for-react-and-typescript-teams-3lf4</guid>
      <description>&lt;h3&gt;
  
  
  AI-assisted frontend testing is a contract, not a checkbox
&lt;/h3&gt;

&lt;p&gt;AI can make frontend testing feel easier. It can generate test cases, suggest edge states, explain mocking patterns, and help turn vague requirements into clearer assertions.&lt;/p&gt;

&lt;p&gt;That is useful.&lt;/p&gt;

&lt;p&gt;But it also creates a risk: teams may confuse more test code with more product confidence.&lt;/p&gt;

&lt;p&gt;In frontend engineering, especially in user-facing flows built with React, Next.js, and TypeScript, testing is not only about proving a component renders. It is about protecting trust at the exact moment a user depends on the interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  The happy path is rarely where trust breaks
&lt;/h3&gt;

&lt;p&gt;AI tools are usually good at producing obvious tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;renders the component&lt;/li&gt;
&lt;li&gt;submits the form&lt;/li&gt;
&lt;li&gt;shows a success message&lt;/li&gt;
&lt;li&gt;handles a basic error&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those are a start, not the finish.&lt;/p&gt;

&lt;p&gt;The more important questions are usually closer to product risk:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens if the API returns partial data?&lt;/li&gt;
&lt;li&gt;What happens if loading takes longer than expected?&lt;/li&gt;
&lt;li&gt;What happens if the user refreshes midway through a flow?&lt;/li&gt;
&lt;li&gt;What happens if consent is denied or expires?&lt;/li&gt;
&lt;li&gt;What happens if validation tells the developer what failed but not the user?&lt;/li&gt;
&lt;li&gt;What happens if the interface works visually but fails for keyboard users?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where frontend testing becomes less about coverage percentages and more about judgement.&lt;/p&gt;

&lt;h3&gt;
  
  
  A practical AI-assisted testing loop
&lt;/h3&gt;

&lt;p&gt;A useful workflow is to treat AI as a second reviewer, not the owner of the test strategy.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Describe the user journey clearly&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Write the flow in plain English before asking for tests. Include the user goal, the failure modes, and the trust-sensitive moments.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Ask for missing edge cases&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Instead of asking only for test code, ask: “What could break user trust in this flow?”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Group tests by risk&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Separate rendering tests, interaction tests, accessibility checks, error states, and data-boundary cases.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Use TypeScript to tighten assumptions&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If a test requires impossible mock data, the type model may be hiding a product ambiguity.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Review generated tests like production code&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
AI-generated tests can assert the wrong thing confidently. The engineer still needs to ask whether the assertion protects the user, not just the implementation.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The frontend testing contract
&lt;/h3&gt;

&lt;p&gt;For me, a stronger frontend testing mindset asks four questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the interface explain what is happening?&lt;/li&gt;
&lt;li&gt;Does it fail safely when the system is uncertain?&lt;/li&gt;
&lt;li&gt;Does it remain usable across accessibility needs?&lt;/li&gt;
&lt;li&gt;Does it protect the user’s intent when data, consent, or network conditions change?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That mindset matters in fintech and open banking flows, but it also applies to any product where the UI carries trust.&lt;/p&gt;

&lt;p&gt;AI can accelerate the work. It can suggest scenarios that humans miss. It can help generate test scaffolding faster.&lt;/p&gt;

&lt;p&gt;But the final responsibility remains human.&lt;/p&gt;

&lt;p&gt;The goal is not to say, “AI wrote our tests.”&lt;/p&gt;

&lt;p&gt;The goal is to say, “Our tests describe the contract we are making with the user.”&lt;/p&gt;

&lt;p&gt;— Rizwan Saleem&lt;br&gt;&lt;br&gt;
UK-based Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder.&lt;br&gt;&lt;br&gt;
Website: &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Accessible Loading States in React Fintech Apps: A Practical Trust Checklist</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 19:50:18 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/accessible-loading-states-in-react-fintech-apps-a-practical-trust-checklist-4h5k</link>
      <guid>https://dev.to/therizwansaleem/accessible-loading-states-in-react-fintech-apps-a-practical-trust-checklist-4h5k</guid>
      <description>&lt;h3&gt;
  
  
  Accessible loading states are product trust work in React fintech apps
&lt;/h3&gt;

&lt;p&gt;A loading state looks small until the user is waiting for something important.&lt;/p&gt;

&lt;p&gt;In ordinary software, a vague spinner is annoying. In fintech and open banking interfaces, it can create confusion at exactly the wrong moment: connecting an account, approving consent, fetching balances, confirming a payment, or recovering from a failed request.&lt;/p&gt;

&lt;p&gt;That is why I do not see loading states as visual polish. I see them as part of the trust contract between the product and the user.&lt;/p&gt;

&lt;h3&gt;
  
  
  The problem with vague loading
&lt;/h3&gt;

&lt;p&gt;A generic spinner often says only one thing: “wait”.&lt;/p&gt;

&lt;p&gt;But users usually need more than that. They need to understand:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;what action is in progress,&lt;/li&gt;
&lt;li&gt;whether they can safely leave or retry,&lt;/li&gt;
&lt;li&gt;whether pressing again may duplicate an action,&lt;/li&gt;
&lt;li&gt;whether the system is waiting on a third party,&lt;/li&gt;
&lt;li&gt;whether the state is still active or has silently failed.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In a fintech flow, those details are not minor. They affect confidence.&lt;/p&gt;

&lt;h3&gt;
  
  
  A practical checklist
&lt;/h3&gt;

&lt;p&gt;When I review a React or Next.js flow, I like to ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the loading state describe the actual operation?&lt;/li&gt;
&lt;li&gt;Is the previous user context preserved instead of blanked out?&lt;/li&gt;
&lt;li&gt;Are buttons disabled only when that is genuinely safer?&lt;/li&gt;
&lt;li&gt;Is there a timeout or recovery path?&lt;/li&gt;
&lt;li&gt;Is the state understandable without colour alone?&lt;/li&gt;
&lt;li&gt;Does it work with keyboard navigation and screen readers?&lt;/li&gt;
&lt;li&gt;Are success, failure, empty, partial, and retry states distinct?&lt;/li&gt;
&lt;li&gt;Does the TypeScript model make impossible states harder to represent?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A useful loading state is not just an animation. It is a small explanation of system uncertainty.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where TypeScript helps
&lt;/h3&gt;

&lt;p&gt;TypeScript cannot design the experience for you, but it can make state clearer.&lt;/p&gt;

&lt;p&gt;Instead of treating a request as a loose collection of booleans, frontend teams can model the flow more explicitly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;idle,&lt;/li&gt;
&lt;li&gt;loading,&lt;/li&gt;
&lt;li&gt;success,&lt;/li&gt;
&lt;li&gt;empty,&lt;/li&gt;
&lt;li&gt;partial,&lt;/li&gt;
&lt;li&gt;failed,&lt;/li&gt;
&lt;li&gt;retrying,&lt;/li&gt;
&lt;li&gt;expired.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That structure makes it easier to avoid impossible combinations like showing a success message and a retry error at the same time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where AI helps — and where it does not
&lt;/h3&gt;

&lt;p&gt;AI-assisted engineering can be useful here. It can help generate test cases, review copy variations, identify missing edge states, and compare implementation options.&lt;/p&gt;

&lt;p&gt;But AI should not be allowed to decide the product risk on its own.&lt;/p&gt;

&lt;p&gt;The engineer still needs to ask: if this state is wrong, confusing, or inaccessible, what might the user do next? In financial interfaces, that question matters.&lt;/p&gt;

&lt;h3&gt;
  
  
  The takeaway
&lt;/h3&gt;

&lt;p&gt;Frontend engineering is not only about rendering a screen quickly. It is about helping people understand what the system is doing, especially when the system is uncertain.&lt;/p&gt;

&lt;p&gt;Good loading states reduce doubt. Good error states reduce panic. Good state modelling reduces accidental product risk.&lt;/p&gt;

&lt;p&gt;That is why accessible loading states deserve more attention in React, Next.js, TypeScript, fintech, and open banking work.&lt;/p&gt;

&lt;p&gt;They are small pieces of UI, but they carry a lot of trust.&lt;/p&gt;

&lt;p&gt;— Rizwan Saleem&lt;br&gt;&lt;br&gt;
UK-based Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder&lt;br&gt;&lt;br&gt;
&lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Next.js Metadata Is an Entity Trust Layer, Not Just SEO Decoration</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 19:47:19 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/nextjs-metadata-is-an-entity-trust-layer-not-just-seo-decoration-2kde</link>
      <guid>https://dev.to/therizwansaleem/nextjs-metadata-is-an-entity-trust-layer-not-just-seo-decoration-2kde</guid>
      <description>&lt;h3&gt;
  
  
  Next.js Metadata Is Not Decoration; It Is an Entity Trust Layer
&lt;/h3&gt;

&lt;p&gt;A lot of frontend teams treat metadata as something that gets added at the end of a project.&lt;/p&gt;

&lt;p&gt;The page works. The design is approved. The components are shipped. Then someone remembers the title tag, meta description, Open Graph image, and maybe a canonical URL.&lt;/p&gt;

&lt;p&gt;That approach misses something important: metadata is not decoration. It is part of how a website explains itself.&lt;/p&gt;

&lt;p&gt;For personal websites, startup sites, technical blogs, and portfolio pages, this explanation becomes part of public trust.&lt;/p&gt;

&lt;h3&gt;
  
  
  The web has to understand what a page represents
&lt;/h3&gt;

&lt;p&gt;A human can land on a page and quickly infer context from the design, writing, navigation, and tone.&lt;/p&gt;

&lt;p&gt;Search engines and social platforms need more explicit signals.&lt;/p&gt;

&lt;p&gt;They need to understand:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What is this page about?&lt;/li&gt;
&lt;li&gt;Who or what is the primary entity?&lt;/li&gt;
&lt;li&gt;Is this the canonical version?&lt;/li&gt;
&lt;li&gt;Which profiles or sources support the same identity?&lt;/li&gt;
&lt;li&gt;What should appear when the page is shared?&lt;/li&gt;
&lt;li&gt;Does the metadata match the visible content?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where frontend engineering and technical SEO overlap.&lt;/p&gt;

&lt;p&gt;In a Next.js project, metadata should be treated as part of the page contract, not as an afterthought.&lt;/p&gt;

&lt;h3&gt;
  
  
  What I check on a serious personal or founder website
&lt;/h3&gt;

&lt;p&gt;For a personal brand site, I want the basic entity signals to be boringly consistent.&lt;/p&gt;

&lt;p&gt;That usually means:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A clear homepage title using the person’s real name and primary positioning.&lt;/li&gt;
&lt;li&gt;A meta description that matches the visible homepage copy.&lt;/li&gt;
&lt;li&gt;A canonical URL for every indexable page.&lt;/li&gt;
&lt;li&gt;Open Graph and Twitter/X card data that creates accurate link previews.&lt;/li&gt;
&lt;li&gt;Person schema only where the facts are verified.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sameAs&lt;/code&gt; links pointing to official public profiles.&lt;/li&gt;
&lt;li&gt;Internal links between biography, articles, projects, and contact pages.&lt;/li&gt;
&lt;li&gt;No exaggerated claims in metadata that are not supported in the page body.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For Rizwan Saleem, the approved public positioning is straightforward: UK-based Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder.&lt;/p&gt;

&lt;p&gt;That wording should remain consistent across the website, schema, and public profiles wherever possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Consistency beats hype
&lt;/h3&gt;

&lt;p&gt;A common mistake in personal-brand SEO is trying to make every field sound bigger than the truth.&lt;/p&gt;

&lt;p&gt;That is risky.&lt;/p&gt;

&lt;p&gt;Search systems and readers are both good at detecting inconsistency. If a title tag claims “world-leading expert” but the actual site shows a normal professional portfolio, the metadata is not helping. It is creating doubt.&lt;/p&gt;

&lt;p&gt;Good metadata does the opposite. It reduces ambiguity.&lt;/p&gt;

&lt;p&gt;It says: this is the person, this is the topic, this is the canonical website, these are the supporting profiles, and this is what the page honestly contains.&lt;/p&gt;

&lt;h3&gt;
  
  
  The frontend takeaway
&lt;/h3&gt;

&lt;p&gt;If you work with React, Next.js, or TypeScript, metadata deserves the same engineering discipline as UI states, accessibility, and data contracts.&lt;/p&gt;

&lt;p&gt;A useful checklist:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does every important page have a unique title?&lt;/li&gt;
&lt;li&gt;Does the description reflect the visible content?&lt;/li&gt;
&lt;li&gt;Are canonical URLs correct?&lt;/li&gt;
&lt;li&gt;Do social previews look professional and accurate?&lt;/li&gt;
&lt;li&gt;Is schema factual and current?&lt;/li&gt;
&lt;li&gt;Are profile links consistent with the official identity?&lt;/li&gt;
&lt;li&gt;Are internal links helping users and crawlers understand the site?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this is glamorous. But it compounds.&lt;/p&gt;

&lt;p&gt;A clear site is easier to trust. A consistent entity is easier to understand. A technically clean personal website gives every future article, profile, and backlink a stronger home base.&lt;/p&gt;

&lt;p&gt;The goal is not to trick the algorithm.&lt;/p&gt;

&lt;p&gt;The goal is to make the truth easier to parse.&lt;/p&gt;




&lt;p&gt;Rizwan Saleem — &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Manchester Tech Career Growth: Credibility Compounds in Small Technical Decisions</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 18:30:28 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/manchester-tech-career-growth-credibility-compounds-in-small-technical-decisions-1k6e</link>
      <guid>https://dev.to/therizwansaleem/manchester-tech-career-growth-credibility-compounds-in-small-technical-decisions-1k6e</guid>
      <description>&lt;h1&gt;
  
  
  Manchester Tech Career Growth: Credibility Compounds in Small Technical Decisions
&lt;/h1&gt;

&lt;p&gt;A serious software career is rarely built from one dramatic breakthrough.&lt;/p&gt;

&lt;p&gt;Most of it is built through small technical decisions that compound over time.&lt;/p&gt;

&lt;p&gt;That is one of the most useful lessons I have learned as a UK-based frontend developer working across React, Next.js, TypeScript, AI-assisted engineering, and fintech/open banking products.&lt;/p&gt;

&lt;p&gt;The visible parts of a product carry a lot of trust. Users may never see the architecture diagram, the deployment pipeline, or the internal debate behind a feature. They do see the loading state. They do feel the error flow. They do notice when a form loses their data, when a consent screen is unclear, or when an interface behaves differently from what the product promised.&lt;/p&gt;

&lt;p&gt;That is why frontend engineering is not only about making screens look correct. It is about translating product risk, data boundaries, accessibility, and user intent into an experience people can rely on.&lt;/p&gt;

&lt;h2&gt;
  
  
  The small decisions that matter
&lt;/h2&gt;

&lt;p&gt;Credibility often compounds through decisions that look minor in isolation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Making a TypeScript type more honest instead of forcing a value through the system.&lt;/li&gt;
&lt;li&gt;Writing loading states that explain what is happening instead of leaving users uncertain.&lt;/li&gt;
&lt;li&gt;Designing error messages that help recovery rather than shifting blame.&lt;/li&gt;
&lt;li&gt;Keeping pull requests small enough for proper review.&lt;/li&gt;
&lt;li&gt;Questioning an AI-generated implementation before merging it.&lt;/li&gt;
&lt;li&gt;Choosing boring, stable code when the product needs reliability more than novelty.&lt;/li&gt;
&lt;li&gt;Asking whether a frontend shortcut creates risk for accessibility, consent, or user trust.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of these decisions create instant visibility. But repeated over months and years, they shape the kind of engineer people trust with important interfaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI changes speed, not responsibility
&lt;/h2&gt;

&lt;p&gt;AI-assisted software engineering makes this even more important.&lt;/p&gt;

&lt;p&gt;AI tools can help with scaffolding, refactoring, comparison, and exploration. They can make a developer faster. But speed is not the same as judgement.&lt;/p&gt;

&lt;p&gt;The developer still owns the decision to ship. The developer still needs to understand the product context, the user impact, the data boundary, the accessibility trade-off, and the failure mode.&lt;/p&gt;

&lt;p&gt;For frontend engineers, this matters because AI can generate UI code that looks plausible while missing the messy parts that make an interface trustworthy: edge states, empty states, validation, progressive disclosure, keyboard use, responsive behaviour, and recovery paths.&lt;/p&gt;

&lt;h2&gt;
  
  
  A UK tech career is built through trust
&lt;/h2&gt;

&lt;p&gt;Building a tech career in the UK has taught me that consistency matters more than performance theatre.&lt;/p&gt;

&lt;p&gt;You do not need to pretend to be the loudest expert in the room. You need to keep improving your judgement, communicate clearly, and deliver work that makes the product stronger.&lt;/p&gt;

&lt;p&gt;That is the practical version of reinvention for me.&lt;/p&gt;

&lt;p&gt;I was not born with a way out, so I built one. But building a way out was not one heroic moment. It was a long sequence of learning, shipping, correcting, and getting better at the next decision.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;If you are trying to grow as a developer, do not underestimate the small decisions.&lt;/p&gt;

&lt;p&gt;A clearer type, a better error state, a more careful review, and a more honest conversation about product risk all count.&lt;/p&gt;

&lt;p&gt;Careers compound the same way systems do: through repeated decisions that either create trust or erode it.&lt;/p&gt;

&lt;p&gt;Make the next decision more trustworthy than the last one.&lt;/p&gt;

&lt;p&gt;— Rizwan Saleem&lt;br&gt;&lt;br&gt;
Lead Frontend Developer, AI/LLM practitioner, fintech/open banking engineer, software engineer, and startup founder&lt;br&gt;&lt;br&gt;
&lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>TypeScript and frontend forms: small details that build user trust | Rizwan Saleem</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 18:20:27 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/typescript-and-frontend-forms-small-details-that-build-user-trust-rizwan-saleem-4gnk</link>
      <guid>https://dev.to/therizwansaleem/typescript-and-frontend-forms-small-details-that-build-user-trust-rizwan-saleem-4gnk</guid>
      <description>&lt;h1&gt;
  
  
  TypeScript and frontend forms: small details that build user trust
&lt;/h1&gt;

&lt;p&gt;A form is one of the easiest parts of a product to underestimate. It can look simple in a design file: labels, inputs, validation, a submit button, and a confirmation state.&lt;/p&gt;

&lt;p&gt;In real product work, especially in fintech, open banking, onboarding, or account-related flows, a form often sits at the point where user trust is either strengthened or weakened.&lt;/p&gt;

&lt;p&gt;The frontend is not only collecting input. It is explaining the system.&lt;/p&gt;

&lt;h2&gt;
  
  
  Trust lives in the states around the form
&lt;/h2&gt;

&lt;p&gt;The happy path is only one part of the experience. A reliable form needs to handle the situations where real users actually feel uncertainty:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens if the API is slow?&lt;/li&gt;
&lt;li&gt;What if the user makes a mistake?&lt;/li&gt;
&lt;li&gt;What if the backend rejects a value the frontend allowed?&lt;/li&gt;
&lt;li&gt;What if a connection fails halfway through?&lt;/li&gt;
&lt;li&gt;What does the user see after submitting?&lt;/li&gt;
&lt;li&gt;Can they recover without losing confidence?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These questions are not decoration. They are part of product quality.&lt;/p&gt;

&lt;p&gt;In sensitive flows, unclear validation or vague error copy can make the product feel less trustworthy even when the underlying system is working correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  TypeScript helps, but it does not replace judgement
&lt;/h2&gt;

&lt;p&gt;TypeScript is valuable because it helps teams make data contracts explicit. A well-typed form flow can reduce avoidable mistakes around optional fields, response shapes, submit states, and error handling.&lt;/p&gt;

&lt;p&gt;But types only protect what the team has chosen to model.&lt;/p&gt;

&lt;p&gt;Frontend engineers still need to think about the user-facing experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Does the validation match the real backend rules?&lt;/li&gt;
&lt;li&gt;Are error states specific enough to be useful?&lt;/li&gt;
&lt;li&gt;Does the user know whether they can retry?&lt;/li&gt;
&lt;li&gt;Are loading states honest without being alarming?&lt;/li&gt;
&lt;li&gt;Are accessibility behaviours tested, not assumed?&lt;/li&gt;
&lt;li&gt;Does the interface avoid exposing unnecessary sensitive details?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is where engineering judgement matters.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI can support the review loop
&lt;/h2&gt;

&lt;p&gt;AI/LLM tools can help by generating edge cases, suggesting tests, reviewing TypeScript contracts, and checking whether a component only handles the happy path.&lt;/p&gt;

&lt;p&gt;A useful prompt is not just, “Build this form.”&lt;/p&gt;

&lt;p&gt;A better prompt is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Review this form flow for missing states, accessibility concerns, unclear validation, TypeScript weaknesses, and user recovery paths.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That kind of prompt uses AI to improve thinking, not replace responsibility.&lt;/p&gt;

&lt;p&gt;The engineer still has to decide what belongs in the product, what is safe, what is clear, and what is maintainable.&lt;/p&gt;

&lt;h2&gt;
  
  
  A practical frontend checklist
&lt;/h2&gt;

&lt;p&gt;Before shipping an important form, I like to check:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Are the TypeScript types aligned with the actual API contract?&lt;/li&gt;
&lt;li&gt;Are loading, success, empty, and error states all designed?&lt;/li&gt;
&lt;li&gt;Are validation messages useful and action-oriented?&lt;/li&gt;
&lt;li&gt;Can the user recover from common failures?&lt;/li&gt;
&lt;li&gt;Is keyboard navigation and screen-reader behaviour acceptable?&lt;/li&gt;
&lt;li&gt;Is sensitive information handled carefully in copy and UI states?&lt;/li&gt;
&lt;li&gt;Are AI-generated suggestions reviewed against the product context?&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Strong frontend work is not only about components, styling, or framework choices. It is about how the interface helps people understand what is happening.&lt;/p&gt;

&lt;p&gt;In products where trust matters, the small details around forms carry a lot of weight.&lt;/p&gt;

&lt;p&gt;Good TypeScript helps. Good React and Next.js patterns help. AI-assisted review can help.&lt;/p&gt;

&lt;p&gt;But the final standard is still human judgement: make the flow clear, resilient, accessible, and honest.&lt;/p&gt;




&lt;p&gt;Rizwan Saleem — &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Small Frontend Diffs Are Easier to Trust</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 18:10:27 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/small-frontend-diffs-are-easier-to-trust-571e</link>
      <guid>https://dev.to/therizwansaleem/small-frontend-diffs-are-easier-to-trust-571e</guid>
      <description>&lt;h3&gt;
  
  
  Small diffs make engineering judgement easier
&lt;/h3&gt;

&lt;p&gt;Frontend work is not just about making an interface appear on screen. It is where product intent, domain rules, accessibility, performance, and user trust meet.&lt;/p&gt;

&lt;p&gt;That is why the size and shape of a change matters.&lt;/p&gt;

&lt;p&gt;A large pull request may contain useful work, but if it combines UI behaviour, API assumptions, TypeScript model changes, styling, copy, and unrelated refactoring, it becomes harder to review properly. Reviewers start scanning instead of reasoning.&lt;/p&gt;

&lt;p&gt;Small diffs create a better environment for judgement.&lt;/p&gt;

&lt;h3&gt;
  
  
  What a reviewable frontend diff usually does
&lt;/h3&gt;

&lt;p&gt;A strong frontend change should make its reasoning visible. It should be clear:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;What user problem is being solved&lt;/strong&gt; — not just which component changed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which state transitions are affected&lt;/strong&gt; — loading, empty, error, retry, success, partial success, or timeout.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which TypeScript types changed&lt;/strong&gt; — and whether they describe the real domain rather than only satisfying the compiler.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which accessibility behaviours are protected&lt;/strong&gt; — focus, keyboard interaction, labels, and feedback.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Which assumptions are new&lt;/strong&gt; — especially around API data, permissions, identity, money, or sensitive information.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How safely the change can be rolled back&lt;/strong&gt; if the assumption proves wrong.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is useful in every product, but it becomes especially important in fintech and open banking flows, where small interface decisions can affect confidence quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI increases the need for disciplined review
&lt;/h3&gt;

&lt;p&gt;AI-assisted engineering can speed up implementation. It can suggest patterns, generate tests, explain unfamiliar code, and produce alternatives quickly.&lt;/p&gt;

&lt;p&gt;But generated speed can also create bigger, blurrier diffs.&lt;/p&gt;

&lt;p&gt;A good engineer still needs to break the work into understandable pieces, challenge the assumptions, and keep ownership of the final decision. AI can help pressure-test a change, but it cannot know the full product context or own the user impact.&lt;/p&gt;

&lt;h3&gt;
  
  
  A practical checklist before opening a frontend PR
&lt;/h3&gt;

&lt;p&gt;Before opening a pull request, I like to ask:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can this change be explained in one sentence?&lt;/li&gt;
&lt;li&gt;Is unrelated refactoring removed or separated?&lt;/li&gt;
&lt;li&gt;Are state changes visible and testable?&lt;/li&gt;
&lt;li&gt;Are accessibility and keyboard behaviour still intact?&lt;/li&gt;
&lt;li&gt;Are TypeScript types closer to the real domain?&lt;/li&gt;
&lt;li&gt;Is there one clear rollback path?&lt;/li&gt;
&lt;li&gt;Would another engineer understand the trade-off in a month?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the answer is no, the diff may need to be smaller.&lt;/p&gt;

&lt;h3&gt;
  
  
  Clarity compounds
&lt;/h3&gt;

&lt;p&gt;Small diffs are not about slowing teams down. They are about making progress easier to trust.&lt;/p&gt;

&lt;p&gt;The best frontend engineering cultures make decisions visible. They reduce hidden risk. They protect user confidence. They leave the codebase easier to work with than they found it.&lt;/p&gt;

&lt;p&gt;That is the kind of discipline that compounds over time.&lt;/p&gt;




&lt;p&gt;Rizwan Saleem — &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Frontend leadership means making uncertainty visible | Rizwan Saleem</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 18:00:27 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/frontend-leadership-means-making-uncertainty-visible-rizwan-saleem-5fib</link>
      <guid>https://dev.to/therizwansaleem/frontend-leadership-means-making-uncertainty-visible-rizwan-saleem-5fib</guid>
      <description>&lt;h1&gt;
  
  
  Frontend leadership means making uncertainty visible
&lt;/h1&gt;

&lt;p&gt;Frontend leadership is often described through delivery, architecture, reviews, mentoring, and component systems. Those things matter. But one of the most valuable leadership habits is quieter: making uncertainty visible early enough that the team can respond to it.&lt;/p&gt;

&lt;p&gt;Uncertainty is present in almost every product build. Requirements shift. APIs return unexpected shapes. Designs show the happy path more clearly than the failure path. Accessibility issues appear late. Performance costs hide inside small decisions. User trust depends on details that can be easy to miss.&lt;/p&gt;

&lt;p&gt;A strong frontend team does not eliminate uncertainty. It exposes it.&lt;/p&gt;

&lt;h2&gt;
  
  
  The happy path is not the full product
&lt;/h2&gt;

&lt;p&gt;A screen can look complete while still hiding important questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What happens when the request is slow?&lt;/li&gt;
&lt;li&gt;What should the empty state say?&lt;/li&gt;
&lt;li&gt;Can the user recover from this error?&lt;/li&gt;
&lt;li&gt;Does keyboard navigation work properly?&lt;/li&gt;
&lt;li&gt;Are form errors useful and calm?&lt;/li&gt;
&lt;li&gt;Is the TypeScript contract strict enough to protect the flow?&lt;/li&gt;
&lt;li&gt;What happens when content is longer than expected?&lt;/li&gt;
&lt;li&gt;Does the interface still make sense on a smaller screen?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are not minor polish tasks. They are part of the product experience.&lt;/p&gt;

&lt;p&gt;In frontend engineering, the user often experiences system quality through the interface. Loading states, validation, error messages, accessibility, and data handling become the visible edge of the wider architecture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Leadership is creating decision clarity
&lt;/h2&gt;

&lt;p&gt;Making uncertainty visible is not about slowing the team down. It is about reducing expensive surprises.&lt;/p&gt;

&lt;p&gt;A practical leadership approach is to ask better questions early:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What assumptions are we making?&lt;/li&gt;
&lt;li&gt;Which states are missing from the design or ticket?&lt;/li&gt;
&lt;li&gt;What can fail, and how should the product respond?&lt;/li&gt;
&lt;li&gt;What should be typed, tested, or documented before the work spreads?&lt;/li&gt;
&lt;li&gt;Where do we need a product decision rather than an engineering guess?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That last point matters. Some uncertainty is technical. Some is product-level. A frontend leader should know the difference.&lt;/p&gt;

&lt;h2&gt;
  
  
  AI can help, but judgement still belongs to the engineer
&lt;/h2&gt;

&lt;p&gt;AI/LLM tools are useful for surfacing edge cases, reviewing TypeScript types, suggesting test scenarios, comparing implementation options, and challenging assumptions. Used well, they can make the thinking loop faster.&lt;/p&gt;

&lt;p&gt;But AI does not own the product outcome.&lt;/p&gt;

&lt;p&gt;The engineering responsibility remains human: decide what is appropriate for the product, the user, the system, and the team. Generated suggestions still need review against accessibility, performance, privacy, reliability, and maintainability.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple practice for frontend teams
&lt;/h2&gt;

&lt;p&gt;Before a frontend feature is considered ready, ask the team to capture three things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the known happy path&lt;/li&gt;
&lt;li&gt;the known failure paths&lt;/li&gt;
&lt;li&gt;the unresolved assumptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This small habit can improve reviews, reduce rework, and make collaboration with product, design, backend, and QA more honest.&lt;/p&gt;

&lt;p&gt;It also creates better engineering culture. People are less likely to hide uncertainty when leaders treat it as useful information rather than weakness.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Frontend leadership is not only about writing clean components or choosing the right framework. It is about helping teams make better product decisions at the point where technical detail meets user experience.&lt;/p&gt;

&lt;p&gt;Make uncertainty visible early.&lt;/p&gt;

&lt;p&gt;Name the assumptions. Check the edge cases. Strengthen the contracts. Keep the judgement human.&lt;/p&gt;

&lt;p&gt;That is how frontend work becomes more reliable, more trustworthy, and easier to lead.&lt;/p&gt;




&lt;p&gt;Rizwan Saleem — &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>A practical AI-assisted engineering checklist for frontend developers | Rizwan Saleem</title>
      <dc:creator>Rizwan Saleem</dc:creator>
      <pubDate>Fri, 29 May 2026 17:50:28 +0000</pubDate>
      <link>https://dev.to/therizwansaleem/a-practical-ai-assisted-engineering-checklist-for-frontend-developers-rizwan-saleem-1gbf</link>
      <guid>https://dev.to/therizwansaleem/a-practical-ai-assisted-engineering-checklist-for-frontend-developers-rizwan-saleem-1gbf</guid>
      <description>&lt;h3&gt;
  
  
  A practical AI-assisted engineering checklist for frontend developers
&lt;/h3&gt;

&lt;p&gt;AI tools are now part of the everyday software workflow for many developers. They can help with scaffolding, debugging, explanation, refactoring, test ideas, documentation, and fast exploration. Used well, they compress the time between question and insight.&lt;/p&gt;

&lt;p&gt;But speed is not the same thing as quality.&lt;/p&gt;

&lt;p&gt;For frontend developers, this distinction matters because our work sits directly between product logic and human experience. A component is rarely just a component. It may carry accessibility decisions, loading states, validation rules, performance trade-offs, analytics events, error handling, security assumptions, and user trust.&lt;/p&gt;

&lt;p&gt;That is why I think AI-assisted engineering needs a disciplined checklist.&lt;/p&gt;

&lt;h4&gt;
  
  
  1. Understand the problem before asking for code
&lt;/h4&gt;

&lt;p&gt;If the prompt starts before the thinking starts, the output will usually be shallow. Before asking an AI tool to generate a solution, define the user problem, the technical constraint, and the quality bar.&lt;/p&gt;

&lt;p&gt;A better prompt often starts with context rather than command: what the component is for, who uses it, what can go wrong, and what stack constraints exist.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Ask for trade-offs, not only answers
&lt;/h4&gt;

&lt;p&gt;A code answer can look correct while hiding weak assumptions. Asking for trade-offs forces the tool to surface alternatives: client vs server rendering, controlled vs uncontrolled state, optimistic updates vs explicit confirmation, library vs custom implementation.&lt;/p&gt;

&lt;p&gt;The value is not only the final snippet. The value is the comparison.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Review generated code like it came from a junior teammate
&lt;/h4&gt;

&lt;p&gt;Generated code deserves a real review. Naming, types, state boundaries, dependencies, accessibility attributes, loading states, testability, and failure paths all need human inspection.&lt;/p&gt;

&lt;p&gt;This is not cynicism. It is engineering ownership.&lt;/p&gt;

&lt;h4&gt;
  
  
  4. Check product-facing details yourself
&lt;/h4&gt;

&lt;p&gt;AI is often good at the happy path and weaker at the lived product path. Frontend quality depends on details such as empty states, long text, keyboard navigation, responsive behaviour, slow networks, API errors, and partially completed forms.&lt;/p&gt;

&lt;p&gt;Those details are where users feel the quality of the product.&lt;/p&gt;

&lt;h4&gt;
  
  
  5. Refactor until the solution fits the system
&lt;/h4&gt;

&lt;p&gt;A generated solution may solve the isolated prompt but still not fit the codebase. The real work is shaping it into the existing architecture, design system, naming conventions, test patterns, and performance expectations.&lt;/p&gt;

&lt;p&gt;Good developers do not just paste. They integrate.&lt;/p&gt;

&lt;h4&gt;
  
  
  6. Keep learning the underlying technology
&lt;/h4&gt;

&lt;p&gt;The strongest AI-assisted developers are not the ones who know the least. They are usually the ones who can judge the output because they understand the fundamentals.&lt;/p&gt;

&lt;p&gt;React, Next.js, TypeScript, accessibility, browser behaviour, APIs, and product thinking still matter. AI increases leverage, but leverage without judgement increases risk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;AI can make software engineers faster, but speed only becomes valuable when it is paired with responsibility. My own rule is simple: use AI to accelerate the work, but keep responsibility for the outcome.&lt;/p&gt;

&lt;p&gt;You do not need a perfect beginning to build serious technical skill. You need curiosity, discipline, ethics, and the courage to keep learning when no one is clapping yet.&lt;/p&gt;




&lt;p&gt;Rizwan Saleem — &lt;a href="https://rizwansaleem.co" rel="noopener noreferrer"&gt;https://rizwansaleem.co&lt;/a&gt;&lt;/p&gt;

</description>
      <category>frontend</category>
      <category>ai</category>
      <category>typescript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
