I’m Badii Boutar. I build online stores for clients, mostly in Tunisia and the Gulf. In April 2026 I started The Merchant Engine, the store I now use for that work, and in October I released it as open source under MIT. This post explains why I built it instead of using what was already there.
The same store, again and again
My clients sell very different things, but their stores ask for the same list:
- Arabic, French and English, with Arabic right to left, and product names, pages and emails translated, not only the buttons.
- Cash on delivery as the main way to pay, because many customers in these markets do not pay by card online.
- A phone number on every order, because the shop calls before the courier leaves.
- An admin a shop owner can use without a developer next to them.
- Invoices, returns, gift cards and promotions, in the local currency and the local tax rules.
Every new client meant building most of that list again, on a different base, with the same bugs coming back. At some point it was clear that I was not building stores. I was rebuilding one store, badly, many times.
Why not an existing platform
I tried the usual options for client work. Each one was close, and each one missed in the same places.
- Hosted platforms handle cards well, but cash on delivery and right to left often feel added on later. The monthly fees and app fees are also hard to justify for a small shop in Tunis.
- Open-source platforms gave me the code, but many were built around one language and one currency first. Arabic often meant a theme fix, not a full locale with its own search, invoice and email text.
- Some had a paid tier or a license key for the parts I needed. For an agency, that means a cost per client and a dependency on someone else’s pricing page.
None of this makes them bad products. They were built for other markets. I wanted one that started where my clients are.
What I built
The Merchant Engine is three apps in one repository:
- A NestJS API, split into 33 modules: catalogue, cart, checkout, orders, payments, shipping, tax, returns, gift cards, promotions, reviews, search, CMS, SEO, mail, webhooks and more. Each module owns its tables and never touches another module’s tables.
- An Angular admin where the shop owner runs the store: products, orders, stock, customers, content and settings.
- An SSR storefront built with Analog, so pages are rendered on the server and search engines can read them.
A few choices shaped everything else:
- Three locales from day one. Arabic, French and English ship in every install, and every text field a customer sees can be translated. Direction is data, so an Arabic page is right to left because the store says so, not because of an
ifon the codear. Adding a fourth language is one registry entry plus its strings, not a change in every module. - Cash on delivery first. The checkout, the order states and the invoices were designed around a payment that arrives days after the order. I wrote about the details in Cash on delivery checkout done right.
- One build for every store. The store’s name, brand colors, locales, currency and domains are entered once in the install stepper and read at runtime. I do not fork the code per client.
- One command to install.
./setup.sh --localasks for the store’s identity, brand, locales and money, then starts the stack.
Zero license keys
I first thought about selling licenses. I decided against it.
A license key helps the seller, not the store. It is one more thing that can fail at install, one more check at boot and one more reason an agency says no. The engine is MIT: use it for any store, paid or not, change it and ship it. There is no paid tier, no feature behind a flag and no cap on products or orders.
I still earn from it the same way I did before. Some store owners do not want to run a server. I install, customize, host and maintain the store for them as Badii Studio. The difference is that the base is now open, so anyone can check what they are paying me to run.
What it is not
To be clear about the limits today:
- Stripe is the only card provider so far. Since v1.0.1 a shopper can pay by card once you enter the Stripe keys in the admin. If you need another card provider on launch day, this is not the store for you yet.
- No live carrier rates. Shipping uses zones and the rates you enter in the admin, with tracking links per carrier.
- No plugin marketplace. You change the code, or you ask me to.
- One person. I build it alone. I answer issues and discussions myself, and I will be honest about what is planned and what is not.
The full list of what ships is on What you get.
Who it is for
- Agencies and freelancers who build stores for clients, especially in markets with Arabic, French or cash on delivery.
- Developers who want a full store they can read: one schema, one set of types and one test suite across the API, the admin and the storefront.
- Shop owners who want their own store without a monthly platform fee, and who are fine with someone, them or me, running a server.
What I’d do
If any of that sounds like your work, try it before you trust it. Place an order on the storefront demo, open it in the admin demo, then run ./setup.sh --local on your own machine with the install guide.
The code is on GitHub under MIT. If something is missing for your market, tell me in the feedback discussion. That is the most useful thing you can send me right now.