To be clear, this project happens to lend itself particularly well for test-driven development. That's not a luxury that I always have. And I'll probably still have to fix some incorrect tests anyway.

(I'd get Impostor Syndrome from reading my own toot, hence the clarification.)

Show thread

Yesterday I gifted myself a whole bunch of unit tests, so all I have to do now is write the implementation and see them flip to green. Thanks, Yesterday Vincent!

I've started seeing words like "modularity" and "generic" as red flags. They're not good in and of themselves: they have to serve a purpose.

Are we going to use these modules? Is this generic over likely future use cases? Are other likely future changes not made more complex?

Show thread

"Don't repeat yourself" is just a means to an end. The goal is to make it easier to apply future changes that should affect different parts of your code base.

But if they evolve independently, then you're only making things more complex to make them even harder in the future.

Show thread

I don't mind having (software-)architectural discussions, but I do feel they're most valuable when people discuss concrete challenges and use cases, rather than vague intuitions about what's "cleanest". For example:

One advantage of Tailwind's removal of a layer of indirection: it obviates the need to come up with names for CSS classes that are neither too specific nor too generic. A serious advantage: the costs of having to name things are often underappreciated.

But how about we turn this around: when an abstraction is particularly hard to name, could that be a sign that it might not actually be a useful one?

Anyway, that's my current analysis. If you know of anything I've missed, do let me know!

Show thread

So to recap, the advantages:

- Constraints keep your design consistent.
- Simple tooling, with just few kBs shipped to your users.
- Styles defined in the context of the component to which they apply.

And to address the elephant in the room: yes, this addresses problems that inline styles do not. Specifically, it is not trivial to apply constraints using inline styles, and media queries and focus and hover states are not supported at all.

Show thread

Tailwind does away with that indirection: you apply your design constraints directly in the component, using plain CSS. It provides "utility classes" like p-0 to p-9, to apply a little to a lot of padding, respectively, to an element. Whatever you choose, it'll be consistent.

Show thread

This layer of indirection was intended to allow you to re-use your classes in different HTML elements.

But in the age of component-based architecture, is that still useful? We write our HTML once for our components, and then re-use those components across our codebase.

Show thread

So how about we just define the constraints in, say, CSS variables?

Well, you could do that, but consider how you would use those.

You'd keep switching between your components and your styles, defining new classes in your CSS that rely on the constraints, and then applying these classes in your components. It adds a layer of indirection between the styles and the components to apply them to.

Show thread

This idea isn't unique to Tailwind. Component libraries like Chakra UI and Material-UI apply it already.

However, to enable the sharing of constraints across your app, these libraries define their styles in JavaScript, using tooling to prevent them from interfering with yours.

This leads to inflated bundle sizes and complex tooling.

Show thread

To understand Tailwind, you need to understand constraint-based design, in which UI elements adhere to a set of constraints designed to make them compose well together to make a harmonious whole.

To go down this rabbit hole, see:

Show thread

We're seeing get quite some traction, so I figured it was about time to try to understand what sets it apart and what problem it solves.

I think I get it now, and to solidify my understanding, I'm going to try to articulate its benefits.

I've been interested in property-based testing for a while, but never had a clear use case for which it was easy to implement. Until recently, and I just submitted a fix for the second edge case fast-check discovered we weren't handling properly.

Really exciting, that feeling of having learned something new that will hopefully be useful more often.

It's here! My masterpiece, the last VSCode extension you will ever need: Whoopee cushion keyboard.

Yes, it makes fart sounds when you type.

That's it. That's the extension.

Get it here:

Or don't, that's probably better.

I've managed to hold it in until this toot, and I don't think anyone's got wind of it yet, but I'm almost ready to unleash my next project onto the world. And believe me, it's going to be a whooper. I'm pumped!

(Or it falls flat on its face. We'll see.)

Hot diggity damn. If you thought having to support different browsers was bad, try supporting Node before ES modules, Node running without ES modules on a version that does support ES modules, Node with ES modules, and the variety of bundlers people are using to package projects for the browser.

@nolan That allows you to do away with dev, test, and acceptance environments. Instead, every change has its own environment, with high confidence that it will behave in the same way as your production environment.

Show older

Server run by the main developers of the project 🐘 It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!