aboutusesTILblog

Today I Learned

Get the RSS feed for Today I Learned

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.

Check it out

ts05.05.2025

ts-reset

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!

Check it out

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:

taranveerbains.ca
<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>
js02.05.2025

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 😆!

Check it out

js22.04.2025

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>
	)
}

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!

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.

Check it out

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.

Check it out

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')

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.

Check it out

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.

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 😆!

css05.03.2025

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!

Check it out

js04.03.2025

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.

Check it out

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.

Check it out

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>

TIL about wxt! It’s like Nuxt but for web extensions.

Check it out

cool tech14.02.2025

sqoosh

TIL about a local first tool for image compression called sqoosh. No more sending images to random servers just to compress them! 😆.

Check it out

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.

Check it out

css08.02.2025

CSS tidbits

TIL about the following…

inset-property.css
    /* top, left, right, button, are all set to to the same value */
    .box {
      inset: 0;
    }
  1. The inset property is a shorthand for top, right, bottom, and left properties.
  2. Absolute elements can only be contained by other elements using Positioned layout.
  3. Positioned elements will always render on top of non-positioned ones
  4. 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 and z-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.
  5. 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 a position: relative and z-index to the children. It is the lightest weight way to create a stacking context.
  6. The z-index property can be used in a flexbox the same way as it can be used with a positioned element.

TIL about the stacking context inspector. It’s a tool that allows you to inspect the stacking context of an element.

Check it out

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.

js30.01.2025

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.

Check it out

cool tech29.01.2025

zoxide

Til about zoxide which is a faster and more robust cd alternative; it lets you navigate your filesystem faster and more reliably.

zoxide-examples
 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>

Check it out

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.

TIL that you can edit the whole document with document.designMode = 'on'!

Toggle document.designMode

Check it out

Happiness = results - expecations-unknown

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.

Check it out

js07.12.2024

docsify

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 😆.

Check it out

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.

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>

Check it out

TIL there’s a tool that can help you find out if your types are wrong for your library!

Check it out

Til about raycast! The productivity tool that our macs should have shipped with ❤️

Check it out

Struggling to choose the right license for your project? There’s a great tool for that!

Check it out

finance22.10.2024

wave app

TIL about wave app! I’m using it to track my expenses and the invoices for my company! It’s pretty cool.

Check it out

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!

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.

Check it out

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',
)

Check it out

Need a tool to help you manage your versioning and changelogs? Check out changesets!

Today I learned how to create multiple Neovim Configs. I’ve set up a home and work config respectively.

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
'

Check it out

Interpolation is defined as “the insertion of something of a different nature into something else.”

backend09.09.2024

orbstack

TIL about orbstack — a fast and lightweight way to run containers on a Mac!

TIL that there’s a tool to help you apply color filters to your dom nodes!

Check it out

TIL that Storybook has a way to specify the behavior of argsArgeTypes. 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

Check it out

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

TIL about e18e (Ecosystem Performance). It’s an initiative to connect folks and projects working on improving JS package performance.

Check it out

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)

the-old-and-new-way
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!

Check it out

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

TIL that the button html element accepts a form attribute. This is cool because it allows you to associate a button with any form, even if it’s not a direct ancestor of our button! How cool is that ❤️!

Check it out

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.

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!

😆 while going through a CSS workshop, I came across this list of CSS mistakes. Be humble folks. We all mistakes.

Here’s a list (probably not complete) set of inheritable css properties.

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 })

Check out this dope tool for understanding the React internals! So dope!

Never make a decision in anger, and never make a promise in happiness

-Imam Ali Ibn Abi Talib

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.

js08.05.2024

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!

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.

Our goal is not to remain calm while suffering but rather to experience a setback without thereby suffering.

css01.05.2024

unset

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.

Check it out

js30.04.2024

bundlephobia

If you ever want to know (sort of) the cost of adding a package to your node app, you can use bundlephobia!

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.

how-to-find-and-replace-in-vim
"while in your quick list
:cdo s/your-search-term/thing-to-replace-with/g

"go to quick list after changes
:wa <CR>


During office hours with Kent, I learned about semver calculator!

It seems pretty dope and I’m going to use it in the future!

js10.04.2024

GROQ

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.

Check it out

TIL about a sick template for building a headless shopify theme with Sanity and Hydrogen.

Check it out

If you pass in a name, it’ll behave like an actual accordion. Thanks Adam Argyle!

Check it out

js14.03.2024

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 🤔!

TIL about dotenv.org! You can use this to share and sync your .env files across machines/teammates. They also allow for the ability to encrypt your secrets and use them in your CI/CD pipelines.

The neat thing about this if someone leaves your company and you don’t have a fancy IT setup, you can just change the keys on the dotenv side of things and the keys the user has on their local machine will no longer be valid!

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!

wont-work.css
: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;
  }
}
css19.01.2024

stylex

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.

Check it out

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 😃.

Check it out

To gamble on yourself is to risk failure. To do it in public is to risk humiliation.

Our fear, like a self-indicating arrow, points to the things we ought to do.

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!

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 columns
  • align: deals with rows
  • content: deals with the grid struture
  • items: 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.

Check it out

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.