Notes

Tom Oliver's profile picture
Tom Oliver

First impressions of Remix vs. Nextjs (pages router)

  • Obviously Remix is the newer kid on the block, so expect library support etc. to be less comprehensive.
  • It seems that Remix has changed its routing system recently. Unfortunately many of the tutorials out there use the old one (directory based), which is confusing.
  • Remix is less of a black box than Next. You are allowed to configure the entry.client.tsx and entry.server.tsx in any way you want to. This lets you take control of exactly how you do SSR and hydration.
  • At the time of writing, Remix heavily leans into using the latest React features like renderToPipeableStream which you will see in your entry.server.tsx. Unfortunately a lot of libraries are not up to date and still use renderToString in examples, like mui. So it can take a while to figure out how to integrate all of your libraries so that they are happy doing SSR.
  • Remix is a framework who's main abstraction is the data fetching on the server side. Nextjs (page router) has a similar concepts with getServerSideProps, getInitialProps etc, but it seems that Remix's solution is more all encompassing and unifying.
  • Nextjs is in weird limbo state at the moment where you have to choose between the pages router and the app router when you create your project. This is fine if you are sure exactly what feature you need, but in the case where you don't really know, Remix might be a safer bet.
Tom Oliver's profile picture
Tom Oliver

Nx hanging

Ok I'm using Nx as a monorepo manager for a project and got into to some very strange behavior. There are several node apps in the repo and to run them, you use npx nx serve <my-app-name>. Sometimes tho, after updating an npm package I would get an error like:

LOCK-FILES-CHANGED
please restart nx daemon using `nx reset`

Unfortunately I couldn't reproduce the error message exactly at the time of writing, so this is the best I could remember.

Anyway, no matter how many times I run nx reset, my npx nx serve commands would just hang. Zero output at all. As I suspected the daemon, I tried to view its logs. To find out where the log file was I did:

$ npx nx daemon
Nx Daemon is currently running:
- Logs: /home/tom/Documents/project/node_modules/.cache/nx/d/daemon.log
- Process ID: 33785

But when I tried to cat the log file it apparently did not exist!

So presumably the daemon was in some kind of infinite death loop... I never got to the bottom of the cause, but did manage to find a solution.

There is an environment variable that disables the daemon because its more of a performance optimisation than a critical feature. So now I just export NX_DAEMON=false and everything seems to work ok.

If you use a nix devShell like me you can just add it to the shellHook like so:

NIX
...
devShells.default = pkgs.mkShell {
shellHook = ''
export NX_DAEMON=false
'';
};
...
Tom Oliver's profile picture
Tom Oliver

Have you heard of semantic Javascript ?

You probably answered "No" because I just thought of it 😇

Everyone knows they should be writing semantic HTML but why not apply the same standards to a "real" programming language.

Semantic programming is all about using the constructs a language provides in such a way as to convey intent to the target audience, whether that be human or machine. In HTML we have the classic example of using the <footer> tag instead of just spamming <div> everywhere. Lets apply that logic to Javascript.

Here's some non-semantic JS.

1
ah, a for loop, I wonder what it does.
2
I have to look inside the loop to find out that we are transforming each element.
JS
let arr = [1, 2, 3]
1for(let i = 0; i < arr.length; i++) {
arr[i] =2arr[i] * 2
}
1
ah, a for loop, I wonder what it does.
2
I have to look inside the loop to find out that we are transforming each element.

now for something semantic

1
This one word tells me that we are transforming each element somehow, without me having to read any further!
JS
// we are doing the exact same thing as before, just better.
let arr = [1, 2, 3]
arr = arr.1map((x) => x * 2)
1
This one word tells me that we are transforming each element somehow, without me having to read any further!

I think you get the idea...

But just in case, here is another scenario...

1
Not sure what this while loop is going to do
JS
1while(i < arr.length) {
...
// do some operation
res = ...
}
1
Not sure what this while loop is going to do

Compare the above to this:

1
This word means we are going to combine the array in some way.
JS
let res = arr.1reduce((acc, cur) => {
...
// do some operation
},{})
1
This word means we are going to combine the array in some way.

So.. what do you think?

Ok, maybe this is just an excuse to get you to do some functional programming.

You got me! 😘

Tom Oliver's profile picture
Tom Oliver

Here's how to burn audio to a CD from the command line.

SHELL
# Remove spaces from filenames
for f in *; do mv "$f" `echo $f | tr ' ' '_'`; done
# Convert all tracks to wav
for i in $( ls ); do ffmpeg -i $i $i.wav; done
# Normalize the volume across all tracks
normalize -m *.wav
# Burn to disk
sudo wodim -v -dev='/dev/cdrom' -audio -pad *.wav
Tom Oliver's profile picture
Tom Oliver

So this is one of the first times I have actually come across a hurdle when it comes to developing software on old computers. A couple days ago I started experimenting with bun, which is amazing by the way. One of the big selling points is that it is really fast, but this speed seems to come at a cost...

As I use NixOS, I installed it the usual way by adding it to my configuration.nix. But alas, life isn't always simple. It seems to install ok, but when I tried to run bun I got an error immediately:

SH
illegal hardware instruction (core dumped)

Wow an actually hardware error! I haven't seen one of those since I was trying some overclocking! So the problem comes down to the fact that bun uses some cutting edge CPU instructions that weren't around in 2012. Now, on other Linux distributions you can simply use a bash script to install bun à la:

SH
curl -fsSL https://bun.sh/install | bash

Apparently it checks your CPU and in the event it finds something of a certain vintage it installs a baseline version of bun which I guess doesn't use any of the funky CPU instructions it would usually. Unfortunately the nix package does not at the time of writing do this. There is actually a PR open to fix this but it has not been merged yet. So for the time being you can basically just take the code from the PR, save it to a file locally and build the baseline version yourself.

  1. Download and save this file.
  2. Now to build is, run:
SH
nix-build -E 'with import <nixpkgs> {}; callPackage ./default.nix {}'
  1. You should now be able to run bun by doing:
SH
./result/bin/bun