The Shopify Remix

Issue #282.April 22, 2024.2 Minute read.
Bytes

Today’s issue: Convincing pea milk companies to sponsor open source, the secrets of the CSS Masonry layout, and keeping up with the Kardashians Node ecosystem.

Welcome to #282.


Eyeballs logo

The Main Thing

A bunch of dolls stacked on top of each other to form one mega-doll

A framework on top of a metaframework on top of a JS library

The Shopify Remix

Have you ever wondered what happens when a big tech company acquires an open-source web framework?

Some companies use it as lead-gen for their enterprise software product, some use it to buy goodwill with developers, and some forget to use it for anything at all.

But since acquiring Remix back in October 2022, Shopify has been running a different playbook – building another open-source framework on top of the one they just bought.

I’m talking about Hydrogen, a Remix metaframework (of sorts) that gives you components, utilities, and design patterns that make it easier to work with Shopify APIs.

Why the double-framework inception? By building Hydrogen on top of Remix, Shopify is hoping to attract the larger and more sophisticated ecomm businesses that are paying developers to build more robust web applications, which often require modern routing, data fetching, and SSR.

And those larger-scale businesses are worth a lot more to Shopify as customers than the small-time stores that just want to use a generic free theme to sell some fake CBD gummies.

You can really see the power of Remix on full display in Hydrogen’s latest release, with new features like:

  • Stable Vite support (which just launched in Remix), unlocking the entire ecosystem of Vite plugins for Hydrogen apps, plus 10x faster HMR.

  • A full SEO overhaul that leverages Remix meta exports.

  • DX improvements like bulk uploading environment variables via the CLI, a 60% smaller package size for the CLI, and more.

Bottom Line: It’s easy to make jokes about Shopify building a framework on top of Remix, which is built on top of React, which is built on top of JavaScript. But if it works out, Tobi & Co. will be laughing all the way to the bank.

        

graphite-logo.png

Our Friends
(With Benefits)

Kermit lying down on his back

Day 3 of waiting for someone to merge your PR

Unblock your pull requests with Graphite

If you could fix one thing to make your team more productive, what would it be?

For most developers, the answer is obvious – faster, better code reviews.

That’s why Graphite built a tool on top of GitHub that lets you create “stacks” of dependent pull requests.

This allows you to continue pushing PRs without waiting for review, and it provides unique tools to quickly review and merge changes:

  • Merge queue automates the best practices to eliminate merge conflicts, so you can instantly rebase, rerun CI, and merge PRs.

  • Automations lets you take action on PRs with “if-this-then-that” rules to eliminate manual work.

  • Insights show you the performance of your team over time, so you can identify and fix bottlenecks in your review process.

Try it for free – and see why 15,000+ developers at Vercel, Snowflake, and more use Graphite to stay unblocked and ship faster.


Spot the Bug logo

Spot the Bug

Sponsored by Raygun

The debugging nerds of the Raygun dev team explain why source maps are such a no-brainer for fixing bugs.

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. Dylan Jhaveri wrote about how Mux is Keeping up with the Node-ish ecosystem – which was the exact name of the Kardashian+JavaScript reality show I was co-producing with Ryan Seacrest (until they shut down Tubi 😭).

  2. Josh Cunningham wrote about Building a CLI from scratch with TypeScript and oclif.

  3. Socket is the best way to protect your application from vulnerable and malicious packages. It proactively detects and blocks 70+ signals of supply chain risk in open-source code, and is trusted by engineering teams at Vercel, Figma, Expo, and more. [sponsored]

  4. Ripl is a new library that provides a unified API for 2D graphics rendering in the browser that focuses on interactive data viz. It isn’t sponsored by the pea milk company with the same name, but it really should be.

  5. Dan Vanderkam wrote this breakdown on How he implemented a new TypeScript Feature as a relatively new TypeScript contributor. It’s called Type Predicate Inference, and is coming out in TypeScript 5.5.

  6. Bright Data’s Scraper Browser API lets you scrape web data from the most complicated websites at scale without being blocked. [sponsored]

  7. Electron 30.0 just came out, and we will not be entertaining any Electron slander at this time.

  8. In React 19 – Part 2, Rafael Carmago dives into how all the code works under the hood in the RSC framework he built from scratch.

  9. Mihai Chirculescu created semantic-autocomplete, a React component that extends MUI’s autocomplete and performs “semantic similarity search” using a quantized machine learning model that runs on client side.

  10. Jen Simmons wrote this deep dive that investigates The current state of the CSS Grid Level 3 spec, aka the “Masonry” layout. But you’ll have to go to your local Masonic Lodge and say a few secret passwords if you want to learn everything about it.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Raygun

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);

Spot the Bugs are always fun because if I don’t point out every potential issue, you all let me know 😅.

With that said, I’m leaning into it this week because this one has a bunch of issues.

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.