Ecom Society
Designed with an agency over nine months, then rebuilt solo in two weeks, then again in one. Same platform, around 85% less infrastructure cost, zero downtime through both migrations.
- Product Design
- Design Systems
- Full-Stack Build
- Mobile

What it is
A platform for people opening their first store
Ecom Society sells access to the thing most first-time sellers are missing: a route. Courses, a step-by-step checklist that runs from buying a domain to scaling a store that already sells, live streams with people who have done it, and a directory of vetted partners for fulfilment, shipping and payments, each with an offer negotiated on members’ behalf.
Two tiers, and they stack in an order that is deliberate. The annual membership unlocks the courses, the checklists and the partners. The monthly one adds the Discord community and the live streams, and can only be bought from inside the platform, which means only annual members ever see it. The community sits behind the tier that proves intent.
I designed it, then I built it, then I built it twice more. What follows is the product as it stands, and then the three times it was made.

The product
What a member actually sees
The dashboard is a resumption surface, not a summary. Continue watching, checklist progress with the next unticked step surfaced, the live stream calendar, and a five-step startup guide that ticks itself off as the underlying courses complete, then disappears when there is nothing left in it.

Dashboard. Continue watching, next checklist step, upcoming streams.

Five checklists, beginner through scaling. Free-roam by choice.

An item carries a description, artwork, an outbound partner link and a lesson.

Course library.
The checklist
The most-used thing in the product
Five checklists run from “you own nothing yet” to “you have a store and want it bigger”. Nothing is gated. Sequence is obvious enough that most people follow it, and being able to read ahead is what makes the platform feel like a map rather than a drip feed.
Items deep-link into the exact lesson that explains them, so the answer to “how do I actually do this” is one click, not a search through a course library. Progress persists per member, and it drives what the dashboard surfaces next.

Lessons stream from VdoCipher, embedded by ID.

Partners, filterable by category.

Each partner page states the exclusive offer plainly.

Live streams run on Discord, then land here as recordings.
Build 01 · Nine months
An agency built it. I led the design.
January to September 2025. I owned design end to end: every screen and every interaction, drawn at desktop, tablet and mobile, with two UI/UX designers working to me and a graphic designer producing course artwork against specs I wrote, sizing and contrast included. I also built the first design system here: colour, type, spacing, radii.
I did not write the code. An external agency did, on Laravel and Vue.
Backend
Laravel 11, PHP, Sanctum
Frontend
Vue.js, Inertia.js, Vite
Data
PostgreSQL, Redis, Meilisearch, Laravel Scout
Media and services
AWS S3, CloudFront, VdoCipher, CopeCart, GoHighLevel, Discord

Every screen specced at three widths in Figma.

The agency build, live.
Build 01
What it actually cost
The build was not bad. Load times were slow, responsiveness broke on some devices, and the shipped result drifted from the design despite three widths being specced for every screen. That gap is normal.
The expensive part was the loop. Any design change, however small, cost a week: draw it, hand it over, wait for dev, wait for QA, take it back. I started declining my own ideas. Not because they were wrong, but because they were not worth a week. A backlog full of improvements sat still while I triaged by cost of delivery instead of by value.
The deeper problem was not speed, it was dependency. Our platform, our data and our pace all lived inside someone else’s shop.
Build 02 · Two weeks
I rebuilt it myself, on Base44
By late 2025 the AI build tools had got good enough that I could take the whole thing. January 2026, I rebuilt Ecom Society on Base44 in about two weeks, design and code, alone.
It was not a port. Dark mode had been asked for since launch, so I rebuilt the design system with tokens for both themes and let members choose. I moved off bespoke components onto a React component library and restyled it to our brand, which was faster to build and faster to load than what it replaced. Payments moved from CopeCart to Stripe, which meant rebuilding the products, the webhooks and the automations that grant platform and Discord access on payment.
Base44 was a sandbox and we knew it going in. It was cheap enough to answer the only question that mattered: can a product built this way carry real paying members in production. It could.

Migration one
Moving 160 members without losing them
We did not carry passwords or sessions across. Before deciding that, I checked: around 93% of members already signed in with a Gmail address. So the new platform went Google-only, existing members were matched on the email they already used, and everyone else got a support path to connect an account.
Zero downtime. The old platform stayed up for a two-month grace period with a banner on every page pointing at the new one. We lost somewhere between twenty and thirty accounts, all of them already inactive, which told us more about their engagement than about the migration.
One thing genuinely did not survive: course progress. Build one never tracked it granularly enough to move. We said so in the announcement and apologised for it rather than quietly resetting everyone.
Build 03 · One week
One missing feature forced the third build
Members wanted a native app. Rather than build a second client and keep two systems in sync, I wrapped the web app in a native shell, so every web deploy is also an app update and admins keep one place to publish.
That plan died on one detail. Base44 could not register redirect URIs, so Google sign-in inside the webview handed off to the system browser and had no way back into the app. Everything else about Base44 was fine. This one thing was fatal.
May 2026: I exported the codebase, moved it to Replit and rebuilt it pixel for pixel in about a week. Secrets were moved by hand and never passed through a model. Since the platform was sitting in staging anyway, I used the window to add what build two lacked: real tracking across checklist ticks, lessons watched and courses completed, which is now what tells us how the product is actually used.
Frontend
React 19, Vite 7, React Router, TanStack Query, Tailwind CSS, Radix UI, Framer Motion, Recharts, Three.js
Backend
Node.js 24, TypeScript, Express 5, esbuild, Pino, Zod
Data
PostgreSQL 16, Drizzle ORM, Drizzle Kit
Services
Google OAuth, Stripe, VdoCipher, Discord, Resend, RevenueCat
Mobile
Capacitor 8, Remote-mode iOS shell, Native Google OAuth with PKCE
Tooling
pnpm workspaces, Orval, Prettier, Node test runner, Replit Autoscale
Migration two
The one nobody noticed
Because build three was a pixel-for-pixel replica, there was nothing to announce. I staged the whole platform on a separate domain, tested it, then swapped the domain over.
No downtime, no announcement, no support tickets. We watched activity across the cut and it was flat against the previous build. The best possible result for a migration is that it does not register as an event.
The admin half
The product nobody sees, and the one that decides whether this scales
A platform that needs a developer to change a lesson title is not finished. So the larger half of the build is an admin portal where the team runs everything without me: courses, modules and lessons, live streams, checklists, partners, notifications and members.
Publishing a lesson is pasting a VdoCipher ID. Course analytics run both directions: per course, how many are enrolled, average progress and completions, and per member, exactly where they are. Member management covers tier changes, granting lifetime access, cancellation, blocking and email invitations, none of which used to be possible without a manual database edit.
Two things I insisted on. Every admin action is written to an audit log with history, so a change is always attributable. And member data is isolated at the data layer with row-level rules, so a member can read their own progress and, structurally, nobody else’s. That is not a permission check in the UI that a bug can route around.

Admin overview: courses, streams, members at a glance.

Course, module and lesson editor. Publishing is a VdoCipher ID.

Member management: tier, expiry, access, blocking.

Audit log. Every admin action, attributable, with history.
Mobile
A native shell over one codebase
Capacitor 8 in remote mode. The app loads the live web platform, so shipping to web ships to mobile and there is exactly one place to publish content. Safe areas are resolved per device so a browser inside a shell stops reading like one.
Auth is the piece that forced this build, so it got the most care. Google sign-in uses a native handoff with PKCE: the account picker appears over the app, and the member is returned signed in without ever leaving it.
Apple rejected us twice. First on guideline 3.1.1, which requires in-app purchase for digital content sold inside a webview. I solved that with RevenueCat: the subscriptions are registered as store products and a signed-out member opening the app gets the native paywall and pays through Apple. The second rejection asked for Sign in with Apple. iOS first was a deliberate order, on the theory that anything clearing Apple clears Google. Offline access is deferred on purpose until the app is live. It is in review as this is written.

Dashboard

Course player

Native paywall via RevenueCat
9 mo → 1 wk
Build time, agency delivery to solo rebuild
~85%
Reduction in infrastructure and delivery cost
0
Minutes of downtime across two full migrations
What it taught me
The cost was never the retainer
I would not undo build one. In early 2025 an agency was a reasonable way to get a real platform live, and the design work from that year is still the backbone of what runs today.
What I misread was where the money went. The retainer and the AWS bill were visible, and cutting them by roughly 85% is the number people react to. The real cost was the week. A week per change is a tax on every idea, and it gets paid in the features you talk yourself out of rather than the ones you ship. That cost never appeared on an invoice.
The second thing is that owning the build changed what I would attempt. When a feature costs an afternoon, I stop triaging by delivery cost and start running several in parallel, each on its own branch, and merging what survives. Dark mode, per-member analytics and the audit log all exist because they became cheap enough to be worth doing.
Three builds in eighteen months reads like churn. It was one product held steady while the thing underneath it was replaced twice, in the open, without members losing a session. That is the part I am proud of.
Next case study