I've recently restarted writing a compiler for fun and I've found that the hardest part is actually psychological. There's so much stuff I want to put into the compiler and language, so I often end up a little overwhelmed. When that happens it's important to just focus on the code and get something done.
It's also very easy to get myself into a rabbit hole, i.e. I'm using tree-sitter as my parser, but tree-sitter isn't designed to be used as a compiler front end, but hmm what if it was, maybe I should write something that automatically translates tree-sitter grammars to Rust AST definitions so that I don't have to manually convert a tree-sitter CST to an AST? Sure, I could go down that path, or I could bite the bullet and manually convert the tree.
Compilers are great exercises in scoping and prioritization because there's so damn many of these rabbit holes.