Is Vanilla JavaScript Better?

The other day, I made a little calculator for my brother’s Frosthaven group. To make it simple, I just did an index.html with some pure, vanilla JavaScript. You can find the code on GitHub.

I’ve been working with JavaScript frameworks like Angular and Vue for what feels like a real long time now. So I’m not a Vanilla JS wizard. There may be better ways to do what I’m doing. I was just trying to get something done quick. This setup was simple to get going since it is just some files with no build step. But it got me thinking, is it better? I’m not so sure.

Vanilla JS is very declarative. While it’s nice to see exactly what it’s doing, I’m not so sure that’s easier for a beginner to reason about. And maybe I’m mostly thinking about the rendering logic. The business logic is going to be pretty much the same, but when it comes to displaying data on the page, I think frameworks have a clear advantage.

I’m sure it’s subjective, but I think this:

<table id="costsTable" aria-label="Enhancement Costs" role="grid">
    <thead>
        <tr>
            <th scope="col">Enhancement</th>
            <th scope="col">Cost</th>
        </tr>
    </thead>
    <tbody id="costsBody">
        <tr *ngFor="let enhancement of costs">
            <td>
                <img [src]="enhancement.icon">
                
            </td>
            <td> gold</td
        </tr>
    </tbody>
</table>

Is a lot easier to follow than:

const table = document.getElementById("costsTable");
table.removeChild(document.getElementById("costsBody"));

const body = document.createElement("tbody");
body.id = "costsBody";

costs.forEach(({ label, cost, id, icon }) => {
    const iconEl = document.createElement("img");
    iconEl.src = `/assets/img/${icon ?? id}.png`;
    iconEl.alt = `Frosthaven icon for ${label}`;
    iconEl.setAttribute("aria-hidden", true);
    iconEl.classList.add("enhancementIcon");
    
    const labelEl = document.createElement("span");
    labelEl.textContent = label;
    
    const enhancementCell = document.createElement("th");
    enhancementCell.setAttribute("scope", "row");
    enhancementCell.appendChild(iconEl);
    enhancementCell.appendChild(labelEl);
    
    const costCell = document.createElement("td");
    costCell.textContent = `${cost} gold`;
    costCell.classList.add("costCell");
    
    const row = document.createElement("tr");
    row.appendChild(enhancementCell);
    row.appendChild(costCell);
    
    body.appendChild(row);
});

table.appendChild(body);

It makes sense to me to keep template/rendering in the HTML.

I think it’s important to understand how to do things in vanilla JS. And there is a lot to be said for the simplicity of getting it setup. I guess completely unique and new idea is that good frameworks provide levels of abstraction that actually make it easier for people to understand the code. You add some complexity on the build side for a better developer experience. Probably worth it.

Maybe I need to try Alpine.js to get around the build issue…

Devlog: May 31, 2023

I worked on dark mode a bit today. I’ve written about it a bit before, but my eyes have a really hard with pure black dark modes with black backgrounds and white text. This is the default in iOS. So I wanted to do something a little different.

For reference, here is light mode:

A screenshot of ScreenCred showing the app in light mode, with a white background and black bordersLight mode

And here is the default, pure black dark mode:

A screenshot of ScreenCred showing the app in dark mode, with a black background and white bordersOld dark mode

I decided to try replacing the black background with a dark gray. In this case, I used secondarySystemBackground. I also made the white borders thinner so they didn’t feel so heavy. I think since the images are darkish, the borders stand out a lot more than the black borders do in light mode.

A screenshot of ScreenCred showing the app in light mode, with a dark gray background and thin white bordersNew dark mode

I like this a lot better. Gonna try it more on my device to make sure.

To accomplish this, I removed the content background from my ScrollViews and added my own background based on the current colorScheme. Not too bad.

ScrollView {
    ...
}
.scrollContentBackground(.hidden)
.background(colorScheme == .dark ? Color(uiColor: .secondarySystemBackground) : Color(uiColor: .systemBackground))

Projects ScreenCred devlog

Devlog: May 29, 2023

So far in ScreenCred, you can only compare movies and shows. I wanted to add a missing category—people.

Search Updates

I was already using TMDb’s multi search endpoint, but was filtering out the people. So it was pretty simple to add people back in. One convenience I wanted to add was search scopes. This adds a picker below the search input that lets to quickly filter results.

A screenshot of the search sheet in ScreenCred showing a picker below the search input that lets you limit results to everything, movies, shows, and people.Power searching

Comparison Updates

My comparisons were also pretty flexible in that compare two Media which can be a movie, show, or person. But, the app had no idea how to compare a person to a movie or show. I essentially have two comparisons now. One comparison is for when the types are like” each other—two movies or shows, or two people. The other comparison is for when the types are different—one person and one movie or show. The main difference is that if they are different, I basically just check if the person is in the credits of the movie or show. Not too bad.

When it’s two people, it works almost exactly as it did before, except showing all the movies and shows the two people worked on together. I made the choice to throw out most Self” TV show credits. In my opinion, this added a lot of noise from interview shows and whatnot. Someone could maybe talk me into adding them back.

Here’s a demo:

A screen recording of the ScreenCred app showing a search for Tom Hanks and Meg Ryan and the resulting movies and shows they were both in.Search demo

You can see from the demo that the images in the comparison are rectangles when you are comparing two people. This is ironic because I put in a bit of work to make profile images for people squares. But squares look bad for movie posters. So now there is some special logic to determine if the image should be square or rectangle.

I also needed to update my URL scheme to allow for people. That was a simple change to my regex that parses the incoming URL to allow of IDs with p, for person. With that change and another recent change to allow a single ID to be passed in the URL scheme, ScreenCred can pretty much handle anything1.

Web Updates

I have a small web server that handles generating the images that are used for the og:image meta tag. Similarly to the app, I pretty much needed update the regex that parsed the urls to also handle p. Now you can get beautiful image of Danny DeVito and Daniel Radcliffe.

An iOS new message composition sheet with a link to ScreenCreed. The preview image shows Danny DeVito and Daniel Radcliffe.Your friends will love this

What’s Left

Need to do something with people who do not have profile pictures. I think I want to give them a placeholder, as well as sort them lower than those who have a picture.

I think I also need to rethink how I handle sorting results. Not sure if the current sorts of number of credits and by name are the most useful when comparing two people. Maybe I should also add sorting by release year? Not sure.


  1. Not literally anything.↩︎

Projects ScreenCred devlog

Devlog: May 28, 2023

Been busy starting a new job this week, but I’ve also managed to get a couple things done in ScreenCred.

Profile Pictures

This one was pretty straightforward, but I managed to complicate it.

Screenshot of ScreenCred app showing the common cast and crew between the show Andor and the movie Rogue One, with rounded rectangle profile images of the person.Putting a name to a face

To fit the design of the app, I knew I wanted rounded corners. Matching the corner radius was a simple matter of maths. But I felt like they were taking up too much space. I think square was the way to go.

Screenshot of ScreenCred app showing the common cast and crew between the show Andor and the movie Rogue One, with rounded square profile images of the person. The outside corners of the image are rounded less than the inside corner.This is differenter

Next, I made them square. I like the spacing much more. I tried giving different corner radiuses to the outside corners. I’m surprised this is not a built in feature of RoundedRectangle. I kinda like this look, but don’t love it. Then started thinking about adding a black border as well as how in the world I’d support RTL languages. So just scrapped that idea.

Screenshot of ScreenCred app showing the common cast and crew between the show Andor and the movie Rogue One, with rounded square profile images of the person. The image has a black border around it.Not too bad

This is where I landed. Square, all the same corner radii, and a black border to make it match the design a bit more. Happy with it.

It’s a simple change, but I think it makes it better having photos there when they are available.

The next thing I worked on was adding the ability to search people. I will write more about that tomorrow.

Projects ScreenCred devlog

Do Nothing

I’m currently at the end of a break between jobs. I took one week off. I had grand schemes of working on my app, maybe starting some other new things, etc. Pretty quickly though, it was clear I needed something else. I ended up just relaxing. Read books. Visited family. Took naps. Played some games. Fiddled with my nevoid config. The usual relaxing stuff. It was nice.

I feel a bit guilty about it about it though.

I’m fortunate enough that I can take time off, unpaid, without it running everything. But I feel like I should’ve been more productive” with that time. My work tends to come in waves. I think that’s pretty normal, but in the times when I’m not feeling inspired or motivated, I feel like I’m just lazy. But, it’s okay to do nothing sometimes. I often forget how important breaks are, wether it’s during the day or during the year. Sometimes the most productive thing you can do is nothing.

It was a nice little break and now I’m excited to jump into my new job.

I Think I Regret Buying the Studio Display

When rumors of the Studio Display started coming out, I started saving money to buy one just in case. When it was announced in 2022, I immediately ordered one and got day-one delivery. I was beyond excited to replace my Dell U3818DW with a beautiful Retina display.

A little over a year later, I’ve never really felt 100% satisfied with it, and I think I’m going to switch back to my Dell…

I’ll try to explain why.

1. My Eyes

This may make no sense, but I’m starting to think the Studio Display is too good for my eyes. I have pretty bad eyes, and it’s like the Studio Display has too good of contrast or something, and it’s sometimes really hard for me to look at text—a problem since my job and a lot of my hobbies involve looking at text on my screen. Sure, I can make the text bigger, and I’ve switched to light themes instead of dark themes. But at that point, I’m bending the monitor to my will instead of using it for what it’s good at.

I also did not get the nano texture on the Studio Display. I think that was a mistake. My office is really bright. The Dell has a matte finish which works a lot better in my space. I can use dark themes on the Dell without it being washed out by window glare just fine. Not the case with the glossy Studio Display.

The Studio Display is definitely still way better for editing photos and stuff like that. But I still have my 14” MacBook Pro’s screen when I need an excellent screen.

2. Convenience

A couple months after I got the Studio Display, I built a gaming PC. I didn’t really think things through. You cannot easily use a PC with a Studio Display. So I now have 2 complete computer setups on my desk. 2 monitors, 2 keyboards, 2 mice. It’s cluttered.

The Dell U3818DW has a KVM switch built in. I can plug both computers in with one set of accessories and somewhat seamlessly switch between them. That is really nice.

Switching back would free up some space. Not only would my desk be cleaner, the Dell has more screen real-estate too. The ultrawide aspect ratio makes a lot of developer tasks nicer.

There are some downsides to not using the Studio Display though. The speakers are much better on the Studio Display. The Dell does not have a webcam and microphone built in. While the Studio Display camera is not stellar, it’s more that sufficient for work meetings and the microphone is pretty good in my experience. I’d have to put a webcam with a (probably) worse mic on top of the Dell. Not ideal, but not the end of the world either.

3. New Family Computer

This is the whole thing that got me really thinking about this. My wife brought up that she thought maybe it was about time to get a family computer for her and the kids to use. She suggested an iMac. That got every gear in my brain whirring. I suggested a Mac Mini and use my Studio Display with it as a cheaper, more flexible option. And what do you know, Mac Minis were over $100 off on Amazon right then. I ordered one.

So I’m going to do the great monitor shuffle and see how we like things. Give it a go.

Basically, I think it came down to it feeling like I was forcing the Studio Display into my life instead of it fitting in naturally. If I had a separate space and desk for my gaming PC, the calculus would probably be different. If I had gotten nano texture instead of the standard glossy finish, I also might feel differently.

Was the Studio Display an expensive mistake? Maybe. Am I glad my family will be able to enjoy it? Yes. Am I asking questions because I don’t know how to conclude this? Also yes.

We’ll see how this goes.

Picture of Sam Warnick

As my daughter says, I'm just a tired dad, with a tired name, Sam Warnick. I'm a software developer in Beaufort, SC.

Some things I do