Supabase as an ecommerce backend, where it helped and where it hurt
What we learned running a real store on Supabase and Next.js: what it saved us, the four places it fought back, and when to pick something else.
Almost everything written about Supabase is a tutorial that stops at the happy path. Auth in ten lines, a table, a select, a deploy button. Then you build something a business depends on and discover the parts the tutorial skipped.
We run a store on it. Dasgowar sells hand-stitched Balochi textiles, doch embroidery from Kech, Panjgur and Mastung, direct from the workshop. Twelve products across six categories at the time of writing, prices in the Rs 1,500 to Rs 3,200 range, order tracking, and an admin panel the workshop owner runs without us.
What Supabase actually is, for this purpose. A hosted Postgres database with an auto-generated API, authentication, file storage and row-level security bolted on. It is not a commerce platform. There is no cart, no order model, no inventory, no checkout. You get a very good database and you build the shop yourself.
That distinction is the whole article.
What it genuinely saved us
It is Postgres. That matters more than any of the branding around it. Real foreign keys, real transactions, real constraints. When an order and its line items have to be written together or not at all, you get that from a database that has been doing it for thirty years, and a good deal of the backend-as-a-service category cannot say the same.
Then the API arrives free with the schema. Define a table, get an endpoint. For a store with a dozen product types and a handful of relationships between them, that removes a whole layer we would otherwise have written, tested and maintained ourselves. On a project this size that is not a small saving.
Auth, file storage and the data all sit in one place too. One vendor, one dashboard, one bill, and no integration seam between the login system and the rows it is meant to be protecting.
The storefront itself is a Next.js app on Vercel, served out of the Mumbai region, which is the closest one to Pakistan. That proximity does more for how quickly the site answers a phone in Quetta than anything we could do inside the database, and we have measured what the distance costs. Supabase is the data layer behind it and nothing more.
Where it hurt
Four places, and they are the honest reason to read this rather than a tutorial.
Row-level security is the entire security model, and it fails open in your head
Every table starts unprotected. You turn RLS on, and from that moment every read and write is governed by policies you write in SQL. That is a good design and it is also the thing most likely to hurt you, because the failure mode is silent.
A table with RLS enabled and no policy returns nothing, which you notice immediately. A table with RLS never enabled returns everything to anyone holding the public key, which you do not notice at all. Nothing in the interface shouts about it and the app works perfectly either way.
Our rule now is that RLS is part of the table definition, not a step afterwards, and no table ships without someone other than the author reading its policies. Treat an unprotected table as a bug of the same severity as a leaked credential, because that is what it is.
There are no commerce primitives, and you will underestimate that
You are building the cart, the order state machine, stock decrementing, price history, and the rules about what happens when someone orders the last item twice in the same second. Postgres gives you the tools to do all of it correctly. It does not give you any of it.
That is fine, and it is why the store does exactly what this business needs rather than what a platform assumed. But when you compare a Supabase build against a hosted commerce platform on price, compare honestly: you are quoting to build features the platform ships on day one.
Serverless and database connections do not naturally get along
A traditional server opens a few connections and keeps them. Serverless functions spin up per request and each one wants its own. Scale that and you exhaust the connection limit while the database itself is barely working.
Supabase provides pooling and it solves this, but it is a thing you have to know about and configure rather than something that is right by default. If you have never thought about the difference between a pooled and a direct connection, this is where you will meet it, usually under load, usually at the worst time.
Images will quietly become your biggest cost and your slowest page
Craft products sell on detail. You have to see the stitch, which means large photographs, on a site whose buyers are usually on a phone and often on a connection that cannot afford them.
Serving what the camera produced is the obvious approach and it is wrong twice over: the pages get heavy, and you pay bandwidth on every view of a file far larger than the screen showing it. Storage is cheap and egress is not, which is the opposite of how most people assume it works.
So the conversion happens at upload. Every product image is turned into WebP and written at three fixed widths, 320, 480 and 1280 pixels, each in its own folder in storage. Phones get the 320 or the 480, desktops get the 1280, and the workshop uploads whatever the camera produced and never learns what WebP is. That last part is the only version of this that survives contact with a real business.
Two decisions that mattered more than the stack
Guest checkout, no account. Every platform wants shoppers to register, because accounts give you email addresses and repeat-purchase data. They also put a form between a person and a purchase, and for buyers arriving from social media on an unreliable connection that form is the highest-friction moment on the site.
We removed it. The cost is real and worth naming: no order history for the shopper, harder returns, no built-in mailing list. For this store that trade was clearly right. For one selling repeat-purchase consumables it would be clearly wrong.
Almost everything is editable. Products, prices, images, categories, the copy on the pages. This is more work than a standard build and the argument for it is simple: a store that needs a developer to change a price is a store that stops changing prices.
What we would do differently
Ship structured data at launch. Dasgowar has no Product schema on its product pages today. Price, availability and product name could all be appearing in search results and they are not. It is roughly half a day of work and we should have done it before launch rather than after. We are fixing it.
Decide the search strategy earlier. Postgres full-text search is good and it is free and it is right there. It is also not what a shopper expects if they are used to typo tolerance and instant results. At twelve products this is invisible. At two hundred it will not be, and retrofitting search is more work than choosing it up front.
When not to use it
If you want a shop this week and the business is a standard catalogue with standard checkout, use a hosted commerce platform. You will be live faster and cheaper, and the constraints will not bother you until you are much larger. We tell clients this and we lose builds because of it.
Supabase earns its place when the shop is not standard. When the admin panel matters more than the storefront, when the data model has something specific in it, when you need the thing to be genuinely yours and portable because it is Postgres underneath and always will be.
Dasgowar is that second kind. A workshop with an unusual product, a non-technical owner who needed real control, and buyers on connections that punish a heavy page. A platform would have fought all three.
Talk to us
If you are weighing a custom store against a platform and want an honest read on which side yours falls, describe the shop and we will tell you. There is a longer piece on the questions worth asking whoever you end up hiring.

