CSS Panda-monium goes stable

Issue #415.August 11, 2025.2 Minute read.
Bytes

Today’s issue: Microsoft Teams + GitHub, pnpm + Bun, and Dan Abramov + Lil’ Wayne. It’s officially crossover week.

Welcome to #415.


Eyeballs logo

The Main Thing

Pauly D covering girl's ears

When someone tries to tell my girl that CSS-in-JS is dead

CSS Panda-monium goes stable

CSS-in-JS is kind of like MTV’s Jersey Shore: lots of people still love it, but that’s not usually something you brag about publicly in 2025.

Because even though CSS-in-JS makes it easy to build dynamic UI components, it often comes with some pretty expensive performance tradeoffs. And since most libraries also don’t play nicely with RSC, it seemed like the CSS-in-JS glory days were firmly behind us – until one panda changed everything.

Panda CSS first launched back in 2023 with the goal of combining the DX of CSS-in-JS with the performance of atomic CSS in a way that’s built for the server-first era. It’s grown steadily since then to over 125k weekly downloads, and last week they finally released Panda v1.

Now that they’re fully stable and ready to take the CSS-in-JS comeback tour to the next level, let’s take a closer look under the hood:

  • Static analysis + PostCSS – Parses your styles at build time and outputs optimized, human-readable atomic CSS

  • Lightweight runtime – No browser-generated styles or <head> injection

  • Type safety baked in – Auto-generated typings for every property, token, and pattern

  • Modern CSS and DX – Cascade layers, variables, and JSX style props, plus new v1 goodies like bgLinear/bgRadial/bgConic gradient props, and a new createStyleContext API for cross-framework design systems

Bottom Line: Pedro Duarte (creator of Stitches and Radix UI) put it best when he said that Panda is “like Stitches, Tailwind, Vanilla Extract, CVA, Styled System and Linaria had a child.”

A love child from six different parents? This really is like Jersey Shore.


Convex logo

Our Friends
(With Benefits)

Veggie Tales character playing the keyboards

My AI agent getting ready to cook

Convex’s new Agent component lets you build AI agents easily

Building an AI agent usually means duct-taping together half a dozen services and praying your vector DB doesn’t choke.

Thankfully, Convex’s new, open-source Agent component fixes that. It gives you simple building blocks for creating persistent, intelligent agents that are fully integrated into your Convex backend – so you can build everything in TypeScript.

Here’s what it gives you:

  • Persistent threads that remember context across conversations and are shareable between users and agents

  • Hybrid vector/text search for fast, relevant lookups over your data (see YouTube tutorial)

  • Durable workflows that stream updates live to every connected client

Check out the docs – and see how easy it is to build AI agents that just work.


Spot the Bug logo

Spot the Bug

Sponsored by Clerk

They made this video showing how they made it easier to customize Clerk UI components with new theming via CSS variables and a dedicated shadcn/ui theme.

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }

  set fullName(name) {
    name = name.split(' ');
    this.firstName = name[0];
    this.lastName = name[1];
  }
}

class Employee extends Person {
  constructor(firstName, lastName, title, salary) {
    super();
    this.title = title;
    this.salary = salary;
  }

  get employeeInfo() {
    return 
      `${this.fullName}, ${this.title}, earns $${this.salary} annually.`;
  }
}

const employee = Employee('Jane', 'Doe', 'Software Developer', 90000);

Cool Bits logo

Cool Bits

  1. This season of Better Call Dahl just took a twist: Oracle responded to Deno’s petition by denying that the term “JavaScript” is generic and insisting their trademark should stand. I guess we have to pay Larry a quarter every time we sing Happy Birthday publish a Bytes issue.

  2. TypeScript 5.9 comes with an updated tsc --init, actual summaries in more DOM APIs, and more.

  3. User Journeys is a new observability feature from Embrace that shows you how technical performance impacts user engagement with your app’s features. It’s like zooming out one level from logs and spans to include *actual user behavior* as a signal. [sponsored]

  4. GitHub is moving into Microsoft’s CoreAI team and will no longer operate as a separate company. Personally, I can’t wait for Microsoft Teams to be integrated into every single repo. #Synergy

  5. Andrey Sitnik wrote about what they learned from creating PostCSS, and what it’s like to maintain an OSS project with 100 million weekly downloads.

  6. Leerob wrote some reflections on the React community, now that he made it out alive (barely).

  7. Learn how to stand up AI agents in 20 minutes with Postman’s AI Agent Playbook webinar series – where each 20-minute session walks through real AI agents you can deploy for engineering, support, and sales workflows using your existing APIs and tools. You’ll walk away with usable templates that’ll help your team save time on day 1. [sponsored]

  8. Manish wrote about how he built an entirely offline AI workspace. But if the entire Microsoft Office suite doesn’t come built in, I’m not interested, Manish.

  9. The V8 team wrote about how they made JSON.stringify more than twice as fast.

  10. CarbonQA provides high-quality QA services for dev teams, so you’ll never have to test your own app again. Their US-based testers work in your tools, talk with your team on Slack, and let your devs be devs. [sponsored]

  11. pnpm 10.14 adds support for JS runtime installation – so you can pick Node, Deno, or Bun and have pnpm download and pin it for you.

  12. Dan Abramov wrote an article called the math is haunted where he answers the question, “So what does using Lean feel like?” But I feel like I’ve already listened to enough Lil’ Wayne songs to have a pretty good idea.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Clerk

class Person {
  constructor(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  get fullName() {
    return `${this.firstName} ${this.lastName}`;
  }

  set fullName(name) {
    name = name.split(' ');
    this.firstName = name[0];
    this.lastName = name[1];
  }
}

class Employee extends Person {
  constructor(firstName, lastName, title, salary) {
    super();
    this.title = title;
    this.salary = salary;
  }

  get employeeInfo() {
    return 
      `${this.fullName}, ${this.title}, earns $${this.salary} annually.`;
  }
}

const employee = Employee('Jane', 'Doe', 'Software Developer', 90000);

There’s a bunch of issues (and probably some others I don’t mention).

First, we’re not validating any types (yes, I hear TypeScript fixes this). Second, it’s probably not a great idea to mutate our name parameter in set fullName. Third, we need to pass firstName and lastName to super inside of our Employee constructor. Fourth, because of automatic semicolon insertion, our employeeInfo will return undefined instead of our string. And last (I think), when we create a new instance of Employee, we need to do so with the new keyword.