Brandon McConnell's Avatar

Brandon McConnell

@brandonmcconnell.com.bsky.social

Software Engineer ⚑️ Crafting some of the most popular Tailwind CSS plugins around. Bugs are my own. Dev-tooling & spec-reading fanatic πŸ’» #codeinpublic

43 Followers  |  10 Following  |  34 Posts  |  Joined: 02.06.2023  |  1.8691

Latest posts by brandonmcconnell.com on Bluesky

I'm happy to open an issue for this as well, except there's a fair chance I'm just doing something wrong. πŸ˜…

I really appreciate you maintaining such a great plugin. I know a lot of work goes into that. I'm happy to compensate you for any time spent on this if you like.

01.08.2025 07:48 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
Video thumbnail

@jamie.build Hi Jamie, I'm updating an app to Tailwind 4 and noticing with some of my dialog exit animations that the dialog briefly reappears after animating out. This only happens intermittently.

Any chance you'd be willing to take a look at this with me?

01.08.2025 07:48 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

Yeah, that's how I've been doing it so far, but targeting specific elements would be pretty neat

22.06.2025 03:18 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

@miriam.codes I was curious if you knew of any spec work being done on CSS nesting support inside of @keyframes, so we can do things like this:

@keyframes {
0% {
width: 0px;
> span {
opacity: 0%;
}
}
100% {
width: 50px;
> span {
opacity: 100%;
}
}
}

19.06.2025 23:25 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

Yes, I actually made that switch right after sending you that message haha

Still, how would you avoid useEffect here, if you would? I'm waiting until the session is ready to know if the user is logged in or not.

19.06.2025 23:23 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
Post image

@chance.dev I'm curious how you'd approach this pattern if you were trying to strip out this useEffect.
gist.github.com/brandonmccon...

If a user is logged in, the root should redirect them to `/dashboard`. Otherwise, it redirects them to `/home`.

17.06.2025 14:49 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

Yes, a lot of this boils down to the desire for nested components.

I generally advocate for separating concerns and moving complex logic into new components, but I often have to do this for a simple conditional and nested pieces of composition simply to hold state.

I’d love nesting!

Thanks again!

17.05.2025 19:51 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

BUILD PLUGIN (4/4)

This approach seems to have the fewest gotchas and simplifies the syntax, making it feel more native.

My biggest hesitation with this approach is that I believe in β€œJust JavaScript,” and while this would be JS, it feels more magical since it happens outside of React.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

BUILD PLUGIN (3/4)

Immediately, I could replace that <$> wrapper with a familiar-feeling string directive, like 'use render' (or similar).

Any block using that directive would immediately be broken out into a separate component.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

BUILD PLUGIN (2/4)

Something great about this approach is that as long as the pre-compilation is robust and works effectively, I could simplify the syntax even further.

Right away, we remove the need to use a callback; we can simply match any content wrapped in syntax like <$> and expand that.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

BUILD PLUGIN (1/4)

e.g. Vite/Webpack/etc.

In this approach, I would pre-compile any uses of this <$> syntax and *actually* break its usage out into separate functional components within the same file.

Natural hoisting makes this even easier because we don’t have to worry about order.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

PROXIES

With the proxies approach, instead of passing the hooks themselves to the callback, I would pass a proxy that watches how the hook is used and somehow carries that usage back to the component instance itself, outside the callback.

I’m not sure how difficult (or possible) that is.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

I think for v1 to actually make sense, I clearly need to change something here to support or align with React’s Rules of Hooks, which most of these appear to break.

I have two defining ideasβ€”
– proxies
– build plugin

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

Because my implementation goes a bit deeper than those others, I can do some things to optimize usage within the package, like auto-memoization, striving to follow the same patterns as the compiler.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

There are countless solutions and packages out there trying to solve this same problem, so it’s definitely a pain point felt in the framework that I think the core team could tackle in an equally or more elegantly.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

I’m not as knowledgeable as you in the compiler’s inner workings.

My primary objective here was to tackle this problem with an approach that ensures the hooks are initialized and used in the same render cycle, which they appear to be, but I can see how it might still violate the rules.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

I agree that sticking to what is recommended as best practice should be promoted here.

Thinking through my implementation, it does feel like a pattern that React Compiler could officially support with the proper affordances.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

Thanks, Dan! I really appreciate your thoughtful feedback here.

Do you happen to have a concrete example you could share that I could test around for where this would likely break?

My implementation is different than the usual `children()` approach, but I’m sure it hits the same limitations.

17.05.2025 16:55 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

And if you would rather not discuss it on X, I’m happy to continue that conversation right here in this thread on Bluesky

TY πŸ™πŸΌ

17.05.2025 06:15 β€” πŸ‘ 3    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Preview
Joe Savona on X: "@branmcconnell It's great to see experimentation in this space and I'm super hesitant to chime in and ruin the parade. But just a heads up that this does break the Rules of Hooks since it's passing hooks as first-class values, so code using this library won't get compiled by React Compiler." / X @branmcconnell It's great to see experimentation in this space and I'm super hesitant to chime in and ruin the parade. But just a heads up that this does break the Rules of Hooks since it's passing hooks as first-class values, so code using this library won't get compiled by React Compiler.

Here is the most relevant message from Joe Savona over there:
x.com/en_js/status...

The conversation has progressed past that point into a few tangential conversations and DMs, but I think addressing and discussing the concern there would be fitting, both for my package and that article I shared^

17.05.2025 06:15 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Preview
Calling React Hooks Conditionally/Dynamically Using Render Props If you've used hooks at all, you'll know that one limitation is not being able to conditionally call them in the render body of your component. So what can we do if we really need to call a hook condi...

There’s one engineer from Meta, who chimed in, convinced that this violates Rules of Hooks, but based on my understanding of the documentation, I don’t think it should.

This article’s implantation is nearly identical and makes the same non-violation claim:
unsplash.com/blog/calling...

17.05.2025 06:15 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

@danabra.mov the conversation is happening on X, but I was hoping you could clear something up for me?

We’re having a discussion about Rules of Hooks, specifically using hooks inside of a render prop so the hooks are contained in the same render cycle, not passed between components

17.05.2025 06:15 β€” πŸ‘ 3    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

I can't share the full codebase yet (at least, without probably a BAA), but I can share the components that are failing to render in case that clearly points us toward the issue

DM'ing you

13.05.2025 20:03 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0

For context, I am not using `$effect` anywhere on in my app.

Turning off my excluded directories when searching my codebase, the only places `$effect` appears are in root.svelte, the file svelte generates at `[ROOT]/.svelte-kit/generated/root.svelte`

13.05.2025 19:40 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

However, there is one specific part of my app where, every time that component renders, it throws the same error.

None of these errors occurred when running Svelte 4, as this is a core part of our app, and upgrading to Svelte 5 following the Svelte 5 migration guide immediately caused this error.

13.05.2025 19:40 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0
Preview
Svelte 5: How to debug effect_update_depth_exceeded in a Svelte 4 library? Β· Issue #13192 Β· sveltejs/svelte Describe the bug My team developed an extensive graphing library in Svelte 4. However, when trying to use the library in a Svelte 5 app, half of the features don't work and the error effect_update_...

@paolo.ricciuti.me I saw you commenting on github.com/sveltejs/sve... and I'm having a similar issue.

I'm wondering if you've learned anything new since that issue was resolved?

I have a Svelte 5 app running with Svelte 4 syntax using the built-in compatibility mode.

13.05.2025 19:40 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

This is amazing. Thank you so much for investigating this and reporting back all your findings. I'm confident your research here will have a significant and direct impact on the accessibility of carousels. That's HUGE πŸ™Œ

09.05.2025 16:53 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

The more I think about it, it's probably best if I recommend everyone use the polyfill directly, since I can't meet every unique need or bundle those concerns with my plugin's maintenance

That said, if there's anything I can do to help bring the polyfill closer to 1:1 with the spec, let me know!

30.04.2025 21:27 β€” πŸ‘ 2    πŸ” 0    πŸ’¬ 0    πŸ“Œ 0
Post image

(2/2) The policies for limitations I was more concerned about were these (attached), primarily those first three sub-bullets

From your experience building it, are those limitations of the polyfill's current state (needs work), or a polyfill of what JS can do (not possible)?

Happy to contribute! πŸ™‚

30.04.2025 21:27 β€” πŸ‘ 1    πŸ” 0    πŸ’¬ 2    πŸ“Œ 0

Thanks! I appreciate the thoughtful responses all around

(1/2) For my use case, I'm considering bundling the polyfill into an export from my package so people who use my plugin can also add the polyfill to their codebase relatively easily, though maybe I just suggest they do that themselves

30.04.2025 21:27 β€” πŸ‘ 0    πŸ” 0    πŸ’¬ 1    πŸ“Œ 0

@brandonmcconnell.com is following 10 prominent accounts