Managing 10,000+ Names For Your Pet PigPublished Fri May 09 2025, 8 min read

In 2018, a friend and I started giving pigs stupid names in Minecraft. We didn't stop.

This isn't a tutorial! This is more of a walkthrough of my thinking, development process, and key takeaways. If you'd like to use my same tech stack, I'll setup a template if there's enough demand.

The need: I figured the best way to manage the list going forward is through a web app. At it's core, I need to edit the list of names, but there's plenty of other things the app should have.

The plan: I started off wanting to make a website in Svelte, using Fuse.js for search and minimessage-js for formatting the names.

Throwing that out the window, I decided to build everything in Rust. I had very little experience with it, but I was looking for an excuse to learn. This project then suddenly had a dual purpose: to solve a problem and to grow my skillset.

For the client/what you see:

For the server/what you don't:

Starting work: So many times before, I'd get bogged down constructing a large foundation to build everything on. Instead, I focused on getting features done and redid parts of the architecture as the project grew.

A Discord message from Justin on December 2, 2024: "trying to learn rust, fucking around with egui to make a web app (took the day off work since i didn't get enough sleep and was light headed earlier)." Included is a screenshot showing a navbar at the top (options "Pigs," "Logs," "Users," and "System") and a list of items on the left. Each item is titled "This is a line," numbered 1-40. On December 3, 2024, from Justin: "alright, only about an hour of progress today because i ordered my one meal of the day and got distracted watching videos for 5 hours, but you can select the list items now." Screenshot shows the same list as yesterday, with line 3's background highlighted in blue.

Editing the list itself was done first. If there was one part of the app that had to function, it's this, else it wouldn't be very good at its job.

I then implemented configuration for the server, gave the UI a fresh coat of paint, spent 18 hours in the hospital, and didn't work on the project for a month due to stress from work.

Returning from my hiatus, I got user accounts and OIDC login working, which took especially a lot of work to read the extra data and account for all error cases1.

To follow, I got around to client-side routing so users can conveniently link to each name on the list.

Finally, I implemented bulk imports. This was likely the most complicated feature to implement, as I tried to reduce how much data the client and server need to exchange while still showing the user a lot at once.

The Bulk Import wizard. A panel on the left lists the user's previous imports. The middle column shows information about the current import and the list of names it includes, all on a gradient background from black at the top to pink on the bottom. On the right lists all duplicates of the selected name from the list in the center.

You can find the finished source code on GitHub. I still need to figure out what to do with this massive list of pig names though.

So, should you do this? I had a lot of fun on this project. While only making a little progress each day, I was fulfilled by working on something and getting to learn along the way, building my knowledge and slowly overcoming each obstacle one at a time.

For your backend, I highly recommend Rocket. It's truly a blast to use, and I haven't run into anything I really dislike about it yet.

For your frontend, it depends. egui has been great, and I'm really happy with the overall look-and-feel of the finished product. If you're making a desktop app--or don't care about the DOM and don't need routing--go for it.

So, what's next? Time to make a video game, I'll see you on the other side.

  1. The OIDC implementation is based on rocket_oauth2 as rocket_oidc is 7 years old as of writing. As such, I had to use jsonwebtoken to parse the extra OIDC data, push any new user data to the database, and to make sure the user's session is not expired in either the OIDC response or the database. All logic for this process can be found in auth.rs.