Appjeniksaan

The compounding seeds of creativity

Early on in my career, I learned a very important lesson about creativity: It can’t be saved for later. Creativity is perishable, just like inspiration. It has to be discharged regularly or it will spoil. And if you let enough of it go to waste, eventually your talents will sour and shrivel with it.

This take from DHH really resonates with my personal experience. You might feel that you should be able to ignore some of the boring day-to-day tasks and switch on creative mode right after, but the mundane bits seem to have quite the effect on the rest. I do find it difficult to avoid this sometimes, but the best way seems to be to not get stuck on failure and just try again.

Table row styling with CSS Grid

Recently I ran into styling issues with a table layout where a lot of columns had to take the minimum amount of space, so certain other columns could take all the room available. The default table styling in CSS is not very flexible, so it would be great to use CSS Grid row such a layout. But with a normal CSS Grid layout you will not have the option to easily style even / odd row backgrounds. When searching how to style even / odd row backgrounds, the suggestions online were pretty outdated. Since subgrid support has become widely available, I think there are better solutions.

An example table

Programming Language Creator First Release
C Dennis Ritchie 1972
Python Guido van Rossum 1991
JavaScript Brendan Eich 1995

The code

To create the table above, we can use the HTML:

<table>
  <thead>
    <tr>  
      <th>Programming Language</th>
      <th>Creator</th>
      <th>First Release</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>C</td>
      <td>Dennis Ritchie</td>
      <td>1972</td>
    </tr>
    <!-- [...additional rows] -->
  </tbody>
</table>

And the styling to make it into a CSS Grid based table:

table {
  display: grid; 
  grid-template-columns: repeat(3, 1fr); /* 3 columns of even width */
}
thead, tbody, tr {
  display: grid; 
  grid-template-columns: subgrid; /* thead, tbody and tr are subgrid */
  grid-column: 1 / -1; /* from the first to the last column */
}
thead tr, tbody tr:nth-of-type(even) {
  background-color: white; /* the header and even rows get alternative background-color */
}
th {
  font-weight: bold;
}

The code above is a very simplified example, but with CSS Grid and subgrid the options for creating advanced table layouts are almost limitless.

Reading Activity

A couple of years ago I gave away almost all my fysical books. Before that moment I had been building quite the little library and kept buying anything that I thought was interesting to read some day. But my growing collection made me feel more and more anxious about the number of pages I still had to read, a cleanup seemed like the best reset.

Right after the purge all was great, but over time more and more books started to pile up on the shelves again. So it was time for another approach. This time, I am dedicating to reading everything that is on the shelves and not purchasing anything new until I’ve read through what I have available. At the moment that is still sort-of overseeable, so it still feels like a challenge and not something completely unreasonable like my situation before the purge.

To hopefully help get a better grasp of how I am making progress I started logging the books I’ve been reading on this domain.

The interesting thing about this approach is that it will get more challenging with time. At the beginning I got to read through books like the The Hitchhiker's Guide to the Galaxy, but at some point I will have to dive into Pale Fire and The Divine Comedy. So fingers crossed for this new approach 🤞.

Start with Something That Does Nothing

When building a new thing, a good first step is to build a thing that does nothing. That way, you at least know you are starting from a good place.

Linking out to this short post by Raymond Chen on the Microsoft devblogs, which provides great advice.

Make sure you can do nothing successfully. Only then should you start making changes so it starts doing something. That way, you know that any problems you have are related to your attempts to do something.

🫨 theshook.¹

Talking about creating useless software, last weekend I spent some time to create an RSS feed aggregator for The Verge. Could I not just use any RSS aggregator to do the same, yes, but that would deprive me of learning something new and writing useless code.

The site stores its links in Deno KV and uses expireIn to automatically remove links 7 days after their publish date. It applies :visited styling to the links to see which pages you have already visited. And on a return visit it shows the time of the new links in bold.

It’s pretty basic, but was fun to create, the source code is up on Github.

Oh yeah, the name, I didn’t want this thing to be too serious, of course it is related to Shook Ones, Pt. II by Mobb Deep.

Check it out now: https://theshook.one

Crafting Useless Software

… useless software is a fantastic way to explore and experience the joy of computing.

Learning and exploring in modern software are so difficult to combine with the day-to-day responsibilities of a software engineer. Creating useless projects is a great way to explore new technology, and labeling the project “useless” lowers the bar of putting it on the internet before everything is perfect.

For me, the best way to learn is to explore without taking the entire process too seriously.

Deno.cron

Last weekend, I was working on a new project that I will post more about some other time.

In order to update data, this project utilized a Github Action set to run every hour. The action involved:

  1. Checking out the code
  2. Setting up a Deno instance
  3. Running the actual task

While none of this is difficult, it feels like a separate piece of code that you have to set up distinct from what you are building.

Below is what the YAML for the Action looks like:

name: Update entries

on:
  schedule:
    - cron: '0 * * * *'
  workflow_dispatch:

permissions:
  contents: read

jobs:
  update:
    runs-on: ubuntu-latest
    timeout-minutes: 3

    steps:
    - uses: actions/checkout@v4

    - uses: denoland/setup-deno@v1
      with:
        deno-version: v1.x
    
    - run: deno task updateEntries
      env:
        DENO_KV_URL: ${{ vars.DENO_KV_URL }}
        DENO_KV_ACCESS_TOKEN: ${{ secrets.DENO_KV_ACCESS_TOKEN }}

After configuring the above, I stumbled upon Deno’s recent introduction of Deno.cron. I had no idea what it was, but it sounded like something that would be similar. As it turns out, it is.

By adding a Deno.cron() call in my the main.ts file of my project, Deno Deploy will execute my update task based on the provided cron schedule. The beauty of this approach is that there’s no need to provide Deno KV credentials, and the output is conveniently logged in the Deno Deploy logs.

The code required to do the same as the YAML above:

Deno.cron('Update entries', '0 * * * *', () => updateEntries())

Comparing the previous setup involving a Github Action with the one-line of TypeScript code, the latter is undeniably awesome.

P.S. I cannot vouch for the stability of this feature and have no idea what the resource limits are. While it has been solid in my experience, it’s worth noting that the feature has only very recently been released and is Unstable. Therefore, use it at your own risk.

Blogging for the Hell of It

Why is that the end goal of blogging? Of writing? Just to make money and grow our followers? To increase our traffic so we can expose our visitors to 300 repetitive ads that take up their entire phone screen? To “convert” our readers into our customers, because them reading and enjoying what we have to say simply isn’t enough? Personally, I want nothing to do with it.

💪

Splitting the Web

Last weekend, I got kicked out of YouTube for using an ad blocker. At first, it seemed tempting to disable the blocking and get back to the entertainment, but perhaps this is just a good incentive to not spend my time watching videos. In this linked “Splitting the Web” post, Ploum argues that the web is splitting in two directions, and I fully agree. The commercial direction is becoming increasingly egregious in its use of your data and attention, turning you into the product. The other direction appears to be comprised of individuals concerned about what is happening to the web.

When my ad blocker interferes with a website or a site requires me to turn it off, I simply leave. If the content was worthwhile, it will likely appear elsewhere. The frustrating aspect of this situation is that the direction I despise seems to be the more successful strategy and is therefore becoming increasingly popular.

Appjeniksaan is my personal software development 🛠 shop which lets me create sites and apps that I think are delightful or just fun 🤪 to build 🚀. On this site I will try 🙈 to share the interesting info I bump into on the www 🌍