I’ve been part of the Ruby on Rails ecosystem for over two decades. I’ve watched teams adopt Rails with wild enthusiasm… evolve their systems… struggle through growing pains… and eventually find themselves in an uncomfortable position; debating whether to abandon the tools that once brought them so much joy.
I don’t think that’s necessary… or even wise.
But I do think it’s understandable.
After working with and talking to hundreds of teams… many of them using Rails, Laravel, Ember.js, or even React… I’ve noticed a pattern. A lifecycle of sorts. The way teams internally adopt and evolve their relationship with a technical stack. I’ve seen it reflected in our consulting clients at Planet Argon, the guests on my podcasts (Maintainable and On Rails), and peers who’ve been part of the various peak waves of these ecosystems.
And while every team is different, the stages of internal tech stack adoption often follow a similar spiral.
This post is an attempt to describe that spiral.
Not as a fully baked theory; but as a conversation starter. A mirror. And maybe a compass.
Because whether your team is building your core product with Rails, or you’re a non-software company maintaining internal tools on Laravel, understanding where you are in this lifecycle might help you understand what comes next.
🌀 The Spiral of Internal Tech Stack Adoption
Before we go deeper, here’s a quick overview of the seven stages I’ve observed. These aren’t fixed; your team might skip around or revisit them multiple times. But in general, this is the pattern I’ve seen:
-
Adopting: A small group of enthusiastic engineers selects and introduces the stack while building a prototype or MVP.
-
Expanding: The stack proves useful… so it spreads. More features, more developers, more tooling.
-
Normalizing: The stack becomes the default. Teams standardize around it. Hiring pipelines and best practices emerge.
-
Fragmenting: Pain points surface. Teams bolt on new tools or sidestep old ones. Internal consistency erodes.
-
Drifting: The stack feels sluggish. Upgrades are deferred. The excitement is gone.
-
Debating: Conversations shift to rewrites or migrations. Confidence is shaken.
-
Recommitting: Teams pause, reflect, and decide to reinvest in the stack… and their shared future with it.
Again, these stages aren’t a ladder; they’re a spiral.
And the question your team has to ask is: Are we spiraling upward… or downward?
Because while The Downward Spiral is a great album, it doesn’t have to be your trajectory.
♻️ It’s a Cycle, Not a Ladder
It might be tempting to look at this lifecycle and think, “Our goal is to get to the Recommitting stage and stay there forever.”
But that’s not how this works.
Every team will move through these stages multiple times over the lifespan of their product. Shifting priorities, team turnover, organizational pivots… they all create new dynamics that ripple across your tech stack.
Recommitting isn’t a finish line. It’s an inflection point. One that clears the fog, sharpens priorities, and invites your team to move forward with intent.
Just don’t mistake clarity for comfort… the spiral keeps turning.
1. Adopting
This is the “we’re just getting started” phase.
You’re building a new product… launching an internal tool… or maybe spinning up a proof of concept for an idea that hasn’t fully proven itself yet. The team is small — maybe even just one or two engineers. The surface area of the application is still manageable. You don’t have years of technical debt slowing you down… yet.
You might not even be around in six months. You might never hire another engineer. Or you might be laying the foundation for a product that hundreds of people will touch every day. It’s all possibility. And possibility is exciting.
This is when the technical leaders on your team make a recommendation: “Let’s use Rails”… or Laravel… or Ember… or React. The pitch sounds familiar:
- “We’ll be able to move quickly…”
- “There’s a strong community…”
- “This framework is well documented and tested…”
- “I’ve used it before and had a great experience…”
- “There are tons of plugins and libraries…”
- “Hiring should be relatively easy down the road…”
Sometimes these decisions are driven by experience. Other times by curiosity or hope. And occasionally, it’s a compromise between a few competing options.
But one thing is consistent: this decision is rarely debated at the org-wide level. You’re a small team. You’re trusted to figure it out. And if you’re successful, the rest of the company will inherit whatever you chose.
That’s a big responsibility. And it’s one that deserves more reflection than it often gets.
In the Adopting stage, there’s a kind of magic. Things are getting built. Confidence is growing. And there’s a sense of momentum. It’s also the phase when you’re most open to experimentation… and least burdened by legacy code or organizational inertia.
That freedom can be your greatest asset… or a future liability.
Because once the rest of the org starts depending on what you’ve built… the clock starts ticking. You’re creating gravity. You’re laying down roots. And without realizing it, you’re beginning to shape the lifecycle that follows.
In this stage, there aren’t many “symptoms” of trouble to diagnose. But there is one smell worth watching for:
Are you adopting this stack because you believe in its long-term fit… or because it feels exciting right now?
The best early decisions come from enthusiasm and discernment. Not just what’s cool… but what’s sustainable for the kind of team you plan to become.
2. Expanding
Things are starting to work. You’ve shipped your MVP, and the initial product has shown enough promise to warrant further investment.
This might be when your startup begins raising money. Or if you’re inside a larger organization, leadership is noticing what your team has been building and wants more. More features, more integrations, more engineers… more everything.
The engineering team starts to grow. Maybe you’re hiring full-time developers. Maybe you’re working with freelancers or external partners. In some cases, it’s a mix of both.
Your original technical decisions are still holding up. The discussions about what framework to use have faded into the background. The focus now is on growing a team that can execute within the current stack.
That means job descriptions begin referencing specific RubyGems or open-source tools your team has already adopted. You start asking candidates what types of third-party systems or infrastructure tools they’ve integrated Rails apps with. You want engineers who can jump in and be productive—because momentum is everything right now.
Onboarding becomes more frequent. The need for documentation increases. There’s more coordination, more meetings, more product specs… and inevitably, more opinions.
Meanwhile, the original engineers—the ones who picked the stack—might be shifting roles. Some move into management. Others are pulled into meetings or strategy work. Some get recruited away. This changes the center of gravity on the team and fragments some of the original context.
That’s not necessarily a red flag. It’s just a natural byproduct of growing quickly.
To support that growth, many teams begin leaning on outside help, bringing in freelancers or working with firms like Planet Argon to meet delivery goals or stabilize certain parts of the system.
Signs your team might be in the Expanding stage:
- You’re actively hiring engineers familiar with your tech stack
- Job descriptions reference specific RubyGems, tools, or integrations
- Original contributors are stepping into new roles or leaving the team
- There’s increased emphasis on onboarding and documentation
- External agencies or freelancers are augmenting the team
- Leadership is asking for more features, faster
3. Normalizing
This is when the technology stack starts to fade into the background a bit.
The stack is no longer a hot topic in team meetings or strategy sessions. It’s just assumed. New team members are expected to figure it out — or are given onboarding resources to get them up to speed. Hiring patterns shift from “must have experience in [Rails/Laravel/etc.]” to “smart generalists welcome.” There’s a belief that the tooling is mature enough and the documentation strong enough that good engineers can pick it up as they go.
Some of the original engineers may have moved into different roles — promoted up into management, or recruited away to another opportunity. The institutional memory of why certain decisions were made may start to thin out. That early enthusiasm that helped rally the team around the technology stack isn’t quite as present anymore. It’s not gone… it just doesn’t show up in the same way.
There’s often more stability in this phase. You have patterns, workflows, and some documented best practices. New features get built. Bugs get fixed. Things are fine.
But “fine” can be a dangerous place to hang out for too long.
You may have a team of people using the same framework in slightly different ways. You might have multiple approaches to testing, job queues, or background processing. Your linter rules may vary from one directory to another. CI/CD pipelines might have been built with just-in-time needs rather than a longer-term strategy.
That early foundation? It’s now several layers buried. It hasn’t been actively questioned in a while.
And that’s okay… for a while.
But normalization is often when invisible complexity starts to grow. The decisions made years ago shape the defaults everyone works with today — even if those choices don’t make as much sense anymore.
Signs your team might be in the Normalizing stage:
- Job postings don’t require deep expertise in the stack anymore
- Onboarding materials are assumed to be “good enough”
- Few people remember why certain architecture choices were made
- Conversations about tooling are rare or surface-level
- “That’s just how we do it here” starts to show up more often
- Engineers spend more time working around problems than fixing root causes
- Updating documentation feels like a chore, not a habit
This is a stage where good habits can take root — or fade away. The stack isn’t the story anymore… but maybe it should be, at least from time to time.
4. Fragmenting
The team has grown… and not just in headcount. Now there are multiple teams. With multiple managers. And multiple priorities. Boundaries are being drawn — to the best of everyone’s ability.
To support that, new tooling is introduced. Conversations about architecture become more frequent. Maybe you’ve started spinning up microservices or smaller applications to own specific pieces of the platform. Some teams adopt new JavaScript frameworks. Other teams reach for different patterns. And it’s around this time that the term “legacy code” starts appearing in planning meetings.
Your single app is starting to feel more like a web of interconnected services… and very few people have a full sense of the whole. The test suite is getting slower. Teams are optimizing for their portion of the platform. Infra work feels like its own company within a company.
This isn’t necessarily a problem. These adaptations make sense — especially when the organization is scaling quickly. Teams are doing their best to deliver. To reduce friction. To match the autonomy they were promised.
But… it’s also where cohesion begins to suffer.
Some teams start using different programming languages. Different infrastructure platforms. Some of that comes from necessity; some of it comes from preference. You may start to hear things like, “This stack just isn’t a good fit for our part of the product.” And depending on who’s leading those conversations, it might even sound convincing.
When teams lack a shared understanding of the primary tech stack — or weren’t around during the earlier stages when that decision was made — they’re less likely to feel a sense of responsibility to carry it forward. That’s not a character flaw. It’s context.
But when enough teams go their own way, the foundation begins to shift. The very things that made your product cohesive and maintainable start to drift apart. And the assumptions driving today’s decisions may not reflect the needs of tomorrow’s (potentially smaller) team.
Signs your team might be in the Fragmenting stage:
- Multiple frameworks or languages are used across services or features
- Different teams own different deployment workflows or CI tools
- Cross-functional planning requires a lot of explanation or diagrams
- The core team’s shared standards feel outdated or optional
- Hiring focuses more on team-specific expertise than core stack familiarity
5. Drifting
The product still works. Nobody disputes that.
From the product side of things, everything seems relatively healthy. Customers are using the app. Revenue is coming in. Features still ship… eventually. But behind the scenes, things feel slower. Heavier. Riskier.
Technical leadership may have changed a few times. The original advocates of the stack have long since moved on. The current team inherited the system — and while they’re keeping things afloat, they haven’t navigated a major stack upgrade before. They’re not sure what’s lurking in the corners.
People are referring to “technical debt” more frequently. It shows up in roadmap discussions. Sprint planning. Team retros. But even when it’s acknowledged, it’s hard to act on. There’s always something more urgent.
Monitoring and observability become focal points. You’re collecting tons of logs and metrics, hoping to make data-informed decisions soon… but those decisions are harder to make when your engineers feel blocked. Or overwhelmed. Or unsure where to start.
Because while the system isn’t broken… it doesn’t feel sustainable.
Signs your team might be in the Drifting stage:
- Deployments are slower and increasingly reliant on manual QA
- Engineers hesitate to touch parts of the codebase without thorough investigation
- Test suite is long-running and semi-trusted
- Technical debt is frequently referenced, but rarely prioritized
- Tooling and documentation feel out of sync with the current product
- Leadership is requesting clarity on what’s really blocking progress
🧰 Need help navigating this phase?
Check out Maintainable Rails — my free email course for teams wrestling with legacy code, slow test suites, and Rails upgrades.
6. Debating
The conversations have shifted.
You’re not just trying to unblock tickets or shave time off deploys anymore… you’re openly asking if your current stack is still the right long-term choice.
Leadership wants to know what’s possible; and at what cost. Engineers are drawing diagrams to explain years of decisions. Technical assessments are being scoped. Rewrite proposals are floating around. But nothing feels definitive.
It’s clear that the team is capable… but tired. The stack feels like a weight rather than a boost. And while nobody wants to jump into a rewrite lightly, it’s starting to feel like you’ve run out of easy paths forward.
Some teams in this stage start experimenting with other frameworks or stacks. They build new tools in a different language. They reference how other companies are “doing it better.” Consultants are brought in to validate hunches… or challenge assumptions. As more data is collected, a clearer picture begins to form — but agreement doesn’t always follow.
This stage is emotionally charged. Some team members are fiercely loyal to the existing stack. Others feel it’s holding them back. People are reflecting on the past, imagining the future, and questioning whether the current path is still worth walking.
These aren’t easy conversations. But they’re necessary.
Signs your team might be in the Debating stage:
- Leadership is asking for estimates to rewrite “just part” of the system
- Engineers are referencing success stories from other tech stacks
- Framework upgrade tasks are scoped but rarely completed
- Tooling and infrastructure conversations dominate team discussions
- There’s little consensus on whether to modernize or replace existing systems
- Consultants or contractors are being brought in to offer a second opinion
This is a good time to pause and realign. Before making drastic changes, revisit your product vision, business constraints, and the real reasons things feel hard. Sometimes what’s needed isn’t a new stack… but a recommitment to the one you already have.
7. Recommitting
Eventually, your team has to choose: double down or start over.
Recommitting means you’re sticking with the stack you’ve built your product — and your team — around. Not out of nostalgia. Not because it’s perfect. But because it still works.
It’s not giving up. It’s opting out of the fantasy that a rewrite will magically fix everything.
You’re not trapped in sunk costs… you’re investing in the stack you already understand. That’s not weakness. That’s leverage.
Recommitting isn’t about nostalgia. It’s about making a grounded decision:
We’ve come this far… and we’re not done yet. So let’s make this better.
That decision unlocks a new type of energy.
Teams begin to invest in modernization efforts. Upgrades get planned — and actually delivered. Documentation becomes something people reference and improve. Refactors have purpose again, enabling future work rather than just cleaning up messes from the past.
Hiring starts to shift, too. You’re not just looking for people who know the stack — you’re looking for those who can help align and grow the team around it. Sometimes that means bringing in new voices. Sometimes it means letting go of folks who aren’t on board anymore.
Some people will move on. Some of them should.
And in a few cases, you might need to ask them to.
Your team might get a little smaller. That can be a really healthy thing.
Fewer silos. Fewer competing visions. More clarity. More momentum.
Recommitting is a forcing function. It requires saying “no” to the infinite set of other directions your team could go — and doubling down on the direction you’ve chosen.
It isn’t the end of the story.
It’s the start of the next cycle… but with your eyes open this time.
🔍 How to Identify What Stage You’re In
Before you can spiral upward, you need to know where you’re standing.
So… what stage are you in?
More importantly: would your teammates say the same?
You don’t need a quiz. You need a conversation.
Here are a few questions to spark that:
- If a new hire joined last week, how would they describe your team’s tech culture?
- When’s the last time someone challenged the way you work… and did it land?
- Are you hiring for what the team is today, or what it needs to become?
- What’s being quietly avoided in planning meetings?
- Are you moving with purpose, or waiting for permission?
Talk about it. With a peer. In a 1:1. Maybe even in your next retro.
💬 Invite Your Team In
Feel like this article hit a nerve? You’re not alone.
Drop the link in Slack or email with something simple:
“This made me think… curious which stage you think we’re in?”
“Stage 5 kinda hurt. Just me?”
🗳️ Try a Team Pulse Check
Post a quick poll:
“Which stage in this article feels most like us right now?”
Compare results. Disagreements are good. They reveal where your team’s stories aren’t aligned yet.
Which might be the most important thing to fix.
💡 What Teams Who Recommit Do Differently
So if your team has chosen to recommit, what happens next?
You’re not pivoting to the latest shiny thing. You’re saying:
We’re going to stick with Ruby on Rails (or insert your stack here).
And if you make that choice, here’s the work:
-
Center your stack in your culture.
Mention it in onboarding. Reference it in planning docs. Make it part of the story your team tells itself. -
Invest in internal education.
Run workshops. Build an internal playbook. Share tips, tricks, and hard-won lessons. -
Send people into the community.
Conferences. Meetups. Slack groups. Encourage curiosity. Normalize outreach. -
Sponsor the ecosystem.
Not just because it looks good. Because it gives your team a stake in the future of their tools. -
Hire differently.
Look for engineers who align with opinions, not just languages. Prioritize mindset over mastery.
Be the kind of place that attracts the kind of people who are drawn to strong opinions and clear commitments.
Because when you truly recommit, better questions become possible:
“If we’re still on Rails ten years from now, what might a healthy version of that look like?”
Maybe:
- You’re running the latest stable release of Ruby and Rails… always
- Your test suite runs against weekly Ruby and Rails builds to catch regressions early
- You file upstream bug reports before they hit your production code
- Rails upgrades happen continuously… not as Q3 projects
- New hires don’t ask, “What version are we on?” because the answer is always “latest”
- The phrase ‘legacy code’ stops meaning ‘scary’ — and just means ‘old.’
You don’t need to operate at Shopify scale. You just need a stack your team can rally around.
🏁 Wrapping Up: The Spiral Doesn’t End
If your team feels stuck somewhere between fragmenting, drifting, and debating… you’re not alone. You’re also not doomed.
Maybe… just maybe… you’ll never get out of the spiral. But you can rethink how you move through it.
Upward. Intentionally. With less friction and more momentum.
Because recommitting isn’t waving a white flag. It’s planting one.
It’s saying: We’ve been through the hard parts. We know what works. Let’s build on that instead of starting over again and again.
It’s choosing the long road because that’s where the depth is.
Your team — whether it’s ten engineers or four hundred — has an opportunity to write the next chapter in your stack’s story. And if you do it well, the next set of new hires won’t just inherit your tools. They’ll inherit your clarity.