John Singh

Shopify theme development — Liquid, metafields, front-end performance

I build and repair Shopify storefronts: custom Liquid sections, product-data architecture that merchants can actually maintain themselves, and the unglamorous front-end work that makes a page load quickly and behave on a phone.

The work below has a price, a written scope and the working days it takes. Everything else, I quote fixed before I start. I take on selected work through freelance platforms, such as Upwork, and I’m not taking direct orders or bookings through this site. On the platform we use, the agreed listing or offer sets the actual scope, price and calendar deadline, and payment goes through that platform, under its terms. Fees the platform or a payment processor charges on top of my price are separate from it, and whether they can be refunded follows the platform’s terms. Any refund I owe is still my responsibility, even if the platform has already released the payment to me and can’t reverse it.

Fixed price

WorkPrice
Speed fix, one template5 working days$550
Speed fix, home, collection and product7 working days$1,200
Purchase tracking, repaired3 working days$300
Black Friday readiness pass3 working days$199
A front-end fix2 working days$150
A custom section4 working days$350
Product data, structured10 working days$1,200

Prices are in US dollars (USD). Not sure where your store stands? The free speed check runs Google’s mobile test on one page and shows you how to read it, and the free catalog check counts every product with no photo or no description.

Scope and guarantees

Software

RosterPress is my browser tool for small shops that make personalised team apparel. It turns the spreadsheet a customer sends with a team order into proofs, a production packet and packing labels, and flags questions for you to answer.

Try the production packet, packing labels and CSV as marked trial copies, using an order you’ve already finished. Purchasing isn’t open yet. Try it on a finished order.

A worked example

A common one, and a good illustration of how I think about this work.

A store with deeply detailed product pages can keep its specification rows in metaobjects, referenced from a list.metaobject_reference metafield on each product. I group the rows by section of the page rather than keeping one list for everything: one reference metafield per section, so each section’s rows stay together and are edited in the admin, and the rendering is the same few lines for every section:

{%- assign rows = product.metafields.custom[block.settings.field] -%}
{%- capture body -%}
  {%- for row in rows.value -%}
    {%- assign label  = row.label.value  | strip -%}
    {%- assign detail = row.detail.value | strip -%}
    {%- unless label == blank and detail == blank -%}
      <dt>{{ label }}</dt><dd>{{ detail }}</dd>
    {%- endunless -%}
  {%- endfor -%}
{%- endcapture -%}

{%- assign filled = body | strip -%}
{%- unless filled == blank -%}
  <section class="spec-group">
    <h2>{{ block.settings.heading }}</h2>
    <dl>{{ body }}</dl>
  </section>
{%- endunless -%}

If a product has no rows for a section, the capture comes out empty and the whole block — heading, wrapper and all — never renders. No conditional per feature, and nothing to maintain when a section is added next year.

The code sets no limit on how many rows a section holds: the grouping is for order and editing, not a size cap.

See it running

I built the section above, and a product comparison table that reads the same data, into a demo store on Shopify’s current Horizon theme. Three desks, spec sheets that hide empty groups, and a comparison that marks a missing value with a dash instead of breaking the row. It is a demo store, not a client’s, and says so.

john-singh-demo-store.myshopify.com  ·  password-protected (Shopify requires a password on development stores)

Separately, a speed demo: a fictional product page for a made-up desk brand, built as two static pages (not a Shopify store, and not the demo store above), once with six problems that commonly slow a store down and once with them fixed. In Google PageSpeed Insights’ mobile lab test on 22 September 2026, the score went from 68 to 96, and the main product photo appeared in 2.7 seconds instead of 24.3. It shows the method, not a result on a real store. See the before and after, with both reports.

How I work