Today I Learned
Get the RSS feed for Today I Learnedthreadreader
TIL about Threadreader
, a tool that helps you read Twitter threads way more easily. Oh sorry,
it’s not Twitter anymore, it’s X. Whatever, Elon.
Whatever the hell it’s called now, Threadreader
will unroll the tweet storm into a single,
cohesive, consumable chunk of content.
TIL about ts-reset
- it’s like CSS resets but for TypeScript! Shout out to Matt Pocock (and the team) for this!
Here’s an example of one of the rules:
import '@total-typescript/ts-reset/array-includes'
const users = ['matt', 'sofia', 'waqas'] as const
// .includes now takes a string as the first parameter
// BEFORE, it would have complained about the type of the first parameter
users.includes('bryan')
There are way more rules so I encourage you to give it a read and maybe incorporate it into your project!
Show your react router routes
TIL that you can utilize npx react-router routes
to see all the routes in your app!
For my site, here’s what I get:
<Routes>
<Route file="root.tsx">
<Route path="newsletter/rss.xml" file="routes/_extras.newsletter.rss[.xml].tsx" />
<Route path="action/old-refresh-cache" file="routes/action.old-refresh-cache.tsx" />
<Route path="blog/rss.xml" file="routes/_extras.blog.rss[.xml].tsx" />
<Route path="til/rss.xml" file="routes/_extras.til.rss[.xml].tsx" />
<Route path="action/theme-switcher" file="routes/action.theme-switcher.tsx" />
<Route path="action/refresh-cache" file="routes/action.refresh-cache.tsx" />
<Route path="action/newsletter" file="routes/action.newsletter.tsx" />
<Route path="blog" index file="routes/blog._index/route.tsx" />
<Route path="tags" index file="routes/tags._index.tsx" />
<Route path="blog/:slug" file="routes/blog.$slug/route.tsx" />
<Route path="tags/:slug" file="routes/tags.$slug.tsx" />
<Route path="inngest" file="routes/inngest.ts" />
<Route index file="routes/_index.tsx" />
<Route path="health" file="routes/health.tsx" />
<Route path=":page" file="routes/$page.tsx" />
<Route path="about" file="routes/about/route.tsx" />
<Route path="til" file="routes/til/route.tsx" />
<Route path="*" file="routes/$.tsx" />
</Route>
</Routes>
headless ui
TIL about headless ui - a library from tailwindlabs
that gives you access to
unstyled ui components that integrate beautifully with tailwind
. If you’re wondering how I found out
about this, Wapplyzer revelead it to me 😆!
c15t (consent management)
TIL about c15t, a new consent management framework with some awesome React support! You can even self-host it (which is a major win for nerds like me)
RBAC in JS
TIL about a role based access control (RBAC) library in JavaScript. CASL
is a library that allows us to declaratively restrict access to resources based on roles and permissions.
import { createContext } from 'react'
import { createContextualCan } from '@casl/react'
export const AbilityContext = createContext()
export const Can = createContextualCan(AbilityContext.Consumer)
export default () => {
const createTodo = () => {
/* logic to show new todo form */
}
const ability = useContext(AbilityContext)
return (
<div>
{ability.can('create', 'Todo') && (
<button onClick={createTodo}>Create Todo</button>
)}
</div>
)
}
easy stacking in css
TIL, it’s pretty easy to stack elements in CSS, without having to use positioning! It’s a litle bit more verbose to do it in tailwind, but it’s the same idea.
.parent {
display: grid;
}
.child {
grid-area 1 / 1
}
Top Card
This card is on top... hover me!
rss feed generator
TIL about feed
, an npm package that allows you to quickly generate an RSS feed for your website!
I used it to generate an RSS feed for my blog and my TIL feeds! It’s pretty simple and super easy to plug into your existing project.
coolors.co
TIL about coolors.co
— a superfast color palette generator. If you’re anything like me,
you’ll probably use it whenever you need to generate a color palette for your side projects, you know,
those side projects that you’re totally working on and not abandoning for a while.
Optional chaining
I learned this hard lesson today. Optional chaining is for uncertain values — not uncertain existence.
If I’m not sure if a global object exists, I can’t rely on optional chaining to access it. I have to check for existence first.
// 👇 this is a valid expression in node
// we check to see if window exists
if (typeof window !== 'undefined') {
window.localStorage.setItem('key', 'value')
}
// 👇 this is not a valid expression in node
// window is undefined (its existence is uncertain)
window?.localStorage.setItem('key', 'value')
Node Modules Inspector
TIL about the node-modules-inspector
— a package that allows you to visualize your node_modules folder,
inspect your dependencies, and so much more 🤯! I’m a big fan of the visualizations, since I’m more of a
visual kinda person. You can use it in your own project with this simple command: npx node-modules-inspector
.
Typescript Ported To Go
TypeScript’s compiler is being reimagined. Currently at version 5.8, TypeScript is still written in TypeScript itself, but there are plans to port it to Go for version 7.
This change promises to improve compilation times—by up to 10 times faster! True, the speed boost
is something we probably won’t see for a few months or years, but I’m super excited to see Go
get some much needed love and attention, since you know, it’s my secondary language of choice.
Better Sleep
TIL about Magnesium Glycinate
, a supplement that helps promote better sleep! I’ve been having a tough time
falling asleep lately, especially after a tough Brazilian Jiu Jitsu practice, or an intense workout. One of my
friends recommended Magnesium Glycinate
as a way to help me sleep better. Let’s see how it works… I just ordered
some today 😆!
Fontsource
TIL about Fontsource
, a free Vercel resource that provides you with information on how to easily
install and self-host
web fonts. They support all Google Fonts, as well as open source ones!
Tanstack Form
TIL: Tanner Linsley, the creator of TanStack Query, Router, and Start, just dropped TanStack Form!
True to form, it’s framework-agnostic, headless, and has zero dependencies. It also handles deeply nested objects out of the box, making it a powerful alternative to traditional form libraries.
System Font Stack
TIL about a growing movement on the web where people are choosing to use system fonts instead of loading custom fonts. Over the years, the default system fonts included with operating systems have become quite robust and visually appealing. If you’re concerned about performance or don’t require a fancy web font, this could be a great solution for you.
Data attribute state management
This one’s pretty sweet and I’ve been reaching for it a lot lately at work!
Rather than having multiple className
conditions, you can use a
data-attribute
to manage your state.
This is not only a great way to keep your component clean but also allows you
to target any state pertinent to your component without JavaScript! Mind you,
I’m assuming you’re using something like Tailwind
for your styling.
// no reliance on utility functions like `twMerge`
<div
data-state-can-scroll={canScroll}
className="data-[state-can-scroll=false]:hidden"
>
Hidden when canScroll is false!
</div>
web extension framework
TIL about wxt! It’s like Nuxt but for web extensions.
TIL about a local first tool for image compression called sqoosh
. No more
sending images to random servers just to compress them! 😆.
TIL about bolt.new
, an AI-powered web agent that lets you deploy apps via
Stackblitz. It’s a pretty sick way to throw up a demo of a new app to illustrate
a concept.
CSS tidbits
TIL about the following…
/* top, left, right, button, are all set to to the same value */
.box {
inset: 0;
}
- The
inset
property is a shorthand fortop
,right
,bottom
, andleft
properties. - Absolute elements can only be contained by other elements using Positioned layout.
- Positioned elements will always render on top of non-positioned ones
- Stacking context
is the stacking order of elements that are positioned.
- We can create a stacking context by combining a non-static position with a
z-index. So position
absolute
andz-index
will create a stacking context. - We can also create one by setting opacity to less than 1.
- Check out the link above for more info.
- We can create a stacking context by combining a non-static position with a
z-index. So position
- The
isolation
property allows you to create a stacking context. We can add this to a parent element and then we can forget about having to add aposition: relative
andz-index
to the children. It is the lightest weight way to create a stacking context. - The
z-index
property can be used in a flexbox the same way as it can be used with a positioned element.
CSS stacking context inspector
TIL about the stacking context inspector. It’s a tool that allows you to inspect the stacking context of an element.
Leave.Comments.
More of a public service announcement and a reminder to myself (especially for
my personal projects), to leave comments on any funky things you’re doing in
code. I wasted an hour battling a bug in my blog because I didn’t leave a
comment regarding a @ts-ignore
directive.
Leave. Comments. Please.
reach.tech
Kent showed me a great way to have a stable id for my react components, between server and client renders.
Ideally, you would be reaching for useId
from react
but if you’re using an
older version of react, like 17
or 16
, then you can use auto-id
from
reach.tech
instead.
Til about zoxide
which is a faster and more robust cd
alternative; it lets
you navigate your filesystem faster and more reliably.
z ~/Documents/new-blog
z ~/Documents/rehype-code-titles
# Go back to the last directory (new-blog)
z -
# Go to the `new-blog` directory
z rehype-code-titles
# Go back to your home directory
z
# open a fzf menu of possible entries that begin with `re`
zi re<SPACE><TAB>
Standard Schema
TIL about the Standard Schema! It’s an effort to standardize the interface of TypeScript validation libraries.
To pull directly from the docs, The goal is to make it easier for ecosystem tools to accept user-defined type validators, without needing to write custom logic or adapters for each supported library.
editing the whole document
TIL that you can edit the whole document with document.designMode = 'on'
!
Toggle document.designMode
happiness one liner
Happiness = results - expecations-unknown
array with method
Today I learned about the with
method on the Array.prototype
object. This
method is used to create a shallow copy of an array but with one element
replaced at a given index.
const arr = [1, 2, 3]
const newArr = arr.with(0, 5)
console.log(arr) // [1, 2, 3]
console.log(newArr) // [5, 2, 3]
This is useful when you want to replace elements in an array without mutating the original array.
So it’s even easier now to add a documentation website to your project! While
looking over the Zod
github repo, I saw that they were using docsify
to
house their documentation. It’s pretty slick and I intend to use it for my own
projects… well at least the work ones 😆.
react-error-boundary
If you’re not using a meta framework like Next.js or Remix, I’d high suggest you check out react-error-boundary.
Seriously, Taran, use this at work.
TS satisfies without satsify
TIL about how one can use satisfies
in typescript, without satisfy
at all!
// taken right from Kent's blog
type OperationFn = (left: number, right: number) => number
// this is a restriction on the operations object
// but with satisfies, I leave myself room to add more operations and don't need to manage another type
const operations = {
'+': (left, right) => left + right,
'-': (left, right) => left - right,
'*': (left, right) => left * right,
'/': (left, right) => left / right,
} satisfies Record<string, OperationFn>
arethetypeswrong
TIL there’s a tool that can help you find out if your types are wrong for your library!
Til about raycast! The productivity tool that our macs should have shipped with ❤️
choose your license
Struggling to choose the right license for your project? There’s a great tool for that!
TIL about wave app! I’m using it to track my expenses and the invoices for my company! It’s pretty cool.
Better node objects logging!
Sick of seeing truncated Objects
in Node? I got you bro (well Matt Pocock has
got you).
let deepNesting = {
level1: {
level2: {
level3: {
level4: {
level5: {
name: 'Moderately Nested Object',
value: 42,
attributes: {
created: '2023-10-01',
modified: '2023-10-15',
tags: ['demo', 'test', 'nested'],
metadata: {
author: 'Jane Doe',
version: '1.0',
license: 'MIT',
},
},
items: [
{
id: 1,
description: 'First item',
status: 'active',
},
{
id: 2,
description: 'Second item',
status: 'inactive',
},
],
},
},
},
},
},
}
// logs: { level1: { level2: { level3: [Object] } } }
console.log(deepNesting)
// You get the whole object!
console.dir(deepNesting, { depth: Infinity })
Matt is the man!
bulletproof react
TIL there’s a useful github repo for bulletproof react!
It gives you a bunch of useufl tips and explanantions on how to make your react code bulletproof.
colored console log
TIL that you can use console.log
with color!
console.log(
'This is %cMy stylish message',
'color: yellow; font-style: italic; background-color: blue;padding: 2px',
)
changesets
Need a tool to help you manage your versioning and changelogs? Check out changesets!
Multiple Neovim Configs
Today I learned how to create multiple Neovim Configs. I’ve set up a home and work config respectively.
git recent
TIL about git recent
by Paul Irish. It’s a command that shows you your latest
local git branches! Super useful when you’re at work and got a lot of stuff on
the go.
git recent
# example output
:'
* main 7167899 (19 hours ago) Taranveer Bains
new til
feature/partytown 548eaf3 (2 days ago) Taranveer Bains
chore(dev-server): update dev script
'
interpolation
Interpolation is defined as “the insertion of something of a different nature into something else.”
css-color-filter-generator
TIL that there’s a tool to help you apply color filters to your dom nodes!
Storybook ArgeTypes
TIL that Storybook has a way to specify the behavior of args
— ArgeTypes
.
This is a great way to constrain the values that your component can accept and
provides information about args
that aren’t explicitly set in the story.
// Replace your-renderer with the renderer you are using (e.g., react, vue3, angular, etc.)
import type { Preview } from '@storybook/your-renderer'
const preview: Preview = {
argTypes: {
// 👇 All stories expect a label arg
label: {
control: 'text',
description: 'Overwritten description',
},
},
}
export default preview
stay away
Keep away from people who try to belittle your ambitions. Small people always do that, but the really great make you feel that you, too, can become great.
-Mark Twain
Ecosystem Performance
TIL about e18e (Ecosystem Performance). It’s an initiative to connect folks and projects working on improving JS package performance.
deepClone... nah, structuredClone
TIL that if we want to make a deepClone
of an object in JS, there’s a built in
method in most browsers: structuredClone
!
The old one (which works but doesn’t account for things like Set
and Map
or
even Date
)
const originalObject = {
name: "John",
age: 30,
date: new Date(),
details: {
hobbies: ["reading", "gaming"],
address: {
city: "New York",
zip: "10001",
},
},
};
const clonedObjectOldWay = JSON.parse(JSON.stringify(originalObject));
// what do you think happened to the date? 😏
// hint... no longer a string!
console.log(clonedObjectOldWay);
console.log(originalObject.date instanceof Date); // true
console.log(clonedObjectOldWay.date instanceof Date); // false (Date is not preserved)
Shout out to Matt Pocock — the person behind Total Typescript — for the twitter thread that exposed me to this function!
do what matters
Don’t forget this brother. My guy hit me hard with this; it was too damn early in the morning for them ninjas to be chopping onions 🥲!
Do what matters with who matters, while it matters.
-Mark Techson
margin vs padding
TIL margin
is meant to increase the distance between siblings. It is not
meant to increase the gap between a child and its parent’s bounding box; that’s
what padding
is for.
css height and width tidbit
width
looks up the tree but height
looks down the tree. An element’s width
is calculated based on its parent’s size, but an element’s height is calculated
based on its children.
Thanks Josh Comeau!
css list of mistakes
😆 while going through a CSS workshop, I came across this list of CSS mistakes. Be humble folks. We all mistakes.
css inheritable
Here’s a list (probably not complete) set of inheritable css properties.
observables api
TIL, from Dom Farolino that he’s trying to make addEventListener
extinct with
the observables api!
// Filtering and mapping:
element
.on('click')
.filter((e) => e.target.matches('.foo'))
.map((e) => ({ x: e.clientX, y: e.clientY }))
.subscribe({ next: handleClickAtPoint })
react internals explorer
Check out this dope tool for understanding the React internals! So dope!
Anger and happiness
Never make a decision in anger, and never make a promise in happiness
-Imam Ali Ibn Abi Talib
Better prose editing
TIL about an app that’ll edit your prose for you! Hemingway App should be able to help me write with better clarity and conciseness. I’m a wordy son of a gun.
patch-package
Got a node_module
giving you a headache? Need to give it a band-aid? Thank
your lucky stars for
patch-package.
It’s a vital band-aid for the bleeding edge!
Suffer anger
You must be willing to suffer the anger of your opponent, and yet not return anger. You must not become bitter. No matter how emotional your opponents are, you must be calm.
Anger is incompatible with joy.
Setbacks without suffering
Our goal is not to remain calm while suffering but rather to experience a setback without thereby suffering.
TIL about the unset
keyword in CSS; it resets the property value from the one
it inherited from its parent and it it doesn’t natrually inherit from its
parent, it sets it to its initial value.
bundlephobia
If you ever want to know (sort of) the cost of adding a package to your node app, you can use bundlephobia!
kanak di rakhi
TIL that Kanak Di Rakhi
is a Punjabi song that me and the Boys wild out to.
It’s a banger. It came out in 1959 and is a must listen to and dance to at any
reception.
Project wide replace in neovim
"while in your quick list
:cdo s/your-search-term/thing-to-replace-with/g
"go to quick list after changes
:wa <CR>
Semver Calculator
During office hours with Kent, I learned about semver calculator!
It seems pretty dope and I’m going to use it in the future!
I also learned that Sanity
has their own query language for working with JSON.
Might be worth looking into if you need to do some transformations and just move
it into the query versus doing it in the code.
Fluid frontvibe
TIL about a sick template for building a headless shopify theme with Sanity and Hydrogen.
details name attribute
If you pass in a name, it’ll behave like an actual accordion. Thanks Adam Argyle!
trigger.dev
Need to run background jobs? Not writing Ruby On Rails and therefore not using
Sidekiq
? Check out trigger.dev
I can probably use this somewhere in the future but TBD 🤔!
CSS variables in media queries
We tried to use some CSS variables we defined inside of the :root
with our
tailwind config and even though tailwind let’s you do that, the outputted CSS
isn’t actually valid 🤯! The media query declarations are processed while our
CSS is being parsed!
:root {
--mobile-breakpoint: 600px;
--tablet-breakpoint: 900px;
}
/* This gets processed before the CSS is parsed */
/* So the media query is invalid */
@media(max-width: var(--mobile-breakpoint)) {
.showMeGoing {
visibility: visible;
}
}
So there’s a kind of new styling solution for the web called stylex brought to you by Facebook. I haven’t used it yet, but damn, it looks neat y’all.
SVG foreignObject
TIL that you can inject other non SVG XML into an SVG document. From our context, that means we can inject some HTML elements in the SVG. I’ve used it once at work and it was kind of nice 😃.
Humiliation
To gamble on yourself is to risk failure. To do it in public is to risk humiliation.
Fear directs
Our fear, like a self-indicating arrow, points to the things we ought to do.
typescript string hack
Want to have some type hinting for a union but allow any string value?!
Use this hack bruh:
type color = 'red' | 'blue' | 'green' | (string & {})
function getColor(c: color) {
console.log(c)
}
getColor('red') // editor will code complete this for you
getColor('yolo') // this works!
CSS Grid, but fun
Alright, I’m not the greatest at CSS, but I respect those people, such as
Josh Comeau
that are! TIL (from reading his blog post) the following about
some CSS attributes and how they relate to grid:
justify
: deals with columnsalign
: deals with rowscontent
: deals with the grid strutureitems
: deals with the DOM nodes within the grid structure
For example, align-items: center
can loosely be translated into:
In the context of the row, these DOM nodes, center them... bro
. Seriously, go
read his article.
Easy to judge. Hard to know.
It’s easy to judge. It’s hard to know. Until we know the reasons why a man acted the way he acted, we cannot say that he acted wrongly.
Waste not a moment questioning a man’s courage. Put the scrutiny solely on your own.
Be not afraid.
It’s okay to be scared, but, be not afraid. Being scared is a reaction to an event; it’s an ephemeral feeling. Be scared when something pops out of a haunted house, but, be not afraid of ghosts. Be scared when you are about to go give a presentation but be not afraid of speaking your mind.
It’s okay — being scared alerts you, wakes you up, and brings danger to your awareness. Being afraid though? This is a state of being. It weakens you, drags you down, and sometimes, paralyzes you.
Be not afraid.
AST Explorer
Turns out you can not only transform JS into an AST, but even SQL statements! Pretty nifty.
the obstacle
See things for what they are. Do what you can. Endure and bear what you must.
neovim cache
If you’re ever having issues with neovim, it might help to clear out the cache.
I recently was running into issues after switching from packer
for my
dependency management to lazy
and there was a sneaky little devil 😈 in the
cache directory causing issues.
You can view the cache directory here: $HOME/.cache/nvim/
.
OAuth and OpenIDConnect
While working on my todo
app, written in go, htmx, and lit
, I forced myself
to get a better idea of how OAuth worked! I’ve used it before, but I never
really understood the flow.
This youtube video really does a good job summarizing exactly what’s going on ❤️ !
react-reverse-portal
Not gonna lie, I’ll probably never need to reach for this tool 😂, but I heard
about it while watching a video on Youtube and thought it was cool.
react-reverse-portal
allows you to render a react node and then take it out of
the dom entirely and return it later, without having to unmount the component.
It’s pretty neat!
vercel serve
TIL about serve
by vercel. It lets you serve your SPA/static files, incredibly
easily! We may or may not be using it at work for some of our SPAs 😉.
golang empty switch
TIL that golang allows for empty switch statements in the condition block. This is not possible in JavaScript! The reasoning behind this is that the switch statement in golang is not limited to only comparing values. Below you can see two versions of branching logic — one with the switch and one with else ifs 😊.
package main
import "fmt"
func main() {
i := 10
switch {
case i < 0:
fmt.Println("Negative number")
case i == 0:
fmt.Println("Zero")
case i > 0:
fmt.Println("Positive number")
}
}
package main
import "fmt"
func main() {
i := 10
if i < 0 {
fmt.Println("Negative number")
} else if i == 0 {
fmt.Println("Zero")
} else if i > 0 {
fmt.Println("Positive number")
}
}
Perplexity AI
TIL about Perplexity AI! It’s pretty slick and useful for web development and research 😊.
CSS Variables and fallbacks
TIL that css var
can accept a fallback! If we’re setting the variable with
some JS and this JS code for some reason or another fails to run, we can set a
sensible fallback and present our users with at least something adjacent to
what we wanted😊!
color: var(--someVariable, #888888);
The acquisition of knowledge
The acquisition of knowledge brings about satisfaction, but it’s application brings about fulfillment.
every returns true for empty arrays
every
on the JavaScript Array object is great since it checks to see if a
given callback function is true for every value in the array… but there’s
some caveats to it. Namely, every
will return true for the empty array, and it
does not take into consideration empty slots during its processing.
Refer to the following code to get an understanding of the caveats:
const isNumber = (v) => typeof v === 'number'
[].every(isNumber) // true
[1, ,2].every(isNumber) // true
[1, null, 2].every(isNumber) // false
scroll driven css animation
TIL that there is CSS scroll driven animations. They don’t have great browser support (still experimental) but I’m using it on my site 🤣.
Davinci's childhood
TIL that Leondard Davinci was the illegitimate son of a notary and a prostitute 😯!
node require cache
TIL that commonjs
has a require
cache. Basically, if you require a module
once in the file, it gets cached and if you attempt to require the module a
second time, EVEN IF THE CONTENT HAS CHANGED, you’ll get the cached version.
Usually this isn’t a problem but it bit me in the butt when I moved my remix app over to be using express. I had to call this function inside of my server code when remix finished rebundling.
function clearRequireCache() {
Object.keys(require.cache).forEach(function (key) {
delete require.cache[key]
})
}
tsx (the runtime)
Today I learned about Typescript execute (I’m using it on my website now too 😆). It’s a CLI alternative to node for running Typescript & ESM!
Panda - a new spin on css-in-js
There’s a new kid on the block and this new kid is a game changer! Panda is a new css-in-js solution that works in the server-first framework era!
neovim and chatgpt
I was googling around and saw that there was a plugin created to allow me to use chatgpt inside of neovim! I just downloaded it and I got to say, it is quite nice 😊!

ripgrep and chatgpt
So I switched over to neovim as my editor quite a while ago but to be honest, I’ve had a hard time grasping how to use telescope and ripgrep effectively. Thank god I have chatgpt around to help me figure out and explain basic commands!
Zahavian Signal
There’s a theory that for a signal to be honest, it has to be costly, otherwise everybody could imitate it. It’s why we spend a 1/4 of our salary on an engagement ring (that and being duped by the diamond companies) 😆.
Amor Fati
Amor fati is a Latin phrase that may be translated as “love of fate” or “love of
one’s fate”. This stoic concept mirrors similar philosophies such as Taqdeer
in Arabic, loosley translated as the absolute decree of the Divine or
Chardi Kala
in Sikhism.
tailwind-merge
While working on my site, I realized that there was a nifty utility that handles merging my tailwind classes for me!
develobears
Check it out; thank me later! Gotta love my besties!
cloudflare status headers
So I’ve been trying to add in some cache-control
headers to my remix site and
I’m using cloudflare as my CDN.
In order to determine if the cache is being hit, cloudflare adds a
cf-cache-status
header to the response. You can find out more about it in the
below blog post!
Say hello in Paris
Heading to Paris with a friend group soon and our research revealed that we should say Bonjour to folks as we encounter them in our travels. Stark contrast to Vancouver where no one says anything to anyone 🤣.
At a recent go meetup, I learned about a a cool thing to create cross platform
applications in Go: wails
.
@loadable/component
While working through my webpack config at work, I noticed the usage of
@loadable/component
. It’s similar to React.Lazy
but solves the issue of SSR
(which is a requirement for my work’s platform).
Object.fromEntries
TIL that there’s a nifty methd on the Object
type in JS: fromEntries
. It’s
the counterpart of entries
method that exists on the Object
.
Here’s an example for you:
let obj = { foo: 'bar', baz: 42 }
const entries = Object.entries(obj)
console.log(entries)
// Expected output: [["foo", "bar"], ["baz", 42]]
obj = {}
console.log(obj)
// Expected output: {} 😆
obj = Object.fromEntries(entries)
console.log(obj)
// Expected output: Object { foo: "bar", baz: 42 }
Air - live reload for Go apps
While working through my golang course, I came across a tool for live-reloading
golang apps: Air
A few good friends and I are going on a trip to Europe. Sheelz (one of my besties), found this awesome app to help us with planning our itinerary.
As I was thinking about how I would migrate my search index for my site to remix, I came across an alternative to Lunrjs… and yes I know I can use Algolia but I personally think it’s overkill for what I want for my site.
So there’s this thing called unified
that allows us to take things like
Markdown, HTML, or plain text and turns it into structured data (AST) so that we
can apply transformations on said data. Its rich plugin pipeline allows us to
typically write one line of code to chain a feature into a process.
It’s more than this though as it is collective
that spans multiple
organizations and an ecosystem that includes:
- remark
- rehype
- retext
- redot
fieldset element
TIL that there’s a fieldset
element in HTML that allows for grouping of
several elements in a web form.
This technology has been around for a while (> 3 years) and I haven’t used it
personally, but it’s pretty damn slick. IndexedDB is a low-level API for client
side storage. Its more popular brother, localStorage
has its limitations and
if you’re ever running into them, you might want to take a look at IndexedDB
.
In a nutshell, IndexedDB
is a transactional database system that allows us to
permanently store data inside a user’s browser. It would be useful for
applications that store a large amount of data and applications that don’t need
persistent internet connectivity to function.
Keep these key things in mind:
- It stores key-value pairs.
- It’s built on a transactional database model.
- The API is mostly async.
- It’s object-oriented 😲.
- It’s not SQL
- It adheres to the same origin policy.
container son
TIL that there’s a sick new css feature dropping soon: container queries
. I
haven’t played around with them much myself but based on what I’ve seen, they
allow developers to now not only make layout changes via css based on the
viewport but also based on the size of an elements containining element.
A lot of people are pretty hyped about this feature and calling it the next evolution of responsive design on the web.
It’s that time of the year again where we’ll be forking over some of our hard earned cash to retailers in preparation for the holidays. TIL camelcamelcamel exists and keeps pricing history of all amazon products.
Whenever you see a “sale” being listed on Amazon, make sure to check this site first 😊!
twix for tailwind and react
I haven’t used this yet and today I didn’t have much going on as I had to work on some stuff around the house (renovations and all) but there’s a project that tries to make it a little bit more ergonomic to work with tailwind and React 😊.
NeoVim is pretty damn fun
After being laid off from Productboard, I’ve been spending time thinking about how I want to continue with my career and what to do with my spare time. Of course landing a job is my priority, but during my time off, I want to devote time to learning skills and technology that I’ve never been able to make the time for in the past.
One thing I’ve always wanted to do (for the “by the way factor”) was setting up vim for my local development work. I devoted the entire day today to set up my neovim config; I’m pretty happy with it so far.
I was once asked about matrices in an interview. Still unsure how they work but we’ve got them in the browser specs 🤣.
matchMedia
My mind was blown today when I learned that browsers now ship with a native way to easily check if the window matches a specific media query. 🤯
Essentially, you can pass in a media query into window.matchMedia
and the
returned object will tell you if the window matches you media query. It also
ships with event listeners so you can handle resizing out of the box ❤️ .
Shout out to my main man Vepor for this piece of knowledge!
TS Utility: Extract
TypeScript has a handy utility type to extract
types from a union type 🤭.
type MyUnion = 'Hello' | 'Mom' | 'I' | 'Love' | 'You'
type WithoutMom = Extract<MyUnion, 'Mom'>
// the above will be the type "Hello" | "I" | "Love" | "You"
HTML attribute - inert
TLDR; this property, when applied to an html element will make it so that the element ignores user input (this also applies to screen readers).
React event.code
Turns out (at least at the time of writing this TIL), that react doesn’t include
the code
property on their Synthetic Events.
So if you wanna figure out which commit in a repo caused an issue, git has a useful command to do just that.
git bisect
Turns out there’s a way to improve event listeners that are tied to the scrolling event in the browser.
const onScroll = (e) => console.log('sup', e)
window.addEventListener('scroll', onScroll, { passive: true })
This will make it so that our scroll handler will not block the main thread (yay!).
Intelligence and Wisdom
Intelligence is knowing a tomato is a fruit. Wisdom is knowing you don’t put a tomato in a fruit salad. Charisma is convincing everyone that it’s a salsa.
Brought to you by Christine.
esbuild-loader
There’s been a lot of new developments in the space of package bundlers. From the OG Webpack to, Rollup to the new kid on the block esbuild each of them have their own unique set of features.
esbuild offers better build times as it is written in Go, which is compiled to JavaScript. The tradeoff here is that es5 isn’t supported (but that’s okay if you’re not supporting IE11). It’s pretty awesome but as it’s in active development and fairly new, it’s not as widely used as the other bundlers and therefore doesn’t have the rich plugin resource that somethings like webpack has.
However, you can leverage esbuild and plug it into a webpack config and via esbuild-loader I did this at work today and it helped with devserver startup times and greatly improved the production build times.
There’s a reason why React is moving toward a linked list approach and moving away the recursive approach used in the current reconciler.
Recursion requires an O(n) call stack (causes jank). But if you do things iteratively, you can stop relying on stacks and push all object references into the heap. Arguably this is harder to reason about and harder to understand but the perf gains are totally worth it.
Document Fragment
So there’s this really handy web api that allows you to create a lightweight version of a Document and append nodes to said lightweight Document. The beauty with this is you can create this tree, make changes to it, and then all at once append the lightweight tree to the DOM.
This is much better than continually writing to the DOM and causing a shit ton of reflows.
Feelings
It’s normal to sit down with a few negative feelings about beginning your work. It’s how you handle those feelings that matters.
History scrollRestoration
Turns out you can set up auto scroll restoration with browser APIs (yay!).
Post-Order Tree Traversal
Learned about another way to traverse a tree! It’s called Post-Order.
Essentially:
- Go left as far as you can
- Go right as far as you can
- Visit Node
GET vs POST
All you need to keep in mind for a GET
vs a POST
. Basically, POST bodies are
not limited whereas the GET values are limited by a character limit for the
value.

TypeScript Utility - Required
TIL that there’s a TS utility type that does the opposite of Partial
.
Require Generic
Want to make it so that people need to provide some sort of generic argument if they don’t use some predefined defaults for your TS code. Check this out:
type NoInfer<T> = [T][T extends any ? 0 : never]
type QT<T> = 'first' | 'second' | T
type Yolo<T> = {
data: QT<T>
}
function doSomething<T = void>(args: Yolo<NoInfer<T>>): null {
// do something
return null
}
doSomething({ data: 'first' }) // okay
doSomething({ data: 'three' }) // not okay
doSomething<'three'>({ data: 'three' }) //okay
RTK query and React Query
State management is hard but there’s a difference between state management in our apps versus managing our app’s server cache. Luckily, there are two libraries that we can use to help us with our server side state needs.
React query and RTK Query. We’re using React Query at work but RTK query looks cool too!
I’ll probably do a small POC this weekend to get a feel for the ergonomics.
Dates and stuff
Whenever you’re going to be talking about dates, keep these things in mind:
- Formatting (locale)
- Timezone (this dictates how much time to add based on UTC)
- UTC (know what this is)
Easier shell scripts
There’s a nifty little library to write shell scripts using node. Yay for less hassle!
DateTimeFormat
Turns out that there’s a neat little time formatter that most browsers ship with that allows us to do locale specific time formatting. It’s inside of the Intl.
Intl.DateTimeFormat('en-US').format(Date.now())
Carl Sagan + Weed
Turns out Carl Sagan was a big proponent of Marijuana. Who knew lolz.
How to deal with a stye
Lol so I got a stye and a home remedy that I’ve been using is a tea bag.
You steep the tea bag for one minute and when it’s bearable, rest the teabag on the affected eye for 5-10 minutes. Preferably use black tea.
Ambient TS files (*.d.ts)
Alright, so I’ve been writing TS for a while and was never really sure why we
needed these .d.ts
files… until today.
The purpose of these files is so that authors/the community can backport popular JS libraries with TS type definitions. This allows library authors the freedom to keep on writing their JS code but allows users of TS to benefit with working code and the typings they need.
These typings probably exist in something like Definitely Typed. However, at work, we’re using a mix of JS and TS (JS is for the jest setup code) and therefore we were required to have ambient TS files so that our TS test code could benefit from the typings related to our JS files.
We are using module aliasing for our TestUtils
so that we can do things like
import { render } from 'TestUtils'
. Under the hood, the render function is
just a nicely wrapped render function from react-testing-library and so the
return types are the same. There was a bug where if I tried to import the
RenderResult
from the testing library, VS code’s TS language server would yell
at me for having an undefined module. The following code highlights the
fix/issue.
// TYPESCRIPT IS A PAIN
// https://stackoverflow.com/questions/39040108/import-class-in-definition-file-d-ts/51114250#51114251
declare module "TestUtils" {
export function render(
v: any,
other?: { initialState?: any }
): import("@testing-library/react").RenderResult
}
// doesn't work
import { RenderResult } from "@testing-library/react"
declare module "TestUtils" {
export function render(v: any, other?: { initialState?: any }): RenderResult
}
document.activeElement
If you want to know what element on the page currently has focus, you can use
document.activeElement
to get access to the reference of the currently focused
element.
I’m using it to handle the /
key to force my website to move focus onto the
search input (similar to what github does) and to not try to make the site
refocus the search if is the currently active element.
React.FC - don't bother
React.FC
was more meant to help beginners get more comfortable writing React
components with TS but honestly, the cons of using it (always having the ability
to pass children
to your component even though you might not be rendering said
children
) make me want to not use it.
If you’re wanting to type children
, you can do:
type Props = {
children?: React.ReactNode
}
Typescript Conditional Types
Turns out TS has some conditional types!
T extends U ? X : Y
If T extends U, then T is type X otherwise it is type Y.
TypesScript Utility Type - Parameters
There’s a neat little utility type in TypeScript that lets you reach into a function and discern the types of the function arguments.
Parameters<(s: string) => void>
// [s: string]
There’s a neat little css function that lets you retrieve the value of an attribute of the selected element and use it in the stylesheet!
For example:
<h1 data-color="red">Hello</h1>
h1 {
color: attr(data-color);
}
Would generate an h1 with red text!
react-testing-library screen
So turns out there’s a handy screen that react-testing-library exports. Don’t always have to use the container!
Good design
While working my way through The Pragmatic Programmer I came by a tip that really struck a chord with me. Good design is easier to change than bad design.
Make things easier to change. Why is decoupling good? By isolating concerns, we make each easier to change. Why is the single responsibility principle good? A change in requirements is mirrored by a change in one module.
Wood filler
If you’ve created too large of a hole inside of your drywall and you want to reuse the same hole for perhaps a drywall anchor, using spackle as filling won’t be enough.
Use wood filler; this’ll give you the consistency and strength you need for loadbearing purposes in the drywall.
Namespace pattern in React
So I’ve seen this pattern around but didn’t know it had a name! If you’ve ever
used Context in React, you’re aware of there being a Provider
and a Consumer
and those two are namespaced to a specific Context. Keep in mind, this is
assuming you’re using React < 16.8.0.
I’m still trying to figure out when this should be used.
const SomeContext = React.createContext()
const SomeContextProvider = ({children}) => {
const [yolo, setYolo] = React.useState(false)
// highlight-next-line
return <SomeContext.Provider>{children}</SomeContext.Provider>
}
const SomeContextConsumer = ({children}) => {
return (
// highlight-next-line
<SomeContext.Consumer>
{context => {
if (context === undefined)
throw new Error('Must be used within a SomeContextProvider')
return children(context)
}}
</SomeContext.Consumer>
)
}
So if you have an element positioned absolutely in a container and the container has overflow hidden the absolute element is gonna be hidden.
Need a structure of grandparent (relative position) > parent (overflow hidden) > child (position absolute)
CSS ID's cannot start with numbers!
Bruh, you can’t do something like document.querySelector('#1')
and expect it
to work. The browser will yell at you! You have to do
document.querySelector([id='1'])
Valid header values
Turns out header values are always strings. So if there’s a header value like
x-header and you want to see if it is true or false in JS, doing
Boolean(req.header[‘x-header’]) would be true
regardless because “true” and
“false” are both true for Boolean
constructor.
You can do something like req.header[‘x-header’] === ‘true’
4 tools from twitter
Massive SVG and art board sizes
So lol when I was exporting an SVG from Affinity, I noticed that the svg size was around 3 mb. Reducing the art board size made the export size waaaay better.
affinity designer
Turns out we aren’t forced to be shackled to the Adobe suite 🤣. There’s similar software called Affinity that does pretty much what Adobe does (without the arm and leg payment).
VSCode regions
TIL that vscode has region folding! It’s like this:
//#region
const y = () => {}
const x = () => {}
//#endregion
Don't forget about closure
Not really a TIL but more of a reminder to myself to not forget about the damn concept of closure and to leverage it in Scala. Just because you have one function to handle sorting, doesn’t mean that function can’t have some helper functions defined within its body.
content-editable
Turns out you can have a contenteditable
attribute on your html and that’ll
make (you guessed it), your content editable lol.
…go ahead… try it out on the list below… you know you want to. 🤪
- Food
- Food
- Food
Collapsing Margins
So today at work I noticed that I was not getting the spacing I expected from block level elements. The reason this was occuring was because my team and I were relying on margins for spacing out elements, but we should have been relying on padding instead.
Margins collapse in on each other (for siblings). If element A has a margin bottom and element b is its sibling and underneath and has a margin top, we would see the margin bottom of element A “collapse” (not be applied) and only see the margin top of element B.
Printer ink
TIL that printer ink requires a vehicle (a resin like honey) and a pigment (a powder). There’s a lot that goes into this process and it is pretty damn cool.
Credit card skimmers and shimmers
TIL that there are credit card scams around like skimmers and shimmers that oftentimes show up at gas station pumps and other brick-and-mortar shops.
To avoid being a victim, do not pay at the pump if they require you to insert the card at the pump (these pumps can be tampered with whilst the inside card reader most likely will not be). Pay with tap when you can
Also, don’t forget to check your transactions regularly and check out free credit reporting services like Borrowell.
Abstract classes vs Traits
So Scala is a single inheritance language but allows classes to utilize multiple
traits (these are like interfaces in Java). Traits
and Abstract
classes in
Scala are essentially the same but there are some key differences.
- Traits cannot have constructor parameters (you can’t do a new trait)
- A class can inherit from multiple traits.
- Traits are for behaviors. Abstract classes are for things.
toFixed vs toPrecision
toFixed(n)
provides n length after the decimal point; toPrecision(x)
provides x total length. Both will round! Both are functions that exist on the
Number prototype!
learning-repos
There’s so much to learn and more than enough time! Here are some cool links to check out.
While working on a javascript monorepos course, I was exposed to Volta.
Volta eases the node development process by allowing developers to easily pin node versions to a project and will automatically switch the development machine to the right version when switching between contexts 😃.
Mac emoji keyboard
TIL keyboard shorcut for emojis on a mac is: Command-Control-Space
TIL that there is a cache control header for a shared cache. The s-max-age is similar to the max-age in that they both set a timer to invalidate a cache for a particular resource. The difference between the two is that the s-max-age applies to shared content and therefore applies to content on a CDN.
This is better in circumstances where we want to force an invalidation for a particular resource. This is not possible with max-age.
Resort Area!
TIL that there’s a dope resort spot in South Asia. Maldives.
npm i prefix
So you can actually run an npm install for a directory without having to
actually change directories. Look: npm install --prefix /my/project/root
Netlify Identity Widget
There’s a Netlify Identity Widget (that is framework agnostic) which can be leveraged to add some authentication to web apps deployed to Netlify.
There’s a limit of 1000 people but for a small e-commerce business that’s more than enough.
react-window
If you’re rendering over 50 rows in react-table and messing around with
complicated filter logic, it’s wise to utilize something like react-window
to
get some performance gains as users are not going to be interacting with
elements not in the viewport so we shouldn’t tax them for the rendering costs
behind such frivolous elements.
toLocaleString
TIL that there is a method built into the Date object toLocaleString
. It
essentially allows us convert a date string to a locale specific string.
useLayoutEffect vs useEffect
99% of the time you want to be using useEffect
but there are some rare use
cases for useLayoutEffect
and I incidentally ran into one today at work 😂.
useLayoutEffect
if you need to mutate the DOM and/or perform some measurementsuseEffect
if you don’t interact with the DOM at all.