Skip to content

Instantly share code, notes, and snippets.

View aleclarson's full-sized avatar

Alec Larson aleclarson

  • United States
  • 03:10 (UTC -04:00)
View GitHub Profile
@aleclarson
aleclarson / octane-august-8-to-22-2026.md
Last active August 23, 2026 17:31
Octane progress: August 8–22, 2026

Octane progress: August 8–22, 2026

Octane can now enhance DOM it doesn't own

An Octane root can now attach behavior to DOM owned by another system instead of assuming that Octane owns and renders the DOM itself.

This opens several practical adoption paths:

  • Add Octane behavior to server-rendered HTML.
  • Introduce Octane incrementally inside an existing application.
@aleclarson
aleclarson / octane-landing-page-feedback.md
Created August 18, 2026 22:29
Notes on the Octane Landing Page

👋 Hey Dominic — I collected a few thoughts on the landing page. Hopefully there’s something useful in here.

Notes on the Octane Landing Page

My main impression is that the page is written primarily for engineers who are already interested in renderer/framework architecture.

That audience obviously matters. But I suspect it causes the page to spend too much time answering:

“Is Octane technically interesting and defensible?”

@aleclarson
aleclarson / solid-2-versus-octane-summary.md
Last active August 18, 2026 10:02
Summary: Solid 2 versus Octane

Solid 2 vs Octane: Two Different Ideas of What a Framework Should Know

Last updated in response to this comment.

The shortest version: Solid 2 makes reactive relationships part of the running program. Octane tries to keep application code closer to ordinary JavaScript while giving a compiler more responsibility for understanding and optimizing it. The debate comes down to what reactive code should mean when you write it, and what information should remain available when the app is running.

The thread began as a developer-experience scorecard. After several rounds between Dominic Gannaway, creator of Octane, and Ryan Carniato, creator of Solid, the disagreement has become both narrower and more interesting.

It is not really compiler vs runtime. Both use both.

@aleclarson
aleclarson / renderer-DX-pillars.md
Last active August 13, 2026 22:41
Renderer DX Pillars

I’d avoid comparing Solid 2 and Octane primarily on benchmark speed. They’re both already attacking the “make DOM updates cheap” problem aggressively; the interesting comparison is what each makes you think about while building a real application. Solid makes fine-grained reactivity fundamental, while Octane deliberately preserves a component/re-render/hooks mental model and pushes more bookkeeping into its compiler. ([SolidJS Docs][1])

I’d use these nine DX pillars:

Pillar The question I’d test
1. State architecture freedom Can state live wherever the domain says it should, or does the renderer pull it toward components?
2. Reactive reasoning How easy is it to understand why somet
@aleclarson
aleclarson / solid-2-versus-octane.md
Last active August 18, 2026 15:53
Solid 2 vs Octane

NOTICE: I've summarized the perspectives of Octane's and Solid's creators here, for anyone short on time: https://gist.github.com/aleclarson/829c10aa7d287944ef75e1c2a90bef06


I'm a React/Preact/Astro developer with an interest in other renderers. The two that have most caught my eye recently are Octane (from Dominic Gannaway of React Hooks / Svelte / Inferno fame) and Solid 2.

I asked ChatGPT to compare them with its own "Renderer DX Pillars", which I've shared below. This is its gut instinct, with very little hedging:

Pillar Winner Why
@aleclarson
aleclarson / solid-2.md
Last active August 13, 2026 22:31
Solid 2.0 summary
  • Solid 2.0 makes async data part of Solid’s normal reactive system.

  • A reactive value can depend on a Promise. Solid tracks that async work as part of the dependency graph.

  • This means you need less manual code for:

    • loading states
    • stale data
    • race conditions
  • transitions

@aleclarson
aleclarson / _README.md
Last active June 17, 2026 11:40
TamperMonkey script for automatic redirects from npmjs.org packages to their npmx.dev equivalents

npmjs to npmx Tampermonkey Scripts

Two Tampermonkey userscripts that make npm package browsing default to npmx.dev, while still allowing you to intentionally open the original npm package page from npmx.

Scripts

npmjs-to-npmx.js

Redirects npm package URLs to the same path on npmx.dev.

@aleclarson
aleclarson / 01_proposal.md
Last active November 7, 2025 19:33
Remix 3 `this.props` proposal

“Setup props” considered harmful!

Ryan Florence doesn't like me saying that, but it's true.

Why is it true? Well, they look like render props until you scroll down to the return statement and see an arrow function. If you refactor a stateless component into a stateful component (i.e. add a setup scope), the render props subtly become setup props, right under your nose.

Most of the time, using setup props is dangerous and unnecessary, as it leads to problems down the road. At first, all is well, but then you use the component more dynamically and, BOOM, you've got a stale data issue that presents itself in confusing ways. Of course, this problem is most apparent in more complex applications with many moving parts.

OK, let's say there's a problem. Can it be avoided?

@aleclarson
aleclarson / 01_track.ts
Last active November 2, 2025 22:43
Remix 3 "track" utility
// Track props access and selectively rerun callbacks on rerender.
export function track<Props extends object>(
...callbacks: ((props: Props) => void)[]
) {
const tracked = callbacks.map((callback) => new TrackedCallback(callback))
let oldProps: Props | undefined
return (props: Props) => {
tracked.forEach((callback) => {
if (!oldProps || callback.shouldUpdate(props, oldProps)) {
@aleclarson
aleclarson / demo.ts
Last active October 23, 2025 21:34
Remix 3 wrapper-free event support (type safe)
import { Event, events, EventTarget, on } from './framework.ts'
// Extending a built-in class with type-safe events
declare global {
interface Worker {
// Does not exist at runtime. No createEventType wrapper needed.
$rmxEvents: {
message: MessageEvent
}
}