Today we’ve got deliberate breaking changes, regret, and old things that are cool again.
Welcome to #153.
You have no idea the physical toll that three rewrites has on a person
This past week our friends at Remix released v1.10.0, completing the “React Router-ing of Remix”. For those who haven’t been paying attention, we’ve gone from React Router to Remix, Remix to React Router, and now we’re back to Remix (snip snap, snip snap) – which is a lot to take in. Let’s break it down.
Before creating Remix, Ryan / Michael and co. were working on the biggest library in the React ecosystem, React Router. After years of “working for free”, they decided it was time to get paid (🫡) and raised money for a project they had been building during The Pandemic, Remix.
The original pitch for Remix was to be an SSR framework for React, built primarily on standardized Web APIs. Through its simple but powerful API, Remix saw consistent adoption from an ever-growing and passionate community. The passion was so strong that other frameworks like Next.js quickly found themselves in a Clayton Christensen fever dream, needing to play API catchup to keep up.
The problem, unfortunately, is that raising VC is often a cruel mistress with a singular, insatiable addiction – growth. And what was the fastest way to grow Remix? Figure out a way to get all those React Router users to become Remix users. And with that, we have the first snip.
✂️: Remixing React Router
To try to satisfy said mistress, the team decided to move all of Remix’s data APIs like loaders
and actions
to React Router so it could own data orchestration for the whole app – and oh yeah, make it dead simple for React Router users to adopt Remix. To do this, they had to, once again, re-write React Router from scratch (without breaking anything).
✂️: React Router’ing Remix After releasing React Router v6.4 (and selling their company to Shopify), the Remix team got busy on the final phase of their journey, integrating React Router back into Remix. They wrapped up the journey this week paving the way for new features like streaming and deferred rendering, but more importantly, now React Router users having a much more seamless path to adopting Remix.
Bottom Line: React Router still dominates the React ecosystem, with over 9 million weekly npm downloads. If all this rewriting can persuade a substantial segment of those users to give Remix a try, Michael and Tobi may come together after all.
That's one powerful back (end)
Congrats! Your team’s app made it to the top of Hacker News, and now you’ve got traffic coming out your eyeballs 🎉. There’s only one problem…
You went with a “usage-based” pricing plan for your hosting — and all that traffic just ate up the rest of the cash in your company bank account (RIP in peace).
Should’ve used Appwrite.
Appwrite is a self-hosted BAAS (backend as a service) platform that gives you a collection of easy-to-use REST APIs that abstract away all the complex and repetitive parts of building a secure backend.
And since it’s packaged as a set of (open-source) Docker microservices, you can host it however you want and not have to worry about getting burned by usage-based pricing.
It handles all of hairy stuff for you, so you can easily integrate your app with multiple user auth methods, set up a DB for storing and querying user data, and a lot more.
I guess that’s why they called it Appwrite. Finally makes sense now.
Senior Full Stack Engineer | ||||
| ||||
Motion is looking for experienced TypeScript engineers to build the next generation of productivity tools. You'll inform key frontend architectural decisions that help Motion scale the next 2 order of magnitudes, create delightful user-facing features, and improve application performance. We are an ambitious team of 15 people distributed remotely across North America. |
Check out their Continuous Testing Brief to learn how you can test your app in a fast, reliable, and *codeless* way. It’s a solid resource.
How many times is the reducer
function invoked?
const nums = [2,4,6]
const reducer = (prev, current) => {
console.count('invoked')
return prev + current
}
nums.reduce(reducer)
esbuild just released v0.17.0, which “deliberately contains backwards-incompatible changes.” which is also the energy we want from all of you this year.
CarbonQA provides QA services for dev teams. They work in your tools, talk with your team on Slack, and let your devs be devs — so you never have to waste engineering time on testing again 🤯. [sponsored]
In a world where everyone seems to be doing the opposite, Marvin takes a noble and contrarian stance in Speeding up the JavaScript ecosystem - module resolution.
LemonadeJS is a reactive JavaScript library with two-way data binding that aims to be as close to vanilla JS as possible. Personally, I’m here for vanilla JS and two-way data binding making a comeback. Let’s bring back that Yeoman logo while we’re at it.
Speaking of old things that are cool again, yours truly wrote Server Rendering with React and React Router in case you want 1/100th of the power of using a framework like Next.js or Remix with 100x the pain.
Speaking of regret, The Excalidraw Team wrote about Rethinking their Component API.
Structura.js is a new TypeScript library that lets you create immutable states with mutable syntax. It pitches itself as an Immer alternative that’s “up to 22x more performant.”
James Somers wrote an article called, What if writing tests was a joyful experience? It reminds me of the article my 9th-grade health teacher wrote called, “What if learning about puberty and drugs from the JV baseball coach was a joyful experience?”
How many times is the reducer
function invoked?
const nums = [2,4,6]
const reducer = (prev, current) => {
console.count('invoked')
return prev + current
}
nums.reduce(reducer)
Answer: Twice
If an initial value isn’t supplied, the first element in the array will be used as the initial value and the first invocation of the reducer function will be skipped.