Today’s issue: Wasm buzzword bingo, getting Tumblr famous in 2014, and the health hazards of writing a JavaScript newsletter.
Welcome to #318.
Ollama?? He's supposed to be dead!
You’ve probably heard a lot about Ollama over the past few months – but chances are, you don’t actually know what it is or how it works.
So on this slow-news Thursday, let’s hold hands and dive into the Llama-verse together to get some answers.
What it is: Ollama is a platform that lets you run over 100 open-source AI models locally. That may not sound like a big deal, but since AI companies are downloading the open internet and selling it back to us for $20/mo, it’s nice to have free tools that also offer better privacy, security, and speed.
How it works: The Ollama CLI can download and serve models, allowing you to chat with them directly from your terminal. It can also spin up an OpenAI-compatible HTTP API that you can curl
or access with their JavaScript SDK.
A few potential uses cases:
VSCode Extensions: Instead of paying for GitHub CoPilot, Ollama makes it possible to leverage a model like codestral
to power auto-complete in your editor, via the Continue extension.
Open AI compatibility: Because Ollama’s API is compatible with the OpenAI Chat Completions API, you can swap out a the paid endpoint for your local model like this:
import OpenAI from 'openai'
const openai = new OpenAI({
baseURL: 'http://localhost:11434/v1',
apiKey: 'ollama', // required but unused
})
const completion = await openai.chat.completions.create({
model: 'llama2',
messages: [{ role: 'user', content: 'Why is the sky blue?' }],
})
console.log(completion.choices[0].message.content)
Bottom Line: Ollama feels like “AI, the good parts” because it’s one of the few options we have for running code on our local machines. And it’s nice to feel like we at least have a small semblance of freedom from our cloud overlords.
Me watching all of my web scrapers get blocked after 6 weeks of work
Their Web Scraper APIs give you programmatic access to structured web data from dozens of popular sites right out of the box.
You’ll never get blocked or rate limited again, and you’ll never have to worry about setting up proxy servers, headless browsers, and other infra – because Bright Data handles it all for you:
Their CAPTCHA auto-solvers, automated IP rotation, and residential proxies make sure you always get the data you need.
Their infrastructure powers 20,000 companies worldwide, with access to 72 million real user IPs in 195 countries, so you can easily scale up.
Their privacy practices comply with GDPR and all other data protection laws.
Take 10 min to try the Web Scraper API for free – no credit card required.
Their WebViewer SDK comes with a Salesforce integration that lets you seamlessly build document processing into a Salesforce app with editing, redacting, and signing functionality.
We have an existing filterRecommendations
function that takes two arguments:
purchasedProducts
: A list of product IDs that a user has already purchased.potentialRecommendations
: A list of product IDs that could be recommended to the user, which might include some products they have already purchased.The goal is to generate a list of unique product recommendations, ensuring that products the user has already purchased are not included.
Given that information, how can this code be improved?
function filterRecommendations(purchasedProducts, potentialRecommendations) {
return potentialRecommendations.filter(
(product) => !purchasedProducts.includes(product)
);
}
// Testing the function
console.time("Recommendations");
const purchasedProducts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const potentialRecommendations = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const result = filterRecommendations(
purchasedProducts,
potentialRecommendations
);
console.log(result); // [11, 12, 13, 14, 15]
console.timeEnd("Recommendations"); // 0.34814453125 ms
David Gerrells created an app that turns a video into pure CSS. Reading about how he did it has left me both amazed and disgusted – which happens more often than you’d think doing this job.
Rspack 1.0 just came out and is officially stable and ready to mingle.
Self-proclaimed “type nerd” Gabriel Vergnaud released a library of composable functions for TypeScript called HotScript. Megan Thee Stallion is also listed as a contributor.
Dan Mindru wrote about How he cut 22.3 seconds of an API call using Trace View, and he’s hosting a free workshop to show you how to do it too. He’s not the hero we deserve, but he’s the one we need right now. [sponsored]
Oskar Wickström created a theme to celebrate his love of monospaced fonts. As Meg from Hercules would say, “People do crazy things when they’re in love.”
Rodrigo Pombo just released v1.0 of Code Hike.
Automattic is migrating Tumblr to WordPress. They better preserve all the fanfic I wrote about Taylor Swift’s cats that helped me get Tumblr-famous back in 2014 (37 total reblogs).
Nick Schneeberger and Benjamin Hanimann created a collection of 242 free APIs. Unlike other API lists, these are tested every 24 hours and assessed a reliability score.
Material UI v6 comes with React 19 support, container queries, and celebrates the 10-year anniversary since its initial commit.
Chris Fallin wrote about Compiling JavaScript to Wasm. If your article bingo card included the terms “WarpMonkey”, “Winliner”, and “Octane” please come forward to collect your prize.
function filterRecommendations(purchasedProducts, potentialRecommendations) {
return potentialRecommendations.filter(
(product) => !purchasedProducts.includes(product)
);
}
We can improve this code by using a Set
to store the purchasedProducts
list. Because Set
allows us to check for the existence of a value in constant time, we can avoid the linear time lookup that Array.includes
requires. In theory, this should make the function significantly faster for large lists of products (but you should always benchmark your code to be sure).
function filterRecommendations(
purchasedProducts,
potentialRecommendations
) {
const purchasedProductsSet = new Set(purchasedProducts);
return potentialRecommendations.filter(
(productId) => !purchasedProductsSet.has(productId)
);
}
console.time("Recommendations");
const purchasedProducts = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const potentialRecommendations = [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
const result = filterRecommendations(
purchasedProducts,
potentialRecommendations
);
console.log(result); // [11, 12, 13, 14, 15]
console.timeEnd("Recommendations"); // 0.212890625 ms