Oriire started on Wix in 2018, enough to test whether anyone wanted it. The next stop was Webflow, where the platform actually grew up. Articles, authors, content types could finally live in a CMS with structure. Contributors came in. The podcast launched. At its peak the site was reaching over a million impressions a month.
By 2025, Webflow had stopped scaling with what Oriire needed to do. The editorial pipeline was Webflow form to Zapier to Notion to manual emails to manual publishing back into Webflow. Each handoff dropped something. Authors stopped knowing whether their submissions had arrived. Email automations frequently did not fire, and paid contributors did not always receive receipts. The CMS costs kept climbing. Building a proper membership tier required stitching together third-party tools that each added cost and fragility. At some point the question stopped being how to make the existing system work. It became whether continuing to do so was the right decision at all. It wasn't.
The current setup
The platform is now built on Next.js 16 with TypeScript, deployed on Cloudflare Workers via OpenNext. Supabase handles authentication, the database, and storage. Media is served through Cloudflare R2.
The stack is less interesting than what it makes possible.
Contributors submit work through an editor with rich text, image uploads, and metadata tagging. The submission goes into an editorial pipeline covering review, revision requests, editorial notes, acceptance, payment, and publication. Each stage is tracked and nothing lives outside the system. Published content connects into a structured archive that links related entries, cultural figures, and authors across the platform. Memberships, payments, and contributor compensation all sit inside the same system. They were built that way deliberately, because managing them across separate tools was one of the things that had made the previous setup unsustainable.
Roles, and why they matter
One of the less visible decisions in the build was how to handle the fact that the platform serves genuinely different people with genuinely different needs.
There are six roles, ranging from visitor and member through contributor, author and editor to admin. Each sees a meaningfully different product. A visitor gets the public archive. A member gets gated content and a membership dashboard. A contributor can submit work, track its status through the editorial pipeline, and receive feedback inside the platform. An author has a public profile linked to published work. An editor sees the full submission queue and can review, request revisions, log payments, and publish. An admin has access to everything.
The reason this matters architecturally is that the same action can mean different things depending on who is doing it. A contributor and an editor can both open the same submission, but what they can see, change, and do is entirely different. Getting that wrong does not just create confusion. It creates trust problems. A contributor who can accidentally see another contributor's unpublished work, or an editor shown the wrong controls, breaks something that is hard to recover from. QA had to be done across every role, every time something changed, because the cost of getting it wrong was real.
Payments
Payment had its own complexity, and it was worth thinking through carefully because getting it wrong would have affected contributors directly.
Oriire has multiple membership tiers at different access levels. Paystack handles payments across Nigeria and other African markets. Ko-fi handles international supporters where Paystack is not yet available. Both feed into the same membership state inside the platform. Contributors are paid for accepted work and the process sits inside the editorial dashboard. An editor logs the payment, attaches a receipt, and updates the submission status. The contributor's record reflects it. Receipts are stored in a separate private storage bucket, isolated from the public media files. Receipts are sensitive and should not be reachable through the same path as a published article image, so keeping them separate was a deliberate decision rather than an afterthought.
What broke during the build
Media costs. Transforming images on demand at scale is expensive, so we decided to stop doing it. Images are now compressed and resized into three variants (full, card, and thumbnail) at the moment of upload, before the file reaches storage. Everything is served from Cloudflare R2, which has no egress fee. This was not the obvious first solution. It required changing where in the process the work happened, from delivery time to upload time, which is a different way of thinking about the problem.
Migrating existing content without breaking anything. When the platform moved to R2, there were over 800 images from the Webflow era stored in a separate bucket with a different URL structure. Those URLs were not contained to database columns. They were embedded inside the HTML of article bodies, references that had been written directly into content over years. The options were to fix them manually, which was not realistic at that volume, or to write migration scripts that could handle files, database records, and inline body content in one pass. Migration scripts were written. 825 files transferred. 484 records updated across seven tables. The content came through intact.
Uploads from the browser. Direct uploads from a browser to R2 require exposing API credentials on the client side, which is not an option. Uploads are routed through a Supabase Edge Function instead. The browser sends the file to the function, which handles the upload server-side and returns the URL. The credentials never leave the server. It is a small architectural decision, but the alternative would have meant putting keys somewhere they should not be, and that tends to become a problem later.
Where it stands
Six years in, Oriire holds 244 articles, 18 Codex entries, and 43 podcast episodes, written and researched by 84 contributors across 80 countries.
More things will break, that is expected. We will fix them.