An app is a monthly fee, a block of JavaScript on every page, and a dependency you do not control. Sometimes that is a fair trade. Often it is not, because the thing the app does is a feature the theme can hold on its own: a bundle, an upsell, a size guide, a free shipping bar, a tabbed description, a review block. Built into the theme these cost nothing per month, load with the page rather than after it, and cannot be broken by somebody else's release.
Portrelle is our own skincare label. It runs fourteen conversion features in three languages with no apps paying rent, because all fourteen live in the theme. That is not a boast about frugality, it is about control: nothing on that store can be changed by a vendor we do not employ, and nothing on it waits for a third party script to load before it works.
How to find out what your apps actually cost you
Run your product page and your cart through PageSpeed Insights and read the field data, not the lab score. Then open the page source and count how many third party domains load before anything the customer can use appears. Then open your Shopify billing and put a number next to each app. You now have the two halves of the trade in front of you, and in most stores three or four apps account for most of both.
The question is never whether an app is good. It is whether the feature is worth a script on every page and a bill every month.
The three categories
Keep. Anything that does real work you cannot replicate: your email platform, your reviews if they carry verified purchase data and syndication, a genuinely complex subscription or loyalty engine, your accounting connection.
Replace. Bundles and volume discounts, free shipping progress bars, upsells and cross sells on the product page, size guides, tabbed or accordion product copy, announcement bars, currency and language switchers where the theme already supports markets. Each of these is a theme change, done once.
Remove. Anything installed for a campaign that ended, anything with an overlapping function, and anything whose script is still loading after the app was disabled, which is more common than it should be. An uninstalled app frequently leaves its snippet behind in the theme.
The part people get wrong
Speed is not the only reason and often not the main one. The main one is that a feature living in the theme can be designed to fit the store, while a feature living in an app looks like the app. A bundle widget that does not match your typography reads as bolted on, and customers notice that before they notice a load time. If your store looks like several different companies made it, that is usually the cause.
Do not rip everything out at once
Replace one app per release, keep the old one installed but disabled for a week, and watch conversion rate and revenue per session rather than page speed. Speed improving while revenue falls means you removed something that was working, and you want to be able to tell which change did it. Read the comparison the way Shopify's own benchmark data lets you read it, against stores your size, rather than against a published average.
What we do with it
We audit the stack against the theme first, then build the replaceable features in, one release at a time, with the old app disabled rather than deleted until the numbers hold. What that looks like finished is on the Portrelle build study, and the service is on the CRO and website page.