Feature teams are the idea that multiple teams can work together to create a piece of software, structured so that each team builds features of the product and is responsible for whatever changes are necessary to every portion of the application involved in delivering that feature. This is contrasted against component teams, where an individual team owns a particular portion of the application and is responsible for making all changes to that portion for every feature.
Component teams historically seemed a good response to scaling up work. You went from having one person alone building a thing to one team building a thing. Within the team, each individual had unofficial ownership of the code they wrote because they knew it best and people would naturally gravitate towards them with questions and requests related to that code. Ownership corresponds with a better understanding of that specific portion of the domain. It can also encourage you to take pride in your work and creates an incentive to do your best since any issues with it will come back to you. Then, having a single team wasn’t enough, so you had to start having multiple teams for a piece of software. As you formed a team for the component, either the team overall took ownership or individuals owned and maintained smaller portions of the overall component.
It made sense in the boxed software world, where you built version one and never needed to really change it. In the modern software world the system evolves regularly, by design. And evolving software has different needs; a component will have different amounts of change required at different points in its lifecycle. This means that a team could be overwhelmed sometimes and idle others. This can cause blocking issues for other teams and scheduling work.
Feature teams resolve a lot of these issues by unblocking work, but you lose the benefits of ownership. You can try and apply collective code ownership to all of the feature teams, but the domain knowledge wouldn’t develop the same way. And once you hit a certain size of team or code, the pride of ownership can go away too.
There are a couple of ways to balance the two. You can use feature teams with an affinity towards features with impacts on particular parts of the system, but that can easily become more complicated with the exclusion of others. Building Microservices proposes using a structure like an open source project internally to allow others to put in a proposed change and have a team who is responsible for being sure it integrates cleanly and to be responsible for the overall cohesion of the component. I haven’t had a chance to try this, but it seems highly promising.
Neither approach to structuring your teams is right or wrong, but by looking at both, understanding the pros and cons, and picking the right one for your needs can be a great boon, rather than dogmatically picking one or the other.