Writing Cross-Platform Hooks for AI Coding Agents
This post was published on
How to write a single hook script that works across Claude Code and Cursor, giving you deterministic control over agent behaviour when it matters most.
My writing on this website will span many different topics, ranging from web standards, tutorials, mental health, thoughts and ideas, and general musings. While the bulk of my writing will be technical in nature it will vary from long form to short form and sometimes include video and audio. Some content will be beginner-friendly, while other pieces will be geared towards those who have been building for the web for some time.
On the last point, please note that I might occasionally misjudge the experience level required for certain content. If you find something where you believe I've got it wrong, please let me know on GitHub, and I would be happy to correct it.
To help you find the content you're interested in, I offer different ways to browse my writing. Below, you'll find a list of tags to filter content by topic. Additionally, all my writing is listed chronologically, allowing you to scroll through or use your browser's find-in-page functionality to locate something specific.
As with most things, this website will evolve and improve over time based on the time I have to work on it and your feedback and suggestions.
One of the first features I want to add is the ability to search for content across the blog. I believe a well-implemented search feature is one of the most powerful navigational tools, enhancing usability and accessibility. I plan to experiment with different implementations, and once available, I would appreciate your feedback on the search results to ensure the best possible experience.
I hope you find value in the writing you discover here.
This post was published on
How to write a single hook script that works across Claude Code and Cursor, giving you deterministic control over agent behaviour when it matters most.
This post was published on
Working code isn't understood code. When AI-generated code feels hard to parse, that's a signal to ask questions, and sometimes, the answer leads to something better.
This post was published on
Take a fieldset, pour some radio buttons and visually hidden labels into it, wrap it in scroll-snap, and you have a clean, semantic horizontal scroller on mobile. What could go wrong? Well... there is nuance we need to talk about.
This post was published on
A practical walkthrough for when you realise your feature branch was created from the wrong base, covering git log, merge parents, cherry-pick, and bypassing commit hooks.
This post was published on
Manage anchor relationships with anchor-scope, leverage the Popover API's implicit anchors, and hide positioned elements gracefully with position-visibility.
This post was published on
A deep dive into the JavaScript concepts behind mocking HTMLImageElement behaviour in Vitest, including Object.defineProperty, Object.getOwnPropertyDescriptor, prototype manipulation, and WeakMap for per-instance state tracking.
This post was published on
How to structure an AI agent session with sequential tasks, review checkpoints, and explicit deliverables—turning a handoff document into actionable state machines, gap reports, and implementation plans.
This post was published on
How to structure a self-contained folder of specifications, screenshots, and Figma links that an AI agent can reference throughout an implementation planning session.
This post was published on
How to structure a handoff document that enables AI agents to perform gap analysis and implementation planning—with traceable acceptance criteria, UI state inventories, and explicit business logic.
This post was published on
Learn how to safely select DOM elements with special characters in their IDs or classes using CSS.escape() to avoid selector parsing errors.
This post was published on
Learn how to programmatically require the presence of a modifier key to enable scroll wheel zoom support in Leaflet maps.
This post was published on
How to use TypeScript’s triple-slash reference directives to load type definitions when type-checking JavaScript with JSDoc.
This post was published on
Learn how to use Node.js util.parseArgs() to simplify command-line argument parsing in your Node.js CLI utilities.
This post was published on
How to use deferred promises to control mock response timing in Playwright tests and avoid race conditions with instant responses.
This post was published on
AI coding agents have made me significantly more productive as an engineer, but they have a systematic problem: as context fills, they drift from explicit guidance and violate documented patterns. This examines AI limitations and the workflow adaptations that help while labs address the underlying issues.
This post was published on
Combining Zod's runtime validation with JSDoc's type annotations to achieve type safety in JavaScript without TypeScript.
This post was published on
Export your Algolia search indices to JSON without building custom export scripts using the Algolia CLI.
This post was published on
Build resilient anchor-positioned layouts that adapt when space runs out.
This post was published on
What I learned reviewing AI-generated JavaScript: real-world issues, code review tips, and ways to ensure robust, production-ready code.
This post was published on
Learn how to use the new CSS ::details-content pseudo-element to style the content area of HTML details elements with greater control and flexibility.
This post was published on
Exploring common misconceptions AI agents have about Visual Regression Testing and practical solutions to address them.
This post was published on
Take your anchor positioning beyond the grid with functions that give you pixel-level control over placement and sizing.
This post was published on
Discover how CSS anchor positioning brings native support for positioning elements relative to each other — no JavaScript required.
This post was published on
Learn how to use HTML invoker commands to open and close dialogs without writing any JavaScript.
This post was published on
What if we embraced authenticity, take creative risks, and live deliberately without fear of judgment - a reflection on finding freedom through self-acceptance in both personal and technical pursuits.
This post was published on
A deep dive into the CSS transform matrix, how it relates to the individual CSS transform properties, a look at the hidden powers of the function forms, and a dragon or two.
This post was published on
In this part, we will add a form to our profile page, use a dialog to display our form, deploy our page using Netlify, and set up Netlify to handle form submissions.
This post was published on
Harness the power of open source and an innovative culture to drive creativity and collaboration within your team—inspired by Mozilla, GitHub, OddBird, Igalia, and Factorial.
This post was published on
In part five of the series, we will complete our layout, add a favicon, and set up Open Graph meta tags for social sharing.
This post was published on
Learn about WCAG (Web Content Accessibility Guidelines), including WCAG 2.2 principles, conformance levels, and upcoming WCAG 3 changes, plus insights on accessibility certification value.
This post was published on
Learn how to use the HTML dialog element to create accessible modal dialogs for your web sites and applications.
This post was published on
Join me on my journey as I prepare for the IAAP Web Accessibility Specialist (WAS) certification, sharing weekly insights, resources, and study plans.
This post was published on
In part four of the series, we will do some refactoring of our CSS so that we take advantage of CSS custom properties. We will also complete the mobile layout by adding the LinkTree component to our page.
This post was published on
Learn how to build a responsive profile page with modern typography, media queries, and CSS Grid. Part three of our hands-on web development tutorial series.
This post was published on
Learn how to build a responsive profile page with modern typography, media queries, and CSS Grid. Part three of our hands-on web development tutorial series.
This post was published on
The financial pressures of modern life can make it hard to justify creative pursuits that don't promise immediate returns. This post explores the hidden costs of creativity in tech and society and the value of creative work beyond monetary gain.
This post was published on
In this post we will start implementing the design by working through some of the issues, learning more about Git and GitHub, get set up for development, create our first visual component, and learn about performance, CSS, and modern image formats.
This post was published on
In this part of the series we will break down the design into components using Atomic Design, set up our repository on GitHub, and create the issues we will need to work on.
This post was published on
Meet Project Calavera, a new open-source CLI tool that makes project configuration setup a breeze, especially for developers working outside the familiar framework ecosystems.
This post was published on
Learn how to use npm link to test your NPM packages locally before publishing to the registry. With some common troubleshooting tips and best practices.
This post was published on
This personal reflection explores how AI chatbots can support emotional growth and self-discovery, offering insights on using AI as a thoughtful companion while acknowledging its limitations compared to human connection and professional therapy.
This post was published on
Introducing Minimalist, a modern, lightweight, and customizable CSS library designed to provide a solid foundation for styling websites and web applications. Learn about its key features, technical details, and how you can get involved.
This post was published on
Unlock simpler web development with CSS's new individual transform properties—cleaner syntax, more intuitive styling, and delightful animations.
This post was published on
Learn how explicit return types in TypeScript can help you catch potential bugs early, improve code reliability, and create more predictable and maintainable TypeScript applications.
This post was published on
My takeaways from Zach Leatherman's talk on web components at the 2023 JSHeroes conference.
This post was published on
Why you should be careful copying and pasting proposed solutions from LLMs.
This post was published on
Perhaps it is the social bubble I find myself in, but it seems there is a lot of talk about gatekeeping happening at the moment. While the bubble metaphor does not quite work for what will follow, I do not have a better one, so humor me.
This post was published on
Git rebase is a powerful tool that allows developers to reorganize and clean up their commit history, such as by squashing or fixup-ing multiple commits into a single commit, which can be useful when submitting pull requests.
This post was published on
In late December of 2023, TPGi posted its list of the top accessibility errors found through its ARC automation tools in 2023. In this post I explain these errors and offer a solution.
This post was published on
While this post does not by any means aim to cover all the amazing things you can do with Intl.NumberFormat, I do cover two very common use cases you may have faced when formatting numbers in JavaScript.
This post was published on
In this post, I share 21 pieces of unsolicited advice for junior web developers. I emphasize the challenges of learning web development, encourage collaboration, and highlight the importance of web accessibility. Additionally, I discuss bootcamps, university degrees, and the value of learning to code.
This post was published on
In this post, I discuss why I care deeply about web accessibility, emphasizing its importance in ensuring equal access for people with disabilities and removing barriers to interaction with websites and applications.
This post was published on
In this post I share how open source empowers me as a developer, fosters community collaboration, and provides a platform for making a meaningful impact. Being part of the open source community is the best way for anyone new to the technology industry to gain experience and contribute to cool projects.
This post was published on
Sensible defaults for your Open Source project and community.
This post was published on
The topic of Polyfill.io and its sale came across my radar about a week ago when Tobie Langel shared a link to LinkedIn on the OpenJS Foundation Slack.
This post was published on
How do I handle type inference challenges with v-for in Vue 3 templates using TypeScript? Let's find out more.
This post was published on
A quick post on best practices when installing Nodejs on different platforms and managing multiple versions.
This post was published on
How do I merge one repository into another without losing commit history? This is a quick guide on how to do this.
This post was published on
A step by step guide to publishing a simple CLI tool to the NPM registry.
This post was published on
This post will look at starting a new Vue project using the Vite toolchain.
This post was published on
Using the Nodejs EventEmitter with GitHub webhooks
This post was published on
Learn how to filter documents in a MongoDB collection by the size of an array field.
This post was published on
An introduction to Flexsearch and its tokenizers through writing and interpreting tests.
This post was published on
When running your Playwright tests, how do you load a different set of data based on the current execution environment?
This post was published on
How to cancel asynchronous operations with the AbortController API.
This post was published on
Usng the special Vuejs is attribute to fix common DOM parsing caveats.
This post was published on
There are a couple of steps to take when switching from the older babel-eslint to the newer @babel-eslint. No worries, I'll show you how.
This post was published on
Let’s work through the process of improving a basic GitHub Action CI workflow to cover multiple Node.js versions and operating systems.
This post was published on
How do you style the cursor in CodeMirror 5? Also, how can you do this for light and dark themes? Let's take a look.
This post was published on
Could it be that the == operator in JavaScript had a bad rap and it’s time to reconsider it?
This post was published on
It’s October, which means pumpkins, candy, costumes, and Hacktoberfest. If you are completely new to open source and contributing on Github, but want to join in the fun, read on.
This post was published on
Some thoughts on the current state and challenges with regards to building a PWA in 2021.
This post was published on
Ok so, this is very different from what I usually post. It is also, hands down, the hardest post I have ever written. But, there is no point in keeping this to myself. No achievement is unlocked by suffering in silence. No medal for pretending everything is A-OK.