I created a simple vector database called "Vector IDB" that runs directly in the browser using IndexedDB. It's designed to store and query JSON documents with vector embeddings, similar to Pinecone, but implemented locally. The API is basic with insert, update, delete, and query functions. While it lacks optimizations like pre-filtering and advanced indexing found in dedicated vector databases, it provides a starting point for experimenting with vector search in the browser without relying on external services. The project was a fun way to learn about vector databases and their use with embeddings from APIs like OpenAI.
Optimizing images for the web is crucial for Core Web Vitals, but the process is overly complex. While tools like Squoosh and web.dev guides offer help, developers still struggle with image optimization. This difficulty stems from needing to consider file size, resolution, codec support, lazy loading, and more. CDNs offer a solution but introduce centralization. To simplify this, I created a prototype tool (https://just-gimme-an-img.vercel.app/) that generates optimized HTML for images, handles AVIF conversion, creates multiple image sizes, and does it all client-side using Squoosh's CLI. The tool aims to make image optimization easier and more accessible, especially for common use cases like hero images. I'm hoping this sparks further discussion and improvements in image optimization tooling to simplify the process for all developers.
akachan.app is a Single Page Application (SPA) built for instant loading without using JavaScript on the client-side. Instead, all JavaScript resides in a Service Worker and is also executable on the server. This approach offers significant performance benefits but introduces challenges regarding third-party sign-in integration and data synchronization.
I've always been fascinated by the potential of the web as an API, an idea I first encountered through Michael Mahemoff's work with microformats and CORS. While technologies like Web Intents explored similar concepts, they proved more complex. The core idea remains powerful: enabling direct client-side interaction between websites to bypass the complexities of server-side integrations. Although CORS is widely supported, its complexity hinders adoption. With the rise of client-side generated sites, the need for decentralized integration is stronger than ever. Tools like Comlink, by abstracting the complexities of postMessage and MessageChannel, make it easier to expose and consume client-side APIs. I demonstrated this with a simple example integrating a pubsubhubbub endpoint with a push notification service. This approach offers several advantages, including simplified data transfer, offline capabilities, and secure, controlled exposure of functionality. Looking ahead, I envision a future where every website exposes a consistent, discoverable API, enabling a more interconnected and modular web experience.
In this post, I share a simple client-side JavaScript PubSub system I built. Motivated by the Not-Invented-Here syndrome and the desire for independent UI components, I created a lightweight event manager called EventManager. It allows components to communicate without direct dependencies by publishing and subscribing to named events. While similar to tools like Redux, this approach avoids separate state management, leveraging the browser's existing state. The code is available on GitHub.
I've created LeviRoutes, a client-side JavaScript routing framework inspired by Rails. It's simple, fast, and focuses solely on handling URL changes. LeviRoutes works with HTML5 History APIs, hashchange events, and even gracefully degrades for older browsers. It supports named parameters like "/:category" for dynamic routing, allowing you to treat the URL as a controller input. Check it out on GitHub!
This post details how to use the HTML5 canvas element to dynamically create visually appealing custom markers for Google Maps. Instead of using a server to generate marker icons, we leverage the canvas API to draw rounded rectangles with gradients, center text within them and ultimately convert them into data URIs. Using the HSL color model allows for the creation of a harmonious range of colors by adjusting the hue while maintaining consistent saturation and luminance. This client-side approach offers flexibility and control over marker appearance, specifically highlighting techniques for rounded corners, gradients, and text centering. The code examples provided demonstrate the process of generating these markers and integrating them into a map.
This post kicks off documenting the requirements for the next version of AJAXTagger. The goal is to create a successful application (by my definition) by outlining features across functional areas, UI/UX, client/server-side business logic, data access, and dependencies. Key features include easy journal tagging, related information retrieval (tags, articles, blogs, websites), diverse search provider integration, streamlined results presentation, image inclusion, and efficient article pulling/saving. The UI should minimize user effort, provide immediate feedback, and offer information hiding. Performance is crucial, targeting IE6/7 and Firefox, with emphasis on minimal server round trips, client-side optimization, and error handling. Data storage is preferably client-side, with external access optimized for speed and resilience. External dependencies include various search engines/services, while internal constraints involve limited server access and reliance on HTML, JavaScript, and XmlHTTPrequest.
I had this brilliant idea to create a merged RSS feed using client-side processing. The idea was to have a main RSS feed that linked to other feeds. My custom XML would include a list of sources. Then, using XSLT in the browser, the client could merge these external feeds into a single view. It worked perfectly locally! However, I hit a roadblock with cross-domain security restrictions when I uploaded it to my server. The browser wouldn't let me pull in feeds from other domains due to security concerns. Additionally, client-side XSLT processing isn't universally supported. So, even if the security issue wasn't there, many feed readers wouldn't be able to display the merged feed. In the end, the project failed. But, I learned a lot about browser security, XSLT limitations and client/server interactions!