Jillur Rahman

Jillur Rahman

Front-End Developer

Back to Blog
Development11 min read

Shopify App Overload: How to Replace 5 Expensive Apps With Custom Code

The average Shopify store pays $300–$600/month in app subscriptions for features that could be built once and owned permanently. A developer can replace most of them with lightweight custom code that performs better and costs nothing to run.

ShopifyAppsCustom DevelopmentPerformanceCost Reduction
Cover image for: Shopify App Overload: How to Replace 5 Expensive Apps With Custom Code

I audited a Shopify store last month that was paying $847/month in app subscriptions. Seventeen apps. Several of them added features that were genuinely useful. Several of them duplicated each other. And at least five of them were doing things that should have been built directly into the theme from day one.

This is not unusual. The Shopify App Store makes it extremely easy to add functionality — install, approve permissions, done. The problem is that every app you install adds monthly cost, adds JavaScript to your storefront (slowing it down), and creates a dependency on a third-party company to keep their app working with your theme.

Some apps are worth every dollar. Others are solving problems that a developer can solve once, better, for a fraction of the long-term cost.

Here's a breakdown of the most common apps that can be replaced with custom code.


App 1: Sticky Add-to-Cart Bar ($9–$15/month)

A sticky add-to-cart bar that appears as the customer scrolls down a product page — keeping the purchase option visible without having to scroll back up — is one of the most effective conversion tools on a product page.

Most stores add this via an app. The app injects JavaScript that watches scroll position and shows/hides a sticky bar element.

The custom code version:

// Sticky ATC — ~30 lines of vanilla JS
const productForm = document.querySelector(".product-form");
const stickyBar = document.querySelector(".sticky-atc");
 
if (productForm && stickyBar) {
  const observer = new IntersectionObserver(
    ([entry]) => {
      stickyBar.classList.toggle("visible", !entry.isIntersecting);
    },
    { threshold: 0.1 },
  );
  observer.observe(productForm);
}
.sticky-atc {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  transform: translateY(100%);
  transition: transform 0.3s ease;
  background: var(--color-background);
  border-top: 1px solid var(--color-border);
  padding: 1rem;
  z-index: 100;
}
.sticky-atc.visible {
  transform: translateY(0);
}

This is 40 lines of code total. It loads instantly (no external script request), matches your theme perfectly, and costs zero dollars per month. Replacing a sticky ATC app with this code takes about 2 hours of developer time.


App 2: Product Tabs ($8–$20/month)

Tabs on product pages — "Description," "Shipping," "Size Guide," "Reviews" — are a standard pattern for organizing product information without overwhelming the page.

Apps that handle this inject their own HTML structure, styles, and JavaScript. They rarely look exactly like your theme, and they add HTTP requests.

The custom code version:

In Liquid, a tabbed section is straightforward:

{% comment %} sections/product-tabs.liquid {% endcomment %}
<div class="product-tabs">
  <div class="tabs-nav" role="tablist">
    {% for tab in section.blocks %}
      <button
        class="tab-btn {% if forloop.first %}active{% endif %}"
        role="tab"
        aria-selected="{{ forloop.first }}"
        aria-controls="tab-{{ forloop.index }}"
        data-tab="{{ forloop.index }}"
      >
        {{ tab.settings.title }}
      </button>
    {% endfor %}
  </div>
 
  {% for tab in section.blocks %}
    <div
      id="tab-{{ forloop.index }}"
      class="tab-panel {% unless forloop.first %}hidden{% endunless %}"
      role="tabpanel"
    >
      {{ tab.settings.content }}
    </div>
  {% endfor %}
</div>
 
<script>
  document.querySelectorAll('.tab-btn').forEach(btn => {
    btn.addEventListener('click', () => {
      document.querySelectorAll('.tab-btn, .tab-panel')
        .forEach(el => el.classList.remove('active'));
      btn.classList.add('active');
      document.getElementById('tab-' + btn.dataset.tab).classList.remove('hidden');
    });
  });
</script>

The tabs are editable in the Shopify theme editor (each tab is a block with title and content settings). Zero app dependency, zero monthly cost, styled to match your theme exactly.


App 3: Size Guide Popup ($7–$15/month)

A size guide popup triggered from a "Size Guide" link on product pages is another extremely common app install — and another thing that's straightforward to build as a native theme feature.

The implementation is a Shopify section with a size_guide_image setting (or metafield, if size guides vary by product) and a modal triggered by a button:

{% if product.metafields.custom.size_guide %}
  <button
    class="size-guide-btn"
    data-modal="size-guide"
    aria-haspopup="dialog"
  >
    Size Guide
  </button>
 
  <dialog id="size-guide" class="modal">
    <button class="modal-close" aria-label="Close">✕</button>
    <img
      src="{{ product.metafields.custom.size_guide.value | image_url: width: 800 }}"
      alt="Size guide for {{ product.title }}"
      width="800"
      loading="lazy"
    >
  </dialog>
{% endif %}
document.querySelectorAll("[data-modal]").forEach((trigger) => {
  trigger.addEventListener("click", () => {
    document.getElementById(trigger.dataset.modal).showModal();
  });
});
document.querySelectorAll(".modal-close").forEach((btn) => {
  btn.addEventListener("click", () => btn.closest("dialog").close());
});

Native <dialog> element. No library, no app, no JavaScript framework. Accessible by default (browser handles focus trapping and escape key). Per-product size guide images via metafields.


App 4: Product Bundle Builder ($25–$49/month)

"Frequently bought together" or "Build your bundle" sections that let customers add multiple products to the cart with a discount are high-value conversion features — but the apps that provide them often cost $25–$50/month and conflict with other JavaScript on the page.

The core logic is a custom Liquid section that displays related products with checkboxes, calculates the combined price (with any bundle discount), and submits a multi-item add-to-cart form:

{% comment %} Fetch bundle products from metafield references {% endcomment %}
{% assign bundle_products = product.metafields.custom.bundle_products.value %}
 
{% if bundle_products %}
<div class="bundle-builder" data-discount="{{ section.settings.bundle_discount }}">
  <h3>{{ section.settings.title | default: "Complete the Set" }}</h3>
 
  {% for bundle_item in bundle_products %}
    <label class="bundle-item">
      <input
        type="checkbox"
        name="bundle[]"
        value="{{ bundle_item.variants.first.id }}"
        checked
        data-price="{{ bundle_item.variants.first.price }}"
      >
      <img src="{{ bundle_item.featured_image | image_url: width: 100 }}" alt="{{ bundle_item.title }}">
      <span>{{ bundle_item.title }}</span>
      <span>{{ bundle_item.variants.first.price | money }}</span>
    </label>
  {% endfor %}
 
  <div class="bundle-total">
    Bundle total: <span id="bundle-price"></span>
  </div>
  <button type="button" id="add-bundle">Add Bundle to Cart</button>
</div>
{% endif %}

The JavaScript handles price calculation, discount application, and the cart API calls. This is a 1–2 day development project, and after that initial investment, there's no monthly fee.


App 5: Back-in-Stock Notification ($15–$30/month)

When a product is sold out, a "Notify me when available" email capture keeps customers engaged and drives revenue when you restock. Most stores use an app for this that costs $15–$30/month.

The custom implementation stores email addresses via a Shopify app proxy or a simple Next.js API route, triggers a Shopify email automation when inventory levels change via webhook, and shows the signup form conditionally based on variant availability:

{% if variant.available == false %}
  <div class="back-in-stock">
    <p>This item is sold out.</p>
    <form id="bis-form" data-variant="{{ variant.id }}">
      <input type="email" placeholder="your@email.com" required>
      <button type="submit">Notify Me</button>
    </form>
  </div>
{% endif %}

The backend uses Shopify's inventory webhook (inventory_levels/update) to trigger notification emails when a variant's inventory goes above zero. This requires server-side code (a Next.js API route or a small Cloudflare Worker) but is a one-time build.


The App Audit Framework

Before replacing any apps, audit what you actually have:

Step 1: List every installed app and its monthly cost.

Step 2: For each app, answer: Is this feature something customers directly interact with? Is it available as a Shopify native feature? Could it be built as a theme component?

Step 3: Group apps into three buckets:

  • Keep: Core to your operations, no reasonable alternative (review platform, email marketing, shipping rates)
  • Replace with custom code: UI features that could be theme components (sticky ATC, tabs, size guides, popups)
  • Remove: Apps you installed but aren't actively using

Step 4: Calculate the 12-month ROI of replacing "replace" bucket apps with custom code. If the custom build costs $800 in developer time and replaces $300/month in apps, the payback period is under 3 months.


What This Is Not

Custom development doesn't replace every app. Your email marketing platform, review collection service, subscription billing app, and shipping rate calculator are services that provide ongoing value and infrastructure that would take significant engineering to replicate. Keep those.

The target for replacement is the category of apps that add small UI features to your storefront — things a developer can build as native theme functionality in a day or two. These are the apps that are most likely to slow your store down, create theme conflicts, and charge you ongoing fees for something that should have been built once.

If you want to run this audit on your own store, I'm happy to look at your current app list and identify which ones are candidates for replacement and what the custom build would cost.

Tags:ShopifyAppsCustom DevelopmentPerformanceCost Reduction
Jillur Rahman — author

Jillur Rahman

Open to work

Front-End Developer & Shopify Theme Specialist — building fast, conversion-focused web experiences for agencies and brands worldwide.

All articles