Welcome, friends!
Big thanks to those of you who shared đšď¸ react.gg! Someone posted it to Hacker News and we hit the front page (!!) for a few minutes (!!) until it got flagged, lol. The orange site giveth, and the orange site taketh away.
Todayâs issue: Weird spammers take over npm, the first web designer to win an EGOT, and the best way to practice a knuckle puck.
Welcome to #174
Our most esoteric 90s pop culture meme yet
Pnpm just released v8.0 on Monday. And while there arenât a bunch of big new features, pnpm itself has been getting a lot of hype lately. They even 5xâd their number of total downloads last year and continue to grow đ.
So what makes this package manager unique, and why are its usage graphs shaped like my D2: The Mighty Ducks commemorative hockey stick from 4th grade? Letâs dive in.
Quick background: Back in 2017, Zoltan Kochan released v1 of pnpm, which TIL stands for âperformant npm.â I always assumed it stood for âpneumonia npmâ, because my lungs would fill up with fluid whenever I used it â but it turns out that was just because my old office had a bunch of asbestos đ¤ˇââď¸.
But âperformant npmâ is actually a great name, because thatâs exactly what it is â a faster, more efficient replacement for npm (and Yarn) that comes with solid monorepo support and mostly feels like youâre just using npm. Hereâs how it works:
With Yarn and npm, if you have 100 projects using a dependency on your machine, youâll have 100 copies of that dependency saved on your disk. They resolve those dependencies by using hoisting to flatten their node_modules
. This eats up a lot of disk space and can cause slow installs (as youâve probably experienced).
Pnpmâs key insight was to use a content-addressable store instead, which stores each of your dependencies only once in a global store on your home folder. If you need different versions of the package, only the files that differ get added to the store (instead of the entire package).
They do this via a non-flat node_modules
directory, which creates a nested structure of dependencies, where every package and file inside the folder is hard linked to the store â saving you time and disk space đ¤.
Bottom Line: Yarn and npm have started adopting some of these ideas, and Bun is coming in hot with its own package manager that claims to be fast af too. But for now, the pnpm hockey stick growth chart shows no signs of slowing down. Now excuse me while I go outside to practice my knuckle puck.
We're all backend devs now đ
Iâm pretty sure Retoolâs mission statement is, âBe a developer genie that grants unlimited wishes.â
The latest magic is Retool Database. It lets you build apps with a fully managed PostgreSQL database with no setup required. That means you can ditch your janky spreadsheets forever â and convert your Google Sheets and Airtable Bases into Postgres tables in a few clicks.
The goal here is to give you the power of a scalable Postgres DB, with the speed and convenience of a spreadsheet. Hereâs how it works:
When you sign up for Retool, they spin up a real, Postgres DB for you thatâs ready to scale.
You can use their database UI to build your schema â add tables, configure fields, and upload CSVs like youâre working in a spreadsheet.
Then you can write real SQL queries for all of your Retool apps (and use it with non-Retool apps too).
They created this drag-and-drop editor and page builder for your SaaS application thatâs embeddable and guaranteed to save you weeks of dev time.
Chances are if you wrote a form in the last 5 years, it looked like this:
import * as React from 'react';
function Form() {
const [name, setName] = React.useState('')
const [email, setEmail] = React.useState('')
function handleSubmit(e) {
e.preventDefault()
// Do something with the data
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" value={name}
onChange={(e) => setName(e.target.value)} />
<input type="text" name="email" value={email}
onChange={(e) => setEmail(e.target.value)} />
<button type="submit">Submit</button>
</form>
)
}
But how would you do this in pure HTML? Answer below.
Speaking of npm, Gabi Dobocan wrote on the Sandworm blog about how 50% of new npm packages are SEO spam right now â promoting things like fake Fortnite V-bucks (ew) and free ebooks (double ew). I emailed Nat Friedman to ask him why npm install hot-singles-near-me
isnât working, but I havenât heard back.
Looking for a good way to monitor your React Native app? The New Relic team wrote some helpful documentation around monitoring React Native applications with New Relic. [sponsored]
Jim Nielsen wrote about Types in JavaScript With Zod and JSDoc for those of us who might like types, but donât like like types.
Update: over 5,600 packages about John Wick have now been uploaded to npm, which means that .02% of npm is currently dedicated to Hollywoodâs most beloved assassin. I know this probably seems like something we would do, but I swear it wasnât us.
JP Camara wrote about how he made Tanstack Table 1000x faster with a one-line change
Tailwind CSS v3.3 just came out with an ESM and TS support, logical properties, and an extended color palette for darker darks. I just hope they have the full Tom Haverford collection of âobsidian, onyx, midnight, lost soul, rolling blackout, sleeping panther, and Void by Armani.â
Lots of you have asked, so we wanted to share that the react.gg domain cost us $7k (đŽâđ¨) and we built the site using Astro and React (đ + âď¸). Also, it was designed and built by our very own Lynn Fisher (đ) â whose past web projects have received multiple design awards (nbd). This year, weâre hoping she becomes the first web designer to win an EGOT đ.
The browser has a built in API called FormData that allows you to easily get the data from a form.
<form>
<input type="text" name="name" />
<input type="text" name="email" />
<button type="submit">Submit</button>
</form>
<script>
const form = document.querySelector('form')
form.addEventListener('submit', (e) => {
e.preventDefault()
const formData = new FormData(form)
const email = formData.get('email')
const name = formData.get('name')
// Do something with the data
})
</script>
Even if youâre using React, FormData makes it easy to get the data without having to manage state for each input.
import * as React from 'react';
function Form() {
function handleSubmit(e) {
e.preventDefault()
const formData = new FormData(e.target)
const email = formData.get('email')
const name = formData.get('name')
// Do something with the data
}
return (
<form onSubmit={handleSubmit}>
<input type="text" name="name" />
<input type="text" name="email" />
<button type="submit">Submit</button>
</form>
)
}
Bonus:
FormData is also one of the Request body types for the Fetch API, so if you are using an edge function to handle your form submissions you can use FormData to easily get the data from the request.
function handleRequest(request) {
const formData = await request.formData()
const email = formData.get('email')
const name = formData.get('name')
// Do something with the data
}