That JS-free lifestyle

Issue #350.December 12, 2024.2 Minute read.
Bytes

Today’s issue: Spilling the TC39 tea, promising not to complain about breaking changes in React Router, and mid-life crisis-ing with Rust.

Welcome to #350.


Eyeballs logo

The Main Thing

A Teletubby dressed up as a soldier

Gearing up to fight the JavaScript Industrial Complex.

That JS-free lifestyle

We all have JavaScript haters in our lives. And while that doesn’t necessarily make them bad people, I usually try to avoid making eye contact – just in case.

But in the spirit of holiday cheer, let’s un-shun the h8rs to celebrate one man who’s building some powerful tools for raging against the JS machine: Chris McCord.

Quick review: Chris created the popular Phoenix framework for Elixir in 2014, and after growing tired of the “inevitable, ballooning complexity that JavaScript brings,” he started working on the Phoenix LiveView library in 2018.

Fast forward six years to last week, and Phoenix LiveView finally just released v1.0, allowing developers to create dynamic, server-rendered applications with one hand tied behind their backs without writing any JavaScript.

Let’s dive into how it works:

  • Real Time Primitives – LiveView builds on top of the real-time primitives in Phoenix Elixir. For example, instead of sharing memory, Elixir apps pass messages between processes. Similarly, LiveView opens up a websocket and passes messages between the client and the server.

  • Server State – When a user interaction occurs, the client sends the server an event with a payload of information (extracted from data-attributes) to handle. The server takes this information, handles any data-fetching or async operations, then updates the application state.

  • Diffing Engine – Once the state is updated, the server does a diff on the template, re-renders the view and sends back the HTML fragments that have actually changed over the websocket. Finally, the client stitches the fragments back into the DOM.

Bottom Line: The JS-free lifestyle clearly isn’t for everyone. But if you’re a functional programming nerd looking to do a JavaScript detox for your New Year’s resolution, Phoenix LiveView could be a dream come true.

        

Neon logo

Our Friends
(With Benefits)

The Pill man from Osmosis Jones smiling

When you learn that Neon can also handle security stuff for you

Neon Authorize lets you secure your app at the *database level*

“But wait, isn’t Neon a serverless Postgres platform? How can they help with authorization?”

Well, those over-achieving nerds just launched Neon Authorize – which integrates with third-party, JWT-based authentication providers like Clerk to bring you authorization closer to your data itself.

This lets you manage authorization directly within Postgres, so you can completely replace security at other layers of your application (or use it as a fallback solution).

Here’s how it works:

  • Most authentication providers issue JSON Web Tokens (JWTs) to convey user identity and claims. These JWTs get passed to Neon Authorize, where you can utilize the validated user identities directly in Postgres.

  • The Neon Proxy performs the validation behind the scenes, and their open-source pg_session_jwt extension makes the extracted user_id available to Postgres.

  • Then, you can use Row-Level Security policies to enforce access control at the row level, so that users can only access or modify data according to defined rules.

Check out the documentation.


Spot the Bug logo

Spot the Bug

Sponsored by Datadog

Their free Frontend Testing Best Practices Guide walks through everything you need to know about creating and maintaining e2e frontend tests with Datadog.

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  set name (value) {
    this.name = value;
  }

  set age (value) {
    this.age = value;
  }

  printName() {
    console.log(this.name);
  }

  printAge() {
    console.log(this.age);
  }
}

Cool Bits logo

Cool Bits

  1. Blaž Hrastnik created a “post-modern” text editor called Helix. It features LSP support, powerful code manipulation tools, and a bunch of those Andy Warhol prints that your artsy college roommate used to hang everywhere.

  2. Next.js 15.1 adds stable support for React 19 🫡.

  3. Clerk just released a new <Waitlist /> component that looks pretty slick. I can’t wait to use it to build FOMO for my new streetwear-for-kids collab with Supreme and Paw Patrol. [sponsored]

  4. A judge just ruled against WordPress in the never-ending saga of WPEngine vs. Matt Mullenweg’s mid-life crisis.

  5. Jake Lazaroff wrote about isomorphic web components, which I’m 95% sure is a real thing and not just a bit he’s doing.

  6. Consider this your weekly reminder to try out bolt.new – StackBlitz’s AI-powered dev sandbox that lets you prompt, run, edit, and deploy full-stack web apps from the browser. [sponsored]

  7. The React Router team created this new Address Book tutorial, but to complete it you have to manually type “I must not complain about breaking changes” into your editor 400 times.

  8. Prabashwara Seneviratne wrote some reflections on managing state.

  9. Charly Poly wrote an article breaking down how to use the step.ai APIs to quickly build AI applications on serverless – and how they help you save a meaningful amount on compute. [sponsored]

  10. Hemanth shared some juicy updates from the 105th TC39 meeting. You’ll never guess which two committee members got voted off the island.

  11. Pavel Romanov wrote this article exploring the core concepts of Node.js readable streams.

  12. Glauber Costa and the Turso team responded to their own mid-life crises by deciding to rewrite SQLite in Rust. As far as MLCs go, this is somewhere between signing up for a marathon and burning the entire WordPress community to the ground.


Spot the Bug logo

Spot the Bug: Solution

Sponsored by Datadog

When the class assigns the name and age properties, it calls the setters, which in turn call themselves. This creates an infinite loop and will throw a “Maximum call stack size exceeded” error. To fix this, you should use different names for the properties and the setters.

class Person {
  constructor(name, age) {
    this._name = name;
    this._age = age;
  }

  set name (value) {
    this._name = value;
  }

  set age (value) {
    this._age = value;
  }

  get name() {
    return this._name;
  }

  get age() {
    return this._age;
  }

  printName() {
    console.log(this._name);
  }

  printAge() {
    console.log(this._age);
  }
}