· case-study · 4 min read

Building a Web Novel Platform from Scratch — One Codebase, Three Audiences

Authors write, readers read, admins watch the dashboards. Three different user types, three different screens — and one full-stack codebase that has to keep all of them happy.

Building a Web Novel Platform from Scratch — One Codebase, Three Audiences

In one sentence

Authors write, readers read, admins watch the dashboards. We built a web novel platform with three distinct user roles end-to-end — planning, design, backend, infrastructure, all from one team.

No 3D, no AI on this one. Just "a normal web platform." Which, as you'll see, is sometimes the hardest kind to make.

Three users, three screens

The first decision in any platform build is who uses it. This project had three from day one:

  • Authors — write novels, publish episodes, manage their works
  • Readers — read public works without an account; bookmark with one
  • Admins — manage all users and novels, watch dashboards for platform health

These three each get different pages, different permissions, different UX — so we were essentially building three apps inside one codebase.

"Novel > Episode" as a data structure

Web novels aren't just blog posts. A novel can hold dozens or hundreds of episodes, each at a different publish state, some free, some paid. We modeled it like this:

User ──────────────┐
                   │
Novel              │
 ├─ id             │
 ├─ authorId ──────┘
 ├─ title
 ├─ genre
 ├─ status (draft/public/private)
 └─ Episodes []
      ├─ id
      ├─ order
      ├─ title
      ├─ content (rich text)
      ├─ status (draft/published)
      └─ publishedAt

The order field is where the trouble lives. Authors reshuffle episodes — "I want to insert a new episode 5 in the middle." Handle that and you can't make order a plain integer.

Renumbering every episode every time someone inserts one will kill the database. The trick: insert the new episode at order 4.5, and only normalize back to integers in a periodic batch when fractions get messy. This is the standard approach.

"Read without an account" rewrote our caching strategy

A core decision early on was that public episodes should be readable without login. That single line completely changed our backend caching.

  • Public episodes are cached at the CDN. Logged-in or not, same cache hit
  • Episode content body never embeds dynamic data like "like count" → fetched separately by a small API
  • Cache invalidates only when an author edits or publishes — invalidate the single episode URL

The result: >90% of traffic served from the CDN. The server only handles author edits and reader interactions like likes/comments.

Admin dashboard split into its own app

Initially we planned to keep the admin screens as routes inside the main React app. We changed our minds quickly:

  • The heavier the admin gets, the heavier the bundle every reader downloads
  • Permission separation is weaker than code separation. One slip and you've leaked access
  • Admin UX is dashboard-heavy — uses a different set of libraries (charts, tables)

So admin lives as a separate React app on a separate domain, sharing the backend. That single decision dropped the public bundle by 30%+.

"Edit" and "publish" must be different operations

The most-requested feature from authors was unexpected:

"My in-progress edits should never accidentally go live."

We started with content = a single text blob per episode. That meant readers were watching whatever the author was typing in real time. So we split each episode into two content slots:

Episode
 ├─ draftContent
 ├─ publishedContent
 ├─ status
 └─ publishAt (scheduled publish)

Authors always edit draftContent. Hitting "Publish" copies it into publishedContent. A small change, but author confidence jumped immediately.

Responsive design when the user is 90% mobile

Web novels are read >90% on mobile. That assumption changes everything.

  • Body text 16–18 px by default — looks small in mockups, perfect on phones
  • Line height 1.7–1.8 — comfortable for an hour of reading
  • Dark mode as the default — overwhelming majority of reading happens at night
  • Swipe gestures for episode navigation — buttons are secondary

Compound those small details and session time differs by 30%+. We initially classified these as "polish details." After beta testing, we reclassified them as "core features."

What we walked away with

"Normal web platforms" are the hardest

When you don't have a flashy 3D layer or AI to hide behind, every evaluation lands on speed, stability, and small UX details. Nowhere to hide. These are the projects that actually expose engineering quality.

Caching strategy matters as much as data modeling

"Public content on CDN, dynamic data via separate API" — that one rule cuts infra costs roughly 5×. Bake it into the model from day one and you'll thank yourself later.

Separate the admin app

Don't keep it in the same React app. Permissions, bundle size, library divergence — all three argue for separation.

Things people ask

How long does a similar content platform take? Three roles, standard scope: 12–16 weeks. Add subscriptions/payments and it's +4 weeks.

How did you implement the author editor? ProseMirror-based rich text. Auto-save every 2 seconds, inline image upload, automatic cross-linking between episodes. The priority was never breaking the writer's flow.

How far does this scale? A million users and a million episodes is fine on PostgreSQL with proper indexes. Beyond that we typically split episode bodies into a separate object store.

What does the admin dashboard look like? Around 15 KPI cards (daily signups, active authors, popular genres, per-episode traffic) plus time-series charts. Every metric is precomputed nightly so the dashboard responds instantly.


If you're starting a content platform — web novels, courses, newsletters, blogs — get in touch with the user roles and target scale. The first call usually maps out the data model and caching strategy with you.

Hammergrid Lab is a creative engineering studio building React/Node.js full-stack platforms alongside 3D and AI tools.

Related services

3D web, 3dweb, 3D configurator, 3D product configurator, 3D product viewer, WebGPU, Three.js

한국어 버전: 작가·구독자·관리자를 위한 웹소설 플랫폼 풀스택 개발 사례

← Back to insights

Start a project