Ride the Lightning CSS

Issue #217.August 28, 2023.2 Minute read.
Bytes

Today’s issue: Marcus Aurelius helps write the Next docs, htmx dad jokes with no punchlines, and emails vs. capitalism.

Welcome to #217.


Eyeballs logo

The Main Thing

Christ the Redeemer statue getting struck by lightning

Devon Govett opening up his laptop

Ride the Lightning CSS

Almost a year ago, Devon Govett and the Parcel team rebranded Parcel CSS to Lightning CSS after having a Cars movie marathon at Parcel HQ (probably).

Fast forward to today, and the “extremely fast CSS parser, transformer, bundler, and minifier” is already getting over 350k npm downloads per week.

And that number should continue to climb, since Tailwind recently announced that it’s integrating Lightning CSS into its next-generation engine called Oxide. That’ll help Tailwind become more of an all-in-one CSS processing tool, while making it faster and lighter. I am speed.

So what makes Lightning CSS so fast anyway? Rust, obviously.

Because Rust is a native systems programming language, it enables Lightning CSS to be up to 100x faster than comparable JavaScript-based tools (see benchmarks). It can minify over 2.7 million lines of code per second on a single thread, and it produces a smaller output by removing unnecessary vendor prefixes, combining longhand properties into shorthand, and more.

Here are some other powerful features and optimizations Lightning McCSS brings to the table:

  • Its browser-grade parser is built on the cssparser and selectors crates created by Mozilla. This lets it fully parse every CSS rule, property, and value like a browser would, leading to improved perf.

  • Instead of treating property values as an untyped series of tokens, it exposes a specific value type for each property.

  • It supports modern CSS features like CSS modules, custom media queries, CSS nesting, and logical properties — and it automatically converts newer features to more compatible syntax based on your browser targets.

You can use Lightning CSS as a JavaScript or Rust library, and it can also be wrapped as a plugin in other build tools. Devon also just announced that it now works in Stackblitz, so you can play with it over there too.

Bottom Line: I’m not sure if they typically award Piston Cups to the fastest CSS tools, but there’s a first time for everything.

        

Convex logo

Our Friends
(With Benefits)

Big guy sitting in a beautiful spring

Me when my entire backend is 100% type-safe by default

Convex lets you use your frontend skills to build a powerful backend

How? By giving you a full cloud backend that can replace your database, server functions, and that nasty glue code. And it’s all 100% Type-safe 🙏.

It’s like if someone created Firebase in the year 2023, and they didn’t hate themselves. Here’s what it gets you:

  • A realtime relational DB that’s reactive by default and simple to work with.

  • First-class React support with their React and Next.js client libraries (see docs).

  • Easy-to-use server functions that manage dev and prod for you.

  • Helpful built-in features like file storage, search, and auth.

Convex is perfect if you’re a frontend dev who wants to use familiar tools to easily spin up a fullstack app that can scale to the moon.

Check out the free tier — and feel the power of TypeScript.


The Job Board Logo

The Job Board

Frontend Engineering Manager (USA Only)
100% Remote
React

Close.com is looking for an experienced full-time Frontend Engineering Manager to join our engineering team and build & lead the 3rd Frontend team. Close is a 100% globally distributed team of 90 happy people, dedicated to building a product our customers love.

Have a job you want to fill?
Pop Quiz logo

Pop Quiz

Sponsored by Configu

Say goodbye to outdated ENV files and embrace the power of configuration-as-code. Configu is open-source software for streamlining, testing and automating application configurations across environments.

How can we improve this code?

async function completeCheckout(orderId) {
  await updateAnalytics(orderId);
  const order = await processOrder(orderId);

  return order;
}

Cool Bits logo

Cool Bits

  1. The Next.js docs have a new section on Forms and Mutations with App Router. “Forms and Mutations” was always my favorite Marcus Aurelius book. Life-changing stuff.

  2. Zero created an easy way to integrate 3rd-party API credentials into your project. Their SDK is available for TypeScript, Rust, Python, and Go. [sponsored]

  3. Alex Kladov wrote an article called TypeScript is Surprisingly OK for Compilers. I’ve often been described as “surprisingly OK” by those meeting me for this first time, so this really hit home.

  4. Dominik Dorfmeister wrote an article about Array Types in TypeScript.

  5. Electron 26.0 came out a couple weeks ago, and I can already feel my laptop getting hotter.

  6. Viewports.fyi is a cool microsite that tries to answer the question, “How fragmented are viewport sizes?”

  7. TinyBase just released v4.1 with a new ui-react-dom module, which provides pre-built components for tabular display of your data in a web app.

  8. Dylan Beattie gave a great talk called, Email vs Capitalism, or, Why We Can’t Have Nice Things. After watching, you’ll know more about how email works than 99% of developers.

  9. Alexander Petros wrote an article called Why doesn’t htmx Have a Build Step. It sounds like the perfect setup to a dad joke, but the punchline is just 2,000 words about why this library isn’t written in TypeScript.

  10. Lea Verou wrote about how JS private class fields are considered harmful and how she is “mourning the loss of encapsulation in her projects.” I’m currently mourning the loss of Bob Barker, who was always there for us on our sick days. RIP, king.


Pop Quiz logo

Pop Quiz: Answer

Sponsored by Configu

How can we improve this code?

async function completeCheckout(orderId) {
  await updateAnalytics(orderId);
  const order = await processOrder(orderId);

  return order;
}

Because processOrder doesn’t depend on the result of updateAnalytics, we can parallelize the two invocations.

async function completeCheckout(orderId) {
  const [_, order] = await Promise.all([
    updateAnalytics(orderId),
    processOrder(orderId)
  ])

  return order;
}