Ryan Castillo
26 Mar 2024
We’re a small team at Wafris so we tend to ask “how can we cheat” a lot. We had proven that our MVP worked and people were willing to pay for it but we were missing core features for a SaaS
Jumpstart Pro (JSP) ended up being a pretty big cheat. It brought features like
This easily saved us a quarter or two worth of work. And we trusted the codebase because it had thousands of contributions over multiple years.
When we started building Wafris our goal was to move fast. So we stuck with what we knew:
We wouldn’t have considered the migration if we didn’t have tests. Experience has told us to at least have
JSP also came with pretty decent test coverage. We knew that between our tests and JSP, it would catch any show-stoppers post-migration.
A big question from the beginning was whether we should merge the git histories or not. We were paranoid about being stuck resolving merge conflicts on files shared between the codebases. Particularly those generated by Devise.
The very first thing we did was copy the entire JSP codebase and paste it on top of our directory. We trusted that git
highlight the areas we needed to spend the most time. It boiled down to:
schema.rb
routes.rb
This approach allowed us to introduce sections of the JSP codebase into our history rather than trying to do it all at once with a merge
or rebase
.
Lazygit was a great tool for managing and visualizing this process.
We still wanted to get updates from JSP as the maintenance is quite active. It seems like they push updates daily!
So we knew that we’d eventually have to merge the Git histories. Git has a nice little trick to blend the histories from multiple repositories:
git merge <remote>/<branch> --allow-unrelated-histories
Losing production data and trying to recover it was the last thing we wanted to do with our time.
The stickiest part involved User
data. We had already implemented teams as an MVP (from the Bullettrain blog) feature but JSP used different terminology: teams were now named accounts and the hasmanythrough table was completely different.
Instead of using JSP’s existing migrations, we ended up deleting them and using their schema as a basis for one giant migration that was 321 lines long.
Suggestion: spend time considering the best approach for you here. You’ll have to either:
rails db:setup
schema.rb
from scratch.JSP does a nice job of splitting out logic into modules which made it straightforward to merge with our models.
The controllers were like the models. More of introducing new actions/methods rather than having to merge anything.
Routes on the other hand were a little more complicated as the migration tripled our routes.rb
due to JSP shipping with Administrate, a skeleton for an API, and several other routes.
This forced us to decide whether we wanted to go with JSP’s route hierarchy.
We ended up going with everything JSP defaulted to but encountered all the annoyances of merging a large file and changing our routes.
Update: this has since been addressed in the recent releases of JSP as the team has utilized the draw
macro to split out this large Routes file into multiple small ones.
Updating the views to JSP's standards was a major shift. Mainly because
importmaps
rather than esbuild
to deliver our assets.The second point wasn’t as complicated as the first but we ran into some sharp corners (e.g. precompiled assets) that caused us to troubleshoot assets longer than we liked.
For the theming, we had to revisit every page to gut out our old theming and default to JSPs. This redundant refactor is one of the pain points of using Tailwind. Rather than editing CSS files, we had to meticulously remove classes.
Overall, it was worth it as we now have more universal theming and dark/light mode as a bonus.
It’s been several months since we migrated to JSP and we’re still reaping the benefits. One new one has been bringing on a contractor and them being able to hit the ground running as they’ve worked with multiple JSP projects before.
JSP is a cheat.
Start blocking traffic in 4 minutes or less