<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tim Santeford</title>
    <link>https://www.timsanteford.com/</link>
    <description>Practical software engineering guides about TypeScript, cloud infrastructure, databases, developer tooling, and lessons learned.</description>
    <language>en-US</language>
    <atom:link href="https://www.timsanteford.com/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Solving the “git-lfs Not Found” Error: How I Fixed Git LFS Issues in My Project</title>
      <link>https://www.timsanteford.com/posts/solving-the-git-lfs-not-found-error-how-i-fixed-git-lfs-issues-in-my-project/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/solving-the-git-lfs-not-found-error-how-i-fixed-git-lfs-issues-in-my-project/</guid>
      <pubDate>Tue, 27 May 2025 16:21:34 GMT</pubDate>
      <description>When I encountered the error message, “This repository is configured for Git LFS but ‘git-lfs’ was not found on your path,” I realized it was time to set up my environment for Git Large File Storage (LFS). For anyone working with large files or collaborating on repositories that use LFS, this error is an important</description>
      <category>Error Fixes</category>
    </item>
    <item>
      <title>Log Record Counts in PySpark (With a Timer)</title>
      <link>https://www.timsanteford.com/posts/log-record-counts-in-pyspark-with-a-timer/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/log-record-counts-in-pyspark-with-a-timer/</guid>
      <pubDate>Sat, 29 Mar 2025 02:40:05 GMT</pubDate>
      <description>When I’m working with large datasets in PySpark, I often need to know how many records are flowing through my transformations. It’s a simple thing, but being able to log that information at the right time can help me catch issues early—like unexpected filters wiping out rows or joins ballooning in size. What makes it</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Balancing Git Commit Quantity and Quality</title>
      <link>https://www.timsanteford.com/posts/balancing-commit-quantity-and-quality-a-developers-perspective/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/balancing-commit-quantity-and-quality-a-developers-perspective/</guid>
      <pubDate>Thu, 27 Mar 2025 04:19:40 GMT</pubDate>
      <description>Commit Quantity vs Quality Balancing commit quantity and quality is a common challenge for software engineers. While some emphasize frequent, incremental commits, others advocate for single, clean commits that ensure a pristine history. In this post, I’ll share my personal approach to navigating this balance, lessons from past experiences, and tips for fostering a team</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Day One: Starting Strong as a New Software Engineer</title>
      <link>https://www.timsanteford.com/posts/day-one-starting-strong-as-a-new-software-engineer/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/day-one-starting-strong-as-a-new-software-engineer/</guid>
      <pubDate>Tue, 25 Mar 2025 04:07:04 GMT</pubDate>
      <description>Welcome to your first day as a software engineer! Whether you’re joining your first tech company or transitioning into a new role, the beginning can feel like a mix of excitement, nerves, and information overload. But don’t worry—there are a few key things you can do on Day One to set the tone for success</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Fixing PySpark Import Errors When Using Custom Modules</title>
      <link>https://www.timsanteford.com/posts/fixing-pyspark-import-errors-when-using-custom-modules/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/fixing-pyspark-import-errors-when-using-custom-modules/</guid>
      <pubDate>Mon, 17 Mar 2025 22:31:18 GMT</pubDate>
      <description>Encountering a ModuleNotFoundError while running a PySpark job can be frustrating, especially when the module exists and works perfectly outside of Spark. I recently ran into this exact issue while working with a Spark job that imported a function from a local utils module. Everything seemed fine until I tried to use a PySpark UDF,</description>
      <category>Error Fixes</category>
    </item>
    <item>
      <title>Running Development Mode in Multiple NPM Workspaces</title>
      <link>https://www.timsanteford.com/posts/running-development-mode-in-multiple-npm-workspaces/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/running-development-mode-in-multiple-npm-workspaces/</guid>
      <pubDate>Sat, 15 Mar 2025 02:10:03 GMT</pubDate>
      <description>When working on a monorepo with multiple packages, getting everything up and running efficiently can be a challenge. I’ve been there—jumping between terminal windows, manually starting different services, and hoping I didn’t forget anything. Fortunately, NPM workspaces provide a great way to manage multiple packages in a single repository, and with the right setup, starting</description>
      <category>Comparisons</category>
    </item>
    <item>
      <title>Building a React File Upload Button to Parse JSON and YAML</title>
      <link>https://www.timsanteford.com/posts/building-a-react-file-upload-button-to-parse-json-and-yaml/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/building-a-react-file-upload-button-to-parse-json-and-yaml/</guid>
      <pubDate>Thu, 13 Mar 2025 00:33:23 GMT</pubDate>
      <description>Handling file uploads in a React app is straightforward, but things get more interesting when you need to filter for specific file types and parse their contents. I needed to create an upload button that only accepted JSON and YAML files, then read and displayed their contents in the browser. Here’s how I did it.</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Full Height Display in Storybook Preview</title>
      <link>https://www.timsanteford.com/posts/making-the-storybook-preview-full-height/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/making-the-storybook-preview-full-height/</guid>
      <pubDate>Tue, 11 Mar 2025 14:04:40 GMT</pubDate>
      <description>When working with Storybook, I wanted my component previews to take up the entire viewport height. But by default, the preview area doesn’t always stretch to fit the full screen. After trying a few different approaches, I found the simplest and most reliable way to achieve this. Here’s how to make sure your Storybook preview</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Adding Adaptive Cards to a React App with Markdown Support</title>
      <link>https://www.timsanteford.com/posts/adding-adaptive-cards-to-a-react-app-with-markdown-support/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/adding-adaptive-cards-to-a-react-app-with-markdown-support/</guid>
      <pubDate>Sun, 09 Mar 2025 13:44:49 GMT</pubDate>
      <description>When I started working with Adaptive Cards in a React app, I wanted a way to dynamically load and style cards while keeping them flexible. Adaptive Cards provide a powerful way to render dynamic UI elements using JSON, but by default, their Markdown support is somewhat limited. To improve this, I decided to integrate markdown-it,</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Fixing the the inferred type of ‘meta’ cannot be named error in Storybook</title>
      <link>https://www.timsanteford.com/posts/fixing-the-the-inferred-type-of-meta-cannot-be-named-rrror-in-storybook/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/fixing-the-the-inferred-type-of-meta-cannot-be-named-rrror-in-storybook/</guid>
      <pubDate>Fri, 07 Mar 2025 23:16:45 GMT</pubDate>
      <description>When I first encountered the “The inferred type of ‘meta’ cannot be named without a reference to…” message in Storybook, I was caught off guard. I wanted a quick solution that would keep my TypeScript checks happy and my Storybook setup running smoothly. After a bit of trial and error, I discovered a simple fix</description>
      <category>Error Fixes</category>
    </item>
    <item>
      <title>Solving Cannot Find CSS Module Errors in Typescript</title>
      <link>https://www.timsanteford.com/posts/solving-cannot-find-css-module-errors-in-typescript/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/solving-cannot-find-css-module-errors-in-typescript/</guid>
      <pubDate>Wed, 05 Mar 2025 21:28:42 GMT</pubDate>
      <description>I remember feeling puzzled the first time my TypeScript compiler complained about an imported .module.css file in my React code. Everything worked at runtime, but VSCode kept throwing red squiggles. To avoid confusion, I decided to create a quick fix that put an end to these errors. Cannot find module ‘./MyComponent.module.css’ or its corresponding type</description>
      <category>Error Fixes</category>
    </item>
    <item>
      <title>Tackling the useNavigate Error in Storybook</title>
      <link>https://www.timsanteford.com/posts/tackling-the-usenavigate-error-in-storybook/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/tackling-the-usenavigate-error-in-storybook/</guid>
      <pubDate>Mon, 03 Mar 2025 21:10:50 GMT</pubDate>
      <description>I recently ran into an error in my Storybook environment that read: useNavigate() may be used only in the context of a component. It took me a moment to understand why this was happening, and I want to share how I solved it. Error: useNavigate() may be used only in the context of a component.</description>
      <category>Error Fixes</category>
    </item>
    <item>
      <title>Managing Event Hub Data: Effective Strategies for Clearing Messages</title>
      <link>https://www.timsanteford.com/posts/managing-event-hub-data-effective-strategies-for-clearing-messages/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/managing-event-hub-data-effective-strategies-for-clearing-messages/</guid>
      <pubDate>Sat, 01 Mar 2025 20:16:16 GMT</pubDate>
      <description>Azure Event Hubs are designed as an immutable, append-only store for events. Once events are ingested, they remain available until the retention period expires. This approach is ideal for high-throughput and reliable streaming, but it also means that individual message deletion is not supported. Instead, the available options focus on managing data lifecycle through retention</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Set Up Auto-Updating Swagger Documentation with Express</title>
      <link>https://www.timsanteford.com/posts/set-up-auto-updating-swagger-documentation-with-express/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/set-up-auto-updating-swagger-documentation-with-express/</guid>
      <pubDate>Sat, 01 Mar 2025 00:04:48 GMT</pubDate>
      <description>I’ve always believed that maintaining up-to-date API documentation is crucial for building reliable software. In my latest project, I wanted to integrate Swagger UI into my Express server, but with a twist—I needed the documentation to update automatically whenever I made changes to my API routes. After some research and experimentation, I discovered a workflow</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Managing Mutation Status with React Query</title>
      <link>https://www.timsanteford.com/posts/managing-mutation-status-with-react-query/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/managing-mutation-status-with-react-query/</guid>
      <pubDate>Thu, 27 Feb 2025 17:44:01 GMT</pubDate>
      <description>As I work with React Query, I often find myself needing to manage the status of mutations to ensure a seamless user experience. This involves disabling fields and buttons while data is being updated or created, preventing users from triggering multiple requests simultaneously. In this post, I’ll share how I handle mutation status using React</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Next-Level User Engagement: Adding Voice Input to Your React App</title>
      <link>https://www.timsanteford.com/posts/adding-voice-input-to-your-react-app/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/adding-voice-input-to-your-react-app/</guid>
      <pubDate>Tue, 25 Feb 2025 04:04:26 GMT</pubDate>
      <description>As I began working on my latest React project, I realized the importance of incorporating voice input to enhance user experience. This feature allows users to interact with the app using voice commands, which can be particularly useful for accessibility and convenience. In this post, I’ll walk you through how I implemented voice input in</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Checking for App Updates and Releases in React</title>
      <link>https://www.timsanteford.com/posts/checking-for-app-updates-and-releases-in-react/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/checking-for-app-updates-and-releases-in-react/</guid>
      <pubDate>Sat, 22 Feb 2025 16:48:57 GMT</pubDate>
      <description>Keeping Your React App Up-to-Date: A Step-by-Step Approach As a developer, one of the challenges I’ve faced is ensuring that users of my React application always interact with the latest version. This becomes particularly important when users keep a tab open to the site for days or even weeks. During this time, if updates are</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Real-Time vs. Batch Processing: When to Use Apache Flink and Apache Spark</title>
      <link>https://www.timsanteford.com/posts/real-time-vs-batch-processing-when-to-use-apache-flink-and-apache-spark/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/real-time-vs-batch-processing-when-to-use-apache-flink-and-apache-spark/</guid>
      <pubDate>Thu, 20 Feb 2025 14:34:46 GMT</pubDate>
      <description>Apache Spark and Apache Flink are two of the most popular open-source frameworks for large-scale data processing. While both are designed to handle big data workloads, they have distinct architectures, processing models, and use cases. Here’s a comprehensive comparison to help you understand their differences: 1. Processing Paradigm 2. Latency and Throughput 3. Fault Tolerance</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Simplifying Inheritance Hierarchies in Python with super()</title>
      <link>https://www.timsanteford.com/posts/how-i-use-super-in-python-to-simplify-my-inheritance-hierarchies/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/how-i-use-super-in-python-to-simplify-my-inheritance-hierarchies/</guid>
      <pubDate>Tue, 18 Feb 2025 14:30:52 GMT</pubDate>
      <description>I’ve spent a lot of time refining my Python code, and one technique that has greatly improved my projects is the use of the built-in super() function. In my early days, I used to hardcode parent class names when calling inherited methods. Over time, I realized that super() not only simplifies the code but also</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Apache Flink Map vs FlatMap Transformations</title>
      <link>https://www.timsanteford.com/posts/apache-flink-map-vs-flatmap-transformations/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/apache-flink-map-vs-flatmap-transformations/</guid>
      <pubDate>Sun, 16 Feb 2025 08:50:37 GMT</pubDate>
      <description>I’ve been working with Apache Flink for some time now, and I often find myself deciding between using the map or the flatMap operators. Recently, I encountered a scenario where choosing the right transformation became crucial for my data pipeline. Here’s a quick comparison I rely on when making that decision: • map - Purpose: Applies</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Redirection to 404 Pages with React Query and React Router</title>
      <link>https://www.timsanteford.com/posts/redirection-to-404-pages-with-react-query-and-react-router/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/redirection-to-404-pages-with-react-query-and-react-router/</guid>
      <pubDate>Fri, 14 Feb 2025 08:40:54 GMT</pubDate>
      <description>I remember the first time I worked on an application that needed custom 404 handling. I kept thinking, “There must be an elegant way to catch these errors and redirect the user to a stylish ‘Not Found’ page.” As it turns out, React Query and React Router together make this process feel quite intuitive, and</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Waveform Widget Customization: Building a YouTube Subscriptions Widget in Waveterm</title>
      <link>https://www.timsanteford.com/posts/waveform-widget-customization-building-a-youtube-subscriptions-widget-in-waveterm/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/waveform-widget-customization-building-a-youtube-subscriptions-widget-in-waveterm/</guid>
      <pubDate>Wed, 12 Feb 2025 18:47:29 GMT</pubDate>
      <description>I’ve recently discovered how flexible Waveterm can be when it comes to customizing my terminal experience. One feature that truly caught my attention was the ability to create waveform widgets. In this post, I’ll walk you through the process of building a YouTube subscriptions widget by editing a JSON configuration file. I’ll explain each step</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Downloading YouTube Transcripts in Python</title>
      <link>https://www.timsanteford.com/posts/downloading-youtube-transcripts-in-python-a-practical-approach/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/downloading-youtube-transcripts-in-python-a-practical-approach/</guid>
      <pubDate>Mon, 10 Feb 2025 04:17:59 GMT</pubDate>
      <description>I recently needed a reliable way to download transcripts from YouTube videos using Python. I was looking for a straightforward solution that wouldn’t require a complex setup or extensive third-party libraries. After exploring a few options, I decided to share my experience with a simple Python script that leverages the youtube-transcript-api package. In this post,</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Analyzing URLs to Determine Media Formats</title>
      <link>https://www.timsanteford.com/posts/determining-media-types-from-urls/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/determining-media-types-from-urls/</guid>
      <pubDate>Sat, 08 Feb 2025 02:48:41 GMT</pubDate>
      <description>As a developer, I often encounter scenarios where I need to determine the type of media a URL points to before rendering it in my application. This could be crucial for optimizing user experience, ensuring compatibility, or simply for organizing content effectively. In this post, I’ll walk you through different methods I use to achieve</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Efficiently Scrubbing Sensitive Information in Python with Regex</title>
      <link>https://www.timsanteford.com/posts/efficiently-scrubbing-sensitive-information-in-python-with-regex/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/efficiently-scrubbing-sensitive-information-in-python-with-regex/</guid>
      <pubDate>Thu, 06 Feb 2025 23:15:48 GMT</pubDate>
      <description>Handling sensitive information is a critical aspect of software development, especially when dealing with user data. Whether it’s masking Social Security Numbers (SSNs), email addresses, or URLs, ensuring that this data is appropriately scrubbed is essential for maintaining privacy and security. In this post, I’ll share my experience creating a Python function that efficiently scrubs</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Optimizing Flink Kafka Offsets Configuration for Seamless Data Streaming</title>
      <link>https://www.timsanteford.com/posts/optimizing-flink-kafka-offsets-configuration-for-seamless-data-streaming/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/optimizing-flink-kafka-offsets-configuration-for-seamless-data-streaming/</guid>
      <pubDate>Tue, 04 Feb 2025 14:17:00 GMT</pubDate>
      <description>Flink’s Kafka integration can be an excellent choice for building near real-time data pipelines. Offsets are at the center of these pipelines, governing exactly where Flink should begin reading data and how it responds to any missing or invalid positions. By combining Flink’s offset initializers with Kafka’s own offset resets, you can create robust and</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Turn a Website into a Secure Android App with Jetpack Compose and Kotlin</title>
      <link>https://www.timsanteford.com/posts/turn-a-website-into-a-secure-android-app-with-jetpack-compose-and-kotlin/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/turn-a-website-into-a-secure-android-app-with-jetpack-compose-and-kotlin/</guid>
      <pubDate>Sun, 02 Feb 2025 05:43:14 GMT</pubDate>
      <description>If you’ve ever wanted to turn a website into an Android app, Jetpack Compose and Kotlin make it surprisingly straightforward. With a few lines of code, you can have a functional app that displays your website. However, when it comes to embedding websites, security should always be a top priority. In this post, I’ll walk</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>Automatically Rerun Pytest Tests on File Save</title>
      <link>https://www.timsanteford.com/posts/automatically-rerun-pytest-tests-on-file-save/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/automatically-rerun-pytest-tests-on-file-save/</guid>
      <pubDate>Fri, 31 Jan 2025 14:16:35 GMT</pubDate>
      <description>Automating tests is a crucial part of any development workflow, ensuring that your code remains reliable and free of regressions. In my journey as a developer, I’ve often found the need to rerun tests automatically whenever I make changes to my files. This not only saves time but also provides immediate feedback, allowing me to</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>MSVCRT on macOS with a Practical Workaround: Getch</title>
      <link>https://www.timsanteford.com/posts/msvcrt-on-macos-with-a-practical-workaround-getch/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/msvcrt-on-macos-with-a-practical-workaround-getch/</guid>
      <pubDate>Wed, 29 Jan 2025 17:30:08 GMT</pubDate>
      <description>I knew from the start that Microsoft’s Visual C Runtime Library (MSVCRT) would not be natively available on macOS, so I wasn’t surprised when I realized it wouldn’t install. Because I don’t often rely on MSVCRT, it didn’t feel like a critical loss—until a coworker asked me to make a shared Python script run smoothly</description>
      <category>How To Guides</category>
    </item>
    <item>
      <title>How I Turned Terminal Output into Clickable Links</title>
      <link>https://www.timsanteford.com/posts/how-i-turned-terminal-output-into-clickable-links/</link>
      <guid isPermaLink="true">https://www.timsanteford.com/posts/how-i-turned-terminal-output-into-clickable-links/</guid>
      <pubDate>Mon, 27 Jan 2025 04:33:17 GMT</pubDate>
      <description>I regularly write scripts that produce various links to logs and related assets. Over time, I grew tired of copying and pasting these URLs into my browser. Eventually, I wondered if I could make them clickable directly in the terminal. First, I tried the usual link syntax but discovered that most terminals ignore Markdown formatting.</description>
      <category>How To Guides</category>
    </item>
  </channel>
</rss>
