Building an Academic Journal Platform: Lessons from IJRN
How we built IJRN, an academic journal submission and peer-review platform. Architecture decisions, role permissions, workflow design, and what we would change.
If you are thinking about building an academic journal platform, a peer-review submission system, or any workflow-heavy multi-role application, this is the post we wish we had read before we started the International Journal of Research Nexus build.
IJRN is a live, running academic journal platform. Authors submit manuscripts, editors assign reviewers, reviewers evaluate in blinded rounds, decisions are communicated, accepted papers get published. Every verb there is a workflow with states, permissions, emails, and edge cases. This is what it took to ship that properly.
The problem brief
The founder of IJRN came to us with the pain most journal editors carry silently: email chaos. Manuscripts coming in as attachments. Reviewer assignments tracked in a spreadsheet. Anonymity maintained by manually renaming files. Decision letters copy-pasted from old ones. Every step leaking information, taking weeks, and burning the editor's evenings.
The brief was simple to state and hard to build: a single platform where the whole lifecycle lives, with real role separation, real audit trails, and no manual file-renaming.
Roles and permission boundaries (this is where most systems fail)
Four roles: author, reviewer, editor, admin. Sounds simple. The hard part is what each can see, not what each can do.
- Author can see their own submissions, their own decision letters, and comments intended for them. They cannot see reviewer identities, other reviewers' comments on their paper, or anything about other submissions.
- Reviewer can see only the manuscripts assigned to them, with author identity stripped. They cannot see other reviewers on the same paper, nor the editor's private notes.
- Editor can see everything in their section — manuscripts, reviewer identities, full comments, internal notes — but only for their assigned section.
- Admin can see everything but should rarely need to; most admin actions are audit-logged.
We enforced this at three layers. Database queries filtered by role at the query layer — a reviewer query for "my manuscripts" literally cannot return other reviewers' data because the query is narrowed before it runs. API routes re-checked the role on every call. Frontend hid UI that a role should not see, but we treated that as cosmetic — the real guarantees live at the data layer.
The lesson: do not trust your frontend to enforce permissions. If a reviewer opens the browser dev tools and changes a form value, the backend must refuse. This sounds obvious; most systems we have audited fail it.
The manuscript state machine
A manuscript moves through a finite set of states, and every transition is a moment that matters.
- Submitted → editor assigns reviewers → Under Review
- Under Review → all reviews in → Decision Pending
- Decision Pending → editor decides → Accepted, Rejected, or Revisions Requested
- Revisions Requested → author resubmits → Under Review (next round)
- Accepted → production → Published
Each transition triggers specific emails to specific roles. Each transition locks or unlocks specific actions. A reviewer cannot submit a review on a manuscript no longer under review. An author cannot resubmit a manuscript in "Under Review" state.
We modelled this as an explicit state machine in the database, not as scattered boolean flags. Every manuscript row has a "status" enum and a "transitions" history log. That design made it trivial to answer questions like "how long is the median time from submission to first decision?" — a question the editor asked us two weeks after launch that we had accidentally made easy. If the system had used scattered booleans, that report would have taken a week to build.
Our post on scoping a SaaS MVP goes deeper into why writing down the state machine before writing code is worth two weeks of engineering time.
Access control for blinded peer review
Double-blind peer review means reviewers do not see author identities and authors do not see reviewer identities. That sounds like a display problem. It is actually a data problem.
When a reviewer downloads the manuscript PDF, it must not contain author metadata in the file properties. When an author reads review comments, the reviewer's name cannot appear in any API response. When an editor views the whole submission, both sides are visible — but if that editor accidentally exports data, the export respects the role of whoever requested it.
We handled this with a serialization layer that takes the raw database record and strips fields based on the requester's role before returning anything over the API. The same record returns different JSON depending on who asks. That layer is about 200 lines of code and it is the most important 200 lines in the product.
Notifications without the noise
Journals live and die by email communication. Too few emails and people miss deadlines. Too many and reviewers mute the inbox.
We landed on three rules:
- Every state transition emits at most one email per affected party. A "revisions requested" decision sends one email to the author. Not three. Not a summary plus a detail. One.
- Digest instead of instant for non-critical events. New reviewer invitations go out immediately. Reviewer comments accumulated during an active review go out as a weekly digest.
- Every email deep-links into the platform. No "log in to see more." The reviewer gets a one-click link straight to the review form. Reduces friction massively.
Indexing, DOIs, and the "publication" step
Academic journals need to be findable. That means DOI registration (via Crossref or DataCite), Google Scholar indexing, and clean metadata on published article pages.
For v1 we deliberately did not automate DOI registration — it requires a Crossref membership and handshake logic that was not worth building until the journal had steady throughput. Instead we set up the system so that the editor could paste a DOI into the admin once registered elsewhere, and the platform handled everything downstream — article page metadata, citation export (BibTeX, RIS), structured data for Google Scholar.
The article pages are server-rendered with clean URLs and schema.org "ScholarlyArticle" structured data. That was enough to get Scholar indexing within a few weeks of going live.
Phase 2, now on the roadmap, will automate Crossref DOI registration at the "accepted" state transition. That is a three-week build we deferred deliberately to keep v1 to 12 weeks. Scope discipline matters — we wrote about why that kind of trade-off is worth it.
What we would do differently
Two things.
First, we would have built the reviewer reminder logic earlier. Late reviews are the single biggest friction in journal publishing. We shipped v1 with manual reminders (editor clicks a button). Automated escalation — reminder at 7 days, second at 14, editor flag at 21 — would have been worth the extra week.
Second, we would have invested more in the reviewer onboarding. Reviewers show up once a month, not every day. Each time they log in, they have forgotten how the form works. A short "what you need to do" panel on every review page would have saved support emails.
Neither is fatal. Both are in the phase 2 queue.
Stack choices, briefly
For IJRN specifically we used TypeScript across the stack with Next.js for the frontend, a PostgreSQL database, and Prisma as the ORM. File storage was on S3 with signed URLs so manuscript PDFs were never served publicly. Email went through a transactional provider with webhooks to track delivery.
We are stack-agnostic as a team — we have shipped in Python, Node.js, and React Native depending on the project. For IJRN, TypeScript end-to-end was the right call because the data model was complex enough that having one shared type system between frontend and backend eliminated a whole class of bugs. On a different project with heavy data processing, we would have reached for Python on the backend.
What this costs to build
An academic journal platform with real peer-review workflows, role-based permissions, and notification logic is in the 10-18 lakh INR range for a solid v1, running 10-14 weeks. That is consistent with what we see for workflow-heavy SaaS products generally.
If you are running a journal manually today, or about to launch one, we would be happy to walk through what your scope would look like. We have built exactly this before — you can see IJRN live at ijrnexus.com and the other work on our projects page — and we can tell you in one call whether a custom build is the right answer for you or whether an open-source option like OJS will hold you over.
Keep reading
Automation Dashboards vs Zapier vs Retool: When to Build Your Own (2026)
Honest comparison of custom automation dashboards vs Zapier and Retool. Cost crossover, lock-in tax, and the workflows where building beats subscribing.
ReadProductized Service vs SaaS vs Custom Build: How Founders Should Choose in 2026
Honest 2026 guide to choosing between a productized service, a SaaS subscription, or a fully custom build. Cost, speed, ownership, and the failure modes of each.
Read