The stream is a personal feed of my thoughts on things I’m working on, interested in, or a random shower thought that might be worth putting some additional thought into. The stream is a form of expression, posting something spur of the moment, without the crowdedness of a social network like Twitter or Facebook. Don’t get me wrong, those places are great for comment and reply interactions. But I also need my own trail of what I’m writing and thinking about that’s not hammered by likes, comments, and other social features that I find distracting.
There’s something nice and calming about seeing half-formed thoughts and ideas on a screen that’s wholly yours. I wish there was more of this kind of web. I was drawn to Tumblr back in 2008 because you could Microblog before you had a Facebook, LinkedIn, Twitter, Threads, or your variant of Fediverse website. Or even prior like posting your thoughts, fan-fiction, and other inspired writing on LiveJournal. Nowadays, that’s all we read from and post to. Or graduated to video like an algorithmic feed like TikTok. No shade for these companies vying for our limited attention. I think I’d rather take it slow and read some stranger’s beautifully designed blog that has little nuggets than an endless scrolling monstrosity that makes you wonder why you’ve spent hours on Reddit, but can’t recall much of what you did.
There’s more I want to add here, like better search capability, pagination, and an updated description of the stream. It’s designed minimally to emphasize the point that it’s not supposed to be too rich nor attention grabbing. And its flow is based on my writing, and no one else. Welcome to The Stream.
For the past few years, I’ve kept a note of inspirational websites. These websites include blogs that I continue to follow, creatives showing their talents, and web design that makes me wonder. I remember years ago, Ayush and I would break down websites that made us go, “How did they do that?” and reverse engineer them. It was interesting going into the source code, trying to solve how someone managed to wrangle with CSS to create a pretty infinite scrolling experience.
I wanted to share some of those websites with you. In the inspirations section, I break down which websites I’ve found and share them with you. I am starting with people whose work I admire and ideas within it that I want to remix back to this website.
Sometimes these websites are minimal, and there’s elegance to it. Sometimes, there’s a lot of interactivity and media, and it’s not overwhelming. When I think back to this website, I’m constantly wondering what I could add, and more importantly, remove. It’s a constant battle to strike the right balance in design.
Watch out for more updates to inspirations, including written work, YouTubers, and so much more. There’s overlap with creators, but that’s a deeper dive into an artist’s work. I’m looking forward to updating these inspirations from time to time.
As a kid, I love reading the classifieds in the SF Chronicle. It was an interesting time to see it in the advent of Craigslist. Of course, this is by no means an alternative to Craigslist. It is hardly a place for others to add classifieds. This is more like a personal space I can add a wall for you to tear a piece of paper like on those coffee shops for finding a gardener. Except it’s more specific to my own tastes.
In the coming months, I plan to add much more to this. It’s like a personal ad system that probably has better click through rates (jk). I loved Metafilter’s ads since they were more tailored to their audience. This is not a paid sponsorship or ad board. I don’t get paid for this, at least for now. If I do in the future, I’ll be sure to put my disclosures in the classifieds.
If you have any classifieds you want to share, feel free to email them to me. I’ll review them personally for now.
And maybe in the future I can add a “missed connections” section. I love easedropping on people’s first time dates, which have been plenty this past year. I plan on writing some short stories about them in the future.
I’ve been pretty active with the website updates. I thought it might do me a little good to start adding a short changelog to the website. This sounds like it will be different than my now page.
Around the Website
Re-arranged the tags so it is better formatted in-line with the published date
I’m also coming up with more ideas of what to do next. I’m thinking about doing a microblog inspired by Linus’ stream. I’m getting inspired from “From Jason” Where Have All the Websites Gone and how he thinks we should trade in our linktree links with things that we like on the Internet. Hell, if I think about my own patterns, they used to be on curated link aggregators.
Episode #171 of Have You Heard podcast: The Damage Done - There’s a large discussion happening about public education right now, and teaching to the Common Core. It’s not pretty, and makes me think hard about sending my kids to public schools
I tried talking to ChatGPT today and using voice as an input. While learning Mandarin might not be there yet (the AI voice doesn’t recognize tonal languages as well), I can see it being good for my Spanish.
I’m proud of the re-write I’ve made towards curations. The idea behind this was to combine the things that I’ve liked, consumed, gestated on, and share with you my thoughts about different things that matter to me.
For my books, I wanted the feeling you get at the bookstore where I write a short blurb about why you should pick up this book. I would spend the first few minutes reading the index cards nicely decorated about why the staff member chose a specific book. There was more potential for a chance encounter. When I read listicles online, there’s often a sense of sameness. It’s not as fun when websites all feel the same.
The same about films in a video store. I love the feeling you get, back when video stores were more popular, about staffpicks. Some small streaming services have this feeling, like FilmStruck, and more recently the Criterion Channel. When the Netflix algorithm is feeding you, or for that matter any algorithm, that hand-feel of someone’s journey into film has turned into “this is what thousands of people in your target demographic cohort also like”. And there’s something missing from that. I want to share what I like about a film, or dislike. And I also want to share why other people appear to have similar or dissonant feelings about it.
People shouldn’t feel boxed into groups of “books I like”, “movies I like”, and “music I like”. It makes everything feel dull, like these are the only categories that define our dating profile. And while I’m starting off with the books and music, I can think of other things I want to curate in the future. One thing people might not know about me is I own a 20+ year old business card collection. It reminds me of places I’ve traveled or people I’ve met. I also want to share a inspirational persons curation of people who I love and have made an impact.
Aside from everything else, I want my personal MySpace back. Back in the day, you would have a customized profile page where you make it play your favorite music, share your favorite lousy quotes, and give it your own personal flair. Even if that flair was like design vomit. It was your vomit. So with that, I’m having a little fun giving you multiple perspectives on what is essentially a listicle. But it’s my listicle. And I can call it something other than a listicle. Like an curated art exhibit. That sounds so much more sophisticated. You’re welcome.
If you missed the link above, check out curations!
Over the past month, I have been making small enhancements to make the website 1% better. I’m excited to talk about many of them, some noticeable, some under the hood.
Major Updates
Tailwind, 🌑 Dark Mode, and Solving My Woes with Styling
Some major updates are around styling. Previously, I was using some CSS files to style the different pages. However, after a lot of tinkering with Tailwind, I went full in. And boy has it made it easier to update styling, especially around media queries.
I hate to think about media queries, write a quick template or some variables, when tailwind makes that super easy. Add to your classes, sm: or md:, or lg: and you’re good to go for what you want to style at a specific breakpoint. What it means is, you have to think about your smallest width first, then move on to where you want your next breakpoint and add that utility class.
Where I immediately saw this benefit was a bug I found with a list of navigation links. With a little bit of tinkering, I was able to make the classes from flex with a default of no wrapping, to flex-wrap then md:flex-no-wrap to get that desired effect.
Another super helpful thing was immediately adding dark mode support. With the prefix, dark:, it made my life so much easier. I saw some initial places where I needed to modify the website immediately, and having this utility class prefix allowed me to get straight to styling vs. thinking about CSS selectors and rules. That said, having a background in CSS is a huge help, and even if I had to write only CSS, I’d still be operable.
Also, you may now notice there are links next to headings. That’s all thanks to installing my first rehype plugin! I had no idea there was such a rich community of rehype and remark plugins for all different use cases. I’m excited to explore more of them.
Lastly, my RSS feed has been updated. The books and films are added to the main feed, as well as styling the feed page itself. I didn’t know it used a .xsl file, and I used a generic template.
New Collections 📚 🎥
I expanded on my library. The films, anti-library, and book reviews have been added. The lindy library is passable and needs a bit more design and explanation. I’m proud of adding the log alongside the movies and books. I plan to link the log back to those pages too, where I can.
A lot of tinkering with Tailwind helped make this a lot easier too. I knew the design needed to look a little different, so for the past month, I’ve been browsing the pages on my own until they looked the way I wanted.
Content Updates
My resume, about page, now page, and many, many other pages have been updated. This was a long time coming. For years, I’ve kept the same about page, being about the “brief” version vs. the Twitter version vs. the LinkedIn version. I don’t think that represented me well. After some inspiration from Derek Sivers’ about page, I restarted the process from scratch. I thought more about it as an autobiography, rather than a professional LinkedIn page. It’s a lot more personal, and hopefully, that shines than the corporate version that I wince at.
Search 🔍
I installed the Algolia Crawler earlier in the month and finally had time to add a search component over the weekend. A little more refinement is needed to get the search results to display correctly (specifically removing the navigation text), but we’ll get there.
Under the hood 🚘
Getting the initial setup with Netlify was a major lift. Everything else has felt like a smaller lift, but also necessary. For example, dependabot wasn’t installed, so I made sure dealing with package updates was automated. I included meta tags that were missing for SEO purposes, verifying Twitter cards and Open Graph links (like LinkedIn) to work correctly.
What’s next?
Honestly, I’m going to take a step back and work on the content. While I’d love to update the Lindy Library, I’d much rather do what I do best, and write more blog posts. I have been working on a personal content pipeline to gather ideas, slowly work through books, and put my own take out there.
If there are any issues you find with the website, feel free to open an issue on GitHub. Ta ta for now 👋.
Changelog
#43 Add Github Actions to automatically tag the repository by semantic versioning
#45 Migrate from vanilla CSS to Tailwind CSS
#48 Dark Mode added!
#50 Additions to “Logs” - Add concert and musical for 2023
#51 Addition to “Library” - Add a brief lindy library
#54 Install Dependabot to Github project
#60, #61 Add first rehype plugin to add relative links to headings
#62 Netlify configuration - add security headers and update timezone
#66 Added top navigation for blog
#75 Expand on the films section and add them to the main page enhancement
#76 Extend press to include more talks, papers, and updated formatting enhancement
#82 Updated meta tags for SEO. Twitter cards and Open Graph links should correctly render updated hero images
#86 RSS page styled, should make it a lot more readable
#91 Migate blog posts with book reviews to the library book detailed pages
I decided to re-write my personal website back in 2017, when I was much more active in writing on my blog. However, that changed quickly when I abandoned making updates in 2018 when I started my job at Clear Labs. There was no longer any time to write as we were working on their Clear Safety product.
I’ve had one or two failed attempts at doing a full re-write, and never fully committed to doing it until this past month. Part of the reason is I dreaded the migration from Jekyll. I knew most of my content was in markdown, but there was this fear in the back of my mind like it was an insurmountable task. Of course, that’s a fallacy, and when you know you could do other things with your time, this project inevitable went into my backlog.
Comeback with Astro
I’ve been itching to write again, and the urge trumped my fear of the migration. I decided to use Astro as my static site generator, with plans to run it as a server as a future. I wrote a small project in Astro, and thought how delightful it was, so I decided to see what the starter had for its blog starter kit. I was pleasantly surprised. It had a great base foundation to start migrating over blog posts, as long as I followed their markdown frontmatter, typically written as Yaml. By taking a look at their base schema, I could easily re-adapt the posts and get something rendering on the page write away.
import { defineCollection, z } from "astro:content";const blog = defineCollection({ // Type-check frontmatter using a schema schema: z.object({ title: z.string(), description: z.string(), // Transform string to Date object pubDate: z .string() .or(z.date()) .transform((val) => new Date(val)), updatedDate: z .string() .optional() .transform((str) => (str ? new Date(str) : undefined)), heroImage: z.string().optional(), }),});export const collections = { blog };
I needed additional metadata for my blog posts, like tags, post type, and a boolean for whether it was a draft.
I’ve created Next.js and Remix projects before, so the file-based routing system was intuitive. The preset included a blog folder with an index.astro and [[...slug]].astro file pre-filled. This made it super easy for my to figure out what was going on by reading the code and commenting the parts I didn’t understand.
After the blog posts migrated over, I quickly threw myself into the other pages that weren’t migrated over, specifically the about page, projects, logs, and newsletter series. Each of those became their own schemas. I updated their markdown frontmatter as well, and the personal site started to look like my old site again.
Deployment
The website was using Netlify, and while I personally would’ve preferred Vercel, it was a good choice. I setup some Github actions to continue to push to Github Pages as well. Netlify’s migration was a pain, because the configuration and its cache were set to build to Jekyll’s configuration. Migrating it over to Astro took some finagling to get the settings just right. I spent a good evening scratching my head until I found the correct environment variable to set it to.
A Side Note about Git
I created my old blog back in 2014, and I was still using master branch as the main branch. With this migration, I moved it over to main. For configuration reasons, it was having trouble moving over in my CI pipeline the first two or three builds. So please remember to check your settings.
Styling
At first, Astro gives you the css from the Bear Blog. While the minimalism was great, that’s not my type of styling. So I adapted it until it started the look the way I wanted it to. Quickly, I realized this isn’t going to be scalable. While astro limits their styling to the component you’re working on, it wasn’t good enough. And the global styles weren’t to my taste.
I knew I wanted to use Tailwind in a full project. Previously, I’ve only used it for tiny pet projects. I went full in immersion. At first, my global styles were being modified by the base.css injected styles from Tailwind. I put too much effort in trying to modify them when I realized, “I started from a base project, and I don’t need these base style files”. That’s when I stopped caring about my blog’s styling conventions and migrated over to Tailwind’s conventions.
Sometimes, it’s hard to break hard habits. The mantra of “Convention over configuration”, as heralded by Ruby on Rails”, was echoing in the back of my mind. While I am not fully migrated over to Tailwind yet, I plan to.
Conclusion
There’s a bunch of things left-over from this migration that I have to still work on.
Analytics (ideally, an alternative to Google Analytics)
Add filters for the writing so you can filter by tags
Migrate over my Newsletter from TinyLetter to Buttondown
Overall though, I’m happy with my switch, and plan on working on my website more. Astro makes it incredible easy to add components from other libraries that I’ve worked with in the past (personally used React, Vue, Svelte, and Solid), so I plan on making more interactive blog posts and projects for this website in the future.
If you have any questions about the migration, want to give me feedback, or would like some help on your own Astro blog, feel free to email me. I’m always happy to help. (Email is in the footer of all pages).