Martin Zoeller
If you’ve developed for mobile apps for more than a few weeks, you know the pain. You start a project, build a few features, and run it. After a few weeks, building manually becomes tedious, so you check the only real option to automate the process: Fastlane. And while the initial setup seems straightforward, chances are your terminal will still explode with red text.
Usually, it’s a Ruby version mismatch. Or you used the system Ruby when you shouldn’t have. Or maybe you used Homebrew (as Fastlane suggests), but it auto-updated yesterday, and now nothing works anymore.
For a long time, I just sort of hacked my way through it: using sudo to force the tool to do what I wanted it to do, blindly pasting random commands from random Reddit threads, and hoping for the best. But after setting up my tenth project and hitting the exact same walls as several years ago, I decided to actually fix it.
This guide is the “correct” way to handle Fastlane. It uses rbenv to decouple your project from whatever mess is happening on your system or Homebrew. It’s predictable, it locks your versions, and it just works.
We’ll go through the manual steps first so you understand what’s happening under the hood. But if you just want to get this over with, stick around to the end: I’ve included a one-shot script that handles the entire setup for you automatically.
The system Ruby is used for, well, internal system processes, so we don’t want to—nor should we—mess with it.
You’ll often hear people recommend going with Homebrew instead. Fastlane tells you the same thing in their docs, and links to a list of Ruby managers for you to pick from. If you’re like me, you don’t fancy picking one, and since they’ve already mentioned Homebrew and you know what that is, you just go with it.
What can go wrong, eh?
While Homebrew is great, it’s pretty aggressive when it comes to updating its packages. This is fine for the most part, but since we’re using Ruby just to install and run Fastlane, we don’t need the newest, shiniest Ruby version.
We especially don’t want to deal with deprecations, framework rewrites or all the other stuff Rubyists probably care about, and rightfully so. We want to build apps, so we just want something that works.
Luckily, rbenv gives us just that: full control, reliable Ruby versions, and a simple setup that’s easy to reproduce across app projects.
The following steps will guide you through removing the old Homebrew mess that’s probably running amok on your system, and then setting up everything in a simple and clean way so you never have to do it again.
(What I mean by never is that you’ll cut 97% of your Fastlane setup for every app you’re building. At some point in the far future, you might want to update Ruby, as you should do with all your dependencies and frameworks. But you probably know that. Just have to add that here to keep the “Well, actually…!” crowd in check. Anyway!)
In your .zshrc, remove the following block:
export PATH="/opt/homebrew/opt/ruby/bin:$PATH"
export LDFLAGS="-L/opt/homebrew/opt/ruby/lib"
export CPPFLAGS="-I/opt/homebrew/opt/ruby/include" Uninstall the packages installed with Homebrew:
brew uninstall fastlane
brew uninstall ruby Install the dependency via Homebrew:
brew install rbenv ruby-build Note that the ruby-build plugin is necessary as rbenv cannot install Ruby by default, but the plugin can.
Add rbenv to your .zshrc:
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc
source ~/.zshrc This allows rbenv to intercept the system ruby.
One small prerequisite: Since rbenv compiles Ruby from source, you need a C compiler. If you have Xcode installed, you are usually good to go, but sometimes the specific Command Line Tools are missing or pointing to the wrong place.
If the command below fails, try running xcode-select --install and try again.
Install a version. We’re using 3.3.6, which is a really solid and stable Ruby version:
rbenv install 3.3.6 Set this version as the global Ruby version to use by rbenv:
rbenv global 3.3.6 In the repository root, on the same level as your fastlane folder, run:
rbenv local 3.3.6 Here’s what it does: It generates a .ruby-version file with the following content:
3.3.6 That’s all. It’s so simple, yet so reliable that it’s actually quite funny.
rbenv manages your Ruby installations. Bundler manages your gems (packages) for the current Ruby installation. It’s magic. Well, not really, but it’s something to be aware of, and something more inexperienced app developers struggle with.
Run this command to install Bundler:
gem install bundler Run these commands to clean up your local setup:
rm Gemfile.lock
rm -rf .bundle
rm -rf vendor Just run this command with your Gemfile in place:
bundle install In case you don’t have a Gemfile, this is what your typical Fastlane Gemfile will most likely look like:
source "https://rubygems.org"
gem 'fastlane' You can get the same Gemfile set up by running:
bundle init && bundle add fastlane To check your installation, you can run this:
bundle exec fastlane -v If you see a bunch of 🚀 rocket emojis (per usual), and some output like fastlane 2.229.0, you know a few things now:
bundle found your Fastlane installation.Gemfile was used.To verify your installation, you can also run this:
which bundle And you will probably see something like this as the result:
/Users/martinzoeller/.rbenv/shims/bundle This confirms that bundle has been invoked by the Ruby 3.3.6 you’ve just installed.
The whole point of this setup is reproducibility. You want your teammates (or your future self on a different machine) to clone the repo and have it just work.
To make that happen, you need to commit the following files to git:
GemfileGemfile.lock (Crucial! This locks the exact versions of your dependencies).ruby-versionHowever, make sure you ignore the vendor directory and the .bundle folder in your .gitignore. Those are for your local machine only.
Now that the plumbing is fixed, the final step is to actually set up the automation.
Run this command to initialize Fastlane for your project:
bundle exec fastlane init This will guide you through a setup wizard and generate two very important files:
Fastfile: This is where you write your lanes (your automation logic).Appfile: This stores your Bundle ID and Apple ID information.From here on out, whenever you want to run a lane, you just run bundle exec fastlane [lane_name]. No sudo, no system Ruby, no headaches.
Since you’re no longer using Homebrew to get Ruby going on your machine, you can now simply run the following script to get your Ruby and Fastlane up and running via rbenv:
#!/bin/bash
# 1. Install rbenv if not present
if ! command -v rbenv &> /dev/null; then
echo "Installing rbenv..."
brew install rbenv ruby-build
fi
# 2. Add rbenv to .zshrc if not already there
if ! grep -q "rbenv init" ~/.zshrc; then
echo "Adding rbenv to .zshrc..."
echo 'eval "$(rbenv init - zsh)"' >> ~/.zshrc
fi
# 3. Initialize rbenv for this script session
eval "$(rbenv init - zsh)"
# 4. Install Ruby 3.3.6 (skips if already installed)
echo "Installing Ruby 3.3.6..."
rbenv install 3.3.6 --skip-existing
# 5. Set local Ruby version
echo "Setting local Ruby version..."
rbenv local 3.3.6
# 6. Install Bundler
echo "Installing Bundler..."
gem install bundler
# 7. Set up Fastlane
echo "Setting up Fastlane..."
# Check if Gemfile exists, if not, initialize it
if [ ! -f Gemfile ]; then
echo "Creating Gemfile..."
bundle init
fi
# Add fastlane to the Gemfile
bundle add fastlane
echo "Done! You are ready to go."
echo "Note: You may need to restart your terminal or run 'source ~/.zshrc' for changes to take effect." To run this script, create a new fastlane-setup.sh file and paste it there. Don’t forget to run chmod +x fastlane-setup.sh to make it executable.
If you’re like me, you only set up new mobile app projects every so often. The old me wanted to do things fast and never wrote down how he actually installed the infrastructure for Fastlane. So every time I set up a new project, I’d ask myself the same questions:
sudo for anything?sudo, so why is this command output telling me I’m doing it wrong?Gemfile? I know it works without…The thing is: Most of the time you just want to get it done and get back to building features. If you’re like me, you do this a few times and then you’ve just had enough, because you keep wasting time with every new project. And if you’re like me, you’ll be glad that there’s a simple setup guide now that gives you everything you need from start to finish.
If you found this useful, say hi over on LinkedIn where I share lessons learned on topics like Mobile App Engineering, Coding with AI, or Communication in Software Engineering. See you there!