Haz

Haz

@haz.dev

Co-founder @ariakit.com. Ex Automattic, WordPress. Posts about Design, JS, CSS, a11y. Neurodivergent, dad.

3.1K followers239 following993 posts

I've been working on these Table of Contents styles for a while. I'll add them to Ariakit Recipes soon. What do you think?

Sneak peek of a text field recipe I'm building for Ariakit. ‣ Supports slots before and after the input, including interactive ones like a select button. ‣ Adapts to any background color while keeping its own colors accessible. ‣ Ready for AI agents. Coming soon.

It’s almost 2027 and git still doesn’t support private folders/files within public repos 😭

One thing I realized while building this is that no router library works well with React view transitions right now. TanStack Router doesn't support them. React Router does, but you have to work around it if you need transition types.

Haz@haz.dev

Another navigation UI. Built this with CSS/React view transitions. I'd tried animating CSS anchor positioning before, and it kinda worked, but only with a lot of workarounds and edge cases. Also, the font-weight changes without a layout shift 👌

Another navigation UI. Built this with CSS/React view transitions. I'd tried animating CSS anchor positioning before, and it kinda worked, but only with a lot of workarounds and edge cases. Also, the font-weight changes without a layout shift 👌

Tried tsrs on a large monorepo (240k+ LOC). It's pretty impressive, but honestly not worth it. Everything passes, but I can't be sure things will FAIL the same way. That's probably more important than passing.

I don't want to pay for SaaS anymore. I want to buy a license to the source code so I can host the software myself and customize it exactly the way I want (using AI agents). If I need a feature in your software, I can just edit the code to add it.

AI is really bad at design, even Claude. But GPT models are painfully worse. Even when you're iterating, they're more likely to make suboptimal design decisions unless you guide them down to the tiniest detail. Claude (even Opus) will at least get *some* of those tiny details right.

I remember being super excited to share my new GitHub/npm projects, even the small ones. Now that AI has taken all the effort out of it, sharing doesn't feel the same. Anyway, here's a small project I spent a few Astra tokens on: github.com/diegohaz/oxl...

github.comGitHub - diegohaz/oxlint-plugin-comment-reflow: Syntax-aware comment wrapping and safe trailing-comment placement for Oxlint.Syntax-aware comment wrapping and safe trailing-comment placement for Oxlint. - diegohaz/oxlint-plugin-comment-reflow

Another drawing my son made. How long did it take you to recognize the character?

Haz@haz.dev

My son made this drawing. He wants to know how many seconds it took you to figure out which character it is.

It would let me create a consistent pressed state for buttons (always inset by 1px), regardless of their size.

My son made this drawing. He wants to know how many seconds it took you to figure out which character it is.

Colored badges that automatically adapt to any background color (CSS mix and relative color syntax). I'm back to UI design work this week. Inspiring posts incoming.

HTML forms are so broken. With every other element, you can do this: <div id="foo"> div⁠.⁠id // "foo" Forms work the same way too: <form id="bar"> form⁠.⁠id // "bar" But then: <form id="bar"> <input name="id"> form⁠.⁠id // the input element 🤡

And it doesn't stop with attributes. An input named "click" breaks form⁠.⁠click(), etc.

Now guess what happens to document.activeElement if you have this: <form name="activeElement"> Yes, it’s as bad as it gets.

The more I use other component libraries, the more convinced I am that Ariakit Components are necessary. We get so many details right, and the flexibility is unmatched.

View full thread

But that will change in the next few months. We've spent the past few months investing heavily in bug fixes and performance improvements. We're preparing v0.5, which will likely be the last release before v1 (finally).

After that, we have tons of new components on the roadmap. Most of the APIs and use cases are already established, so it's just a matter of timing and tokens. If you haven't tried it yet, ask your agent to give it a try, and let me know how it goes.

The more I use other component libraries, the more convinced I am that Ariakit Components are necessary. We get so many details right, and the flexibility is unmatched.

AI also seems to understand it particularly well. Having no breaking changes over the past 3 years, despite 37 new versions, might have helped keep the training data up to date. The one area where we're behind is the number of components.

Saw the eclipse today in León, Spain. My second totality, and it was even better than the first. I tried to capture it on camera, but there's simply no way to reproduce what you see. You either get a great close-up of the sun or a great shot of the surroundings with a tiny sun.

I really recommend seeing one if you get the chance. It's an incredible experience. The eclipse is extremely bright, but no camera can capture it faithfully. It looks like a huge, thin ring light in the sky, feels more artificial than natural.

Ariakit has hundreds of component tests duplicated across happy-dom and Playwright. happy-dom is 6× faster, so humans and agents use it for quick feedback during dev. Playwright is authoritative and runs once when each task is complete. This setup has sped up development. Highly recommend it.

Worth noting that we use @⁠ariakit⁠/⁠test, which provides user event methods and works around many happy-dom quirks. We can reliably reproduce browser behavior in most cases.

npmjs.comnpmjs.com

Design has become such an important skill these days. No matter how intelligent models become, we've evolved over 100s of thousands of years to detect nuance, intent, emotion. Theory of mind. We have a biological advantage here. That's why AI will never be good at Design.

We've made so many improvements to @ariakit.com components over the past 3 months. I'm especially excited about the performance gains. In the next version, the new ComboboxSelect component will be twice as fast as the current Combobox + Select combination used to build selects with search fields.

This comes on top of the improvements we've already made in recent versions. So if you haven't upgraded in a while, you can expect components to be up to 4× faster across the board.

Ariakit React just hit 1M weekly downloads on npm 🎉 We're just getting started. Launching something big in September/October.

If you're already managing DNS on Cloudflare, consider transferring your domains there. I just saved $160/year by moving a few domains from GoDaddy to Cloudflare.

Due to the growing number of supply chain attacks on OSS, we've limited PRs to maintainers only. But that doesn't mean contributors don't get credit. In fact, they get even more credit now by:

View full thread

Everyone involved is automatically added to the merge commit as `Co-authored-by`. They also appear in the changelog entries and receive the "Contributor" badge on GitHub.

Honestly, I feel like this is the best experience for both contributors and maintainers. No spam or AI slop PRs, no back-and-forth reviews, and everyone is rewarded.

Due to the growing number of supply chain attacks on OSS, we've limited PRs to maintainers only. But that doesn't mean contributors don't get credit. In fact, they get even more credit now by:

1. Opening the issue 2. Helping with the issue 2.a. Providing a workaround 2.b. Testing a proposed solution 2.c. Linking to a fork with a solution 2.d. Helping with API/Design decisions 3. Reviewing the PR

I don't know if it's just me, but I often struggle with walls of text that lack code examples when trying to understand code decisions. That's why I use this custom instruction in ChatGPT. It really helps me follow its line of thinking during the session and in the final output.

Text: When working with code, always include examples or snippets in your explanation. Simple, focused code examples make code problems easier to understand.

We just removed .nvmrc from Ariakit and let pnpm manage Node.js too. If your project already uses pnpm, you may not need a separate Node version manager. Here’s the migration:

1. Pin Node for the project: `pnpm runtime set node 24` This adds devEngines.runtime to package.json. Then pnpm install resolves an exact Node version, records its checksum in pnpm-lock.yaml, and installs it locally.

2. Point GitHub Actions at the same configuration: - uses: actions/setup-node@v6 with: node-version-file: package.json The result: package.json becomes the single source of truth for both pnpm and Node, and contributors don’t need to switch Node manually.

I started watching Peaky Blinders on Netflix and realized I don't understand English at all. Without subtitles, I can't understand even 20% of what they're saying. It's like watching The Boys except everyone's Butcher. Send help!

If you're using jsdom with Vitest, consider switching to happy-dom instead. It's much faster, but it comes with one caveat: its DOM spec coverage isn't as extensive as jsdom's. That's why I was using jsdom. But there's a better approach...

Set the default environment to happy-dom, then override it in test files that need jsdom with this comment: // @⁠vitest⁠-⁠environment jsdom This way, you get happy-dom's speed by default and use jsdom only in the files that actually need it.