Legacy codebase to Remix.run

The 27th of November I got a legacy codebase that needed to be maintained. I had never seen the code, but after some poking around in the codebase it was evident that it needed maintenance.

I had just built an app using Remix.run

The app was built using C#, Angularjs, JQuery, FabricJS, chartjs and MySQL as DB. The short version of what the app does is calculating reverberation-time of a room/connected rooms taking into consideration the NRC and absorption of the material in the room. Using graphs and adding material/absorption to the room the app can be used to get close to the RT-60 goal or at least as near as possible.

I dicided to go with Remix.run, MongoDB (with Prisma), Fabricjs and chartjs and Tailwindcss. The app should live side by side with the original app. I planned to use Fly.io for deployment.

I literally started with this.

npx create-remix@latest

My plan was to look at the db model, dive into how the old website looked and mimic the functionality and try to improve on user experience.

I have made rewrites before, but to be honest I never felt this happy with the progress. In a couple of days, I had rewritten the material routes and entity routes. The Graphs were just client side but with useEffect hook I could get them easily to not server render.

My mongodb is located in Sweden using Mongo Atlas. The app was deployed with Fly.io running in Frankfurt. This is initial load with cache disabled and this kind of load from the database.

export const loader: LoaderFunction = async () => {
  const materials: MaterialPick[] = await db.material.findMany({
    select: {
      id: true,
      name: true,
      absorbtionLevels: true,
      attributes: true,
      absorberClass: true,
      description: true,
      physicalMaterial: {
        select: {
          name: true,
        },
      },
      materialType: {
        select: {
          name: true,
        },
      },
    },
    orderBy: [
      {
        name: "asc",
      },
    ],
  });
  return json(
    materials.map(
      (material) => {
        const jsonData = material.absorbtionLevels as Prisma.JsonArray;
        const attr = material.attributes as Prisma.JsonArray;
        return {
          ...material,
          absorbtionLevels: jsonData.map((a) => {
            const obj = a as Prisma.JsonObject;
            const absorbtion = obj["absorbtion"] as number;
            const frequency = obj["frequency"] as Frequency;
            return { absorbtion, frequency };
          }),
          attributes: attr,
        };
      }
    )
  );
};

Pretty fast!!

If I could do this all over again and pick whatever stack I wanted, I would never move away from Remix.run. Maybe I could have used PostgreSQL instead since MongoDB with Prisma is beta. The app is a work in progress, but the main bits are in place with a superfast iteration.

Hands down! If you ever needed to rewrite legacy code and you had the luxury to choose for yourself. Give Remix.run a try and make a POC to see for yourself. It can only be explained by using it.

I'm glad to be a frontend/backend coder again.

8