Hello, World!

23 April 202417 August 2026Web14 mins read

Updated 17 August 2026: This post describes the site’s original Astro and Svelte build. The site now uses TanStack Start with Vite+. TanStack Start provides the Router-based React application layer, while Vite+ brings development, builds, linting, formatting, and related tooling into one workflow. The original sections remain below as a record of how the site was first built.

Why this website?

I’ve wanted to create this website for a very long time. Back in 2022, I wondered what I would do with a website if I ever built one for myself. I’ve always loved journaling in large notebooks or private digital applications, but I also wanted a personal digital space where I could share my thoughts, tutorials, and interests with my friends on the internet (or for myself in future).

It took me some time to streamline my ideas for the website without going beyond my scope. In 2023, I began researching how personal blogs and websites are managed effortlessly and sought a suitable tech stack to work with. I needed an easier way to handle a large amount of content. Most websites tend to be heavily interactive; I was looking for the perfect balance.

What kind of features I want in website?

  • Creating a cozy, modern, minimalist website.
  • Using intuitive icons for blogs, settings, and navigation.
  • Minimalist settings for themes, sounds, and layout.
  • Command palette for quick access.
  • Displaying Discord activity on the site.

So about the tech stack..

Since this is my personal website and project, I wanted to try something that's quite trendy and for the right reasons. These were the important tools and dependencies when I first built it:

Current stack: The site now uses TanStack Start, React, Vite+, and Tailwind CSS. Icons come from selected Iconify JSON collections and are rendered through the site’s own React icon component.

There were a few more dependencies based on the tools above. I discuss them in each section as part of the original implementation.

Layout

From the beginning, I wanted to create a cozy website with a two-layout sidebar for the desktop view and a bottom-bar navigation for mobile view. As a result, I spent a considerable amount of time prototyping it.

The Desktop View

  • Desktop view has a left sidebar with navigation links.
  • A footer is present at the end of the sidebar.
  • A Command Bar is at the top of the main content for productivity that includes the Command Palette and Settings.
Desktop View
Desktop View

The Mobile View

  • Mobile view has a bottom bar for navigation.
  • Special menu button opens more links and settings.
  • Designed for easy reading with one-thumb scrolling.
  • Simplified Command Bar in the menu bar only.
Mobile View
Mobile View

Pages

I’m listing the pages I want on my website and discussing how I addressed any issues I encountered.

Home

  • Simple introduction to important pages and a bit about me.
  • Happy with current setup: hero section, latest blog posts, snippets, and skills.
  • Future plans: add side projects and favorite bookmarks.

Blog

Also, you are reading this blog currently 😈

  • Repository for lengthy writings with categorized and tagged posts.
  • Happy with current setup: blog cards, sorted posts by year, and color-coded categories.
  • Future plans: improve filtering options and add reaction feature to each post.
Astro’s Content Collections originally loaded these posts and optimized their images at build time.

Current implementation: Vite discovers the MDX files with import.meta.glob, Zod validates their frontmatter, and vite-imagetools handles post-image transforms during the build.

Snippets

  • Collection of small codes, tips/tricks, and tool installations.
  • Happy with: snippet cards, sorted posts by year, and color-coded categories.
  • Future plans: enhance filtering options similar to the blog page.

Uses

  • Showcases tools used for projects or productivity, well-categorized.
  • Happy with: transitions, categories, and tool icons.
  • Future plans: enable one-click installs for each tool.

Features

Interactive/non-interactive features were created specifically for this website. I’ll discuss the struggles I encountered and what I aim to improve.

Branding..

For a long time during the development phase, I was using a picture created by Kostur, and I really liked it. I was content with it. I love his minimalistic artistic take on it. I will always use it for Discord. Thank you, Kostur!

Kostur's Take
Kostur's Take

However, I wanted a more cozy logo in general. My wife started making pixel art this year and began drawing me in various ways. She enjoyed doing it, and we ended up loving this one. It fits the color schemes and vibes of this website better, and I am happier with it.

Oh by the way, hover over the sprite - it's animated too 🥳.

Ashfid

This is just the starting of many animations for the sprite. There will be more animations doing different kind of activities for more context on each page.

Astro Content Collections

This section originally documented an Astro Content Collections setup using defineCollection, getCollection, and astro:content. That implementation has been retired.

Replacement: Posts remain MDX files, but src/content/index.ts now imports them through Vite, validates the exported frontmatter with Zod, and exposes typed blog and snippet collections to TanStack Start routes.

Discord Status - Lanyard

I wanted to display my Discord activity or any digital activity I’m doing, like playing games or listening to Spotify. I found a great app by Phineas called Lanyard. Thanks to Nuro that mentioned this application, it was great read about it.

In short, you join Lanyard’s Discord server and make sure the activity status privacy is turned on. Then, you get your Discord’s developer ID and use it to connect to Lanyard’s websocket server or REST API. I originally used svelte-lanyard to connect the Svelte implementation.

Current implementation: The React status card now uses the use-lanyard hook and reads the Discord ID from the validated site configuration.

Discord Status Activity using Lanyard
Discord Status Activity using Lanyard

Command Palette

I'm a big fan of command palettes in editors like Visual Studio Code. They make navigating through files and settings a breeze, and finding what you need is usually a one-shot deal.

Creating such a feature, however, is complex, mainly due to accessibility and behavioral considerations.

Visual Studio Command Palette
Visual Studio Command Palette

Like any other front-end developer, I searched for packages to help me out. Surprisingly, all I needed was a robust fuzzy search package: Fuse.js, the ultimate JS library for fuzzy search.

Now, let's talk challenges:

  • Trapping tab focus within the palette for better accessibility.
  • Enabling storage of commands via any external component.
  • Making the palette keyboard-responsive.
  • Assigning unique IDs to each command button without disrupting search order.
  • Grouping search results into sections post-search, which proved tricky and still needs refinement.
  • Keeping the input focused while changing selected commands with the arrow keys.

Despite these hurdles, the palette is now deployable. Improving command addition implementation remains on the to-do list for another day.

My Command Palette (ignore the command titles)
My Command Palette (ignore the command titles)

Settings

I had to prototype the settings menu in many styles, but I was not satisfied. I was content with the dropdown settings menu for a long time. However, I never really felt it was a part of my website, even though it functioned well. I didn’t take it that seriously until I desired a more minimalistic approach, with icons for settings.

Old dropdown menu of settings
Old dropdown menu of settings

The new menu settings reside on the command bar of the desktop view or at the top of the menu in the mobile view. It’s straightforward and no-nonsense so far. I’m very pleased with it now because I can move this component around and still be satisfied with it.

New settings menu - theme collapsed
New settings menu - theme collapsed

My Struggles:

  • Creating a reusable settings store.
  • Bundling different code themes with actual themes. I solved this by creating a small database containing all the themes and their respective code themes.

I still have 2-3 settings to create. So far, flipping the layout and providing dyslexia support for fonts come to mind.

New settings menu - theme expanded
New settings menu - theme expanded

View Transitions

I fell in love with the ‘whole view transitions’ video released by Google, which allows for native-like application transitions from page to page. I wanted to incorporate this into my website. The original implementation used Astro’s view-transition support and client-side router.

Current implementation: TanStack Router now handles client-side navigation with view transitions enabled by default. Stable viewTransitionName values preserve the page, heading, navigation, and category morphs.

I considered adding a GIF to demonstrate it, but it’s best experienced firsthand. It’s most noticeable on the Tools page when you switch categories, or anytime you navigate from the home page to the blog or snippets. It ensures that pages morph with a fade, which is the default transition.

My Struggles:

  • Knowing what element should morph without motion sickness.
  • Theme toggles.

Code Highlighting

Developer websites without any code highlighting? That’s impossible. I found Expressive Code. I first adopted it through the Astro ecosystem and its use in Starlight. It remains part of the site and now runs as a rehype plugin in the Vite MDX pipeline, with the same IDE-like features, plugins, and VS Code themes 🎊!

HelloWorld.cs
public void Test()
{
String message = "Hello World";
Console.WriteLine(message);
}

Expressive Code also got multi-theme support. It's very important featureset for me. Expressive Code is built on Shiki highlighter.

Navigation indicators are essential for the currently active page, with accessibility in mind, using the aria-current attribute. I also added small indicators for pages that take time to load - this was trickier, but very fun to implement. The original indicators were tied to Astro’s view-transitions API and client-side router.

Current implementation: TanStack Router’s Link, location, and router-state APIs now drive active and pending navigation states.

The mobile view also has indicators, just without any for loading.

OH, links got sounds too! 🕺

Themes

I want to add more themes to the list than just dark and light theme. I am okay with the variables I created for this site. My aim to make 6 distinct themes in total this year at least with accessibility in mind.

I am using tailwind to place these tokens all over the components but css variables are my starting point for any design system.

Sounds

I added basic sounds to navigation links that activate when the user interacts with them. I still want to add different types of sounds to different buttons.

It works great with the sound toggle too.

SEO

SEO is very important for any post or website to get indexed. I am working very heavily on the SEO. The original Astro component manually rendered title, canonical, Open Graph, article, and Twitter metadata from Astro.url.

Current implementation: A shared React seo() helper builds canonical links and metadata for TanStack Start route heads. Article dates use ISO timestamps, and tags are derived from the validated MDX frontmatter.

Seems like all features are done- NO!

Important features are done but many accessibility is still not consistent.

  • Little bugs will be present.
  • Even though view transitions API got reduced motion built in, I still wanted it to be a css variable to toggle.
  • Color contrasts needs to be better.
  • Make some more components more robust.
  • Types for some variables needs to be more robust.
  • Background patterns.
  • Reduced motions for transitions

The points above are not in order. But it's very important for me to implement them very soon.

Result

Well, the result is this very website. Support me by just looking around the website or by forgetting me in your bookmarks page (if I even get there) 🎊!

Thank you for reading this long post! 💖