banner
BGIcon

Overview

Ibis is a premium alternative to Overleaf: what a LaTeX editor would look like if it were rebuilt today. It is named for Thoth's bird, the Egyptian god of writing, and it is meant to be a writing instrument. It covers the whole path from a blank template to a submitted paper: a three-panel editor, real compilation in a sandbox, a PDF viewer linked to the source, citations, live collaboration, review and history.

The project was planned as eight phases, and every phase ended with lint, typecheck, tests and a production build all green. The final phases added the parts a team or institution needs: accounts, single sign-on, roles and audit logging, encrypted secrets, a private package registry, signed webhooks, a public API, a command-line client and an installable PWA.

Technologies

  • - Next.js 16 / React 19
  • - TypeScript
  • - Tailwind CSS 4
  • - Prisma 7 + SQLite (Postgres-portable)
  • - CodeMirror 6
  • - Yjs (CRDT)
  • - pdf.js
  • - TeX Live in Docker
Editor with file tree, LaTeX source, compiled PDF and build problems
Projects with last build, versions and collaborators
Research library: references shared across projects
Template gallery
BG
Icon
  • Year

    2026

  • Type

    Full-Stack Web Application

  • Role

    Solo Developer

Highlights

Feature complete across all eight planned phases, with 542 tests and lint, typecheck and production build green.

Built real-time multiplayer editing on a Yjs CRDT with server-enforced roles, presence, comment threads, tracked changes and revision history with diffs.

Built a compile pipeline that picks Docker TeX Live, then local TeX, then a clearly labelled fallback previewer, with a log parser and bidirectional SyncTeX.

Shipped 26 real LaTeX templates, six citation styles, DOI, arXiv, ISBN and ORCID lookup, and eight venue check profiles.

BG
Icon
  • Phases

    8 of 8 complete

  • Data Model

    25 Prisma models

Technical Implementation

Workspace: A three-panel editor on CodeMirror 6 with project-wide autocomplete, a custom minimap, vim and emacs modes and crash recovery. A structural LaTeX reader understands sections, labels and citations, which drives the document map, word counts per section and cross-reference checks.

Compilation: Builds run in a TeX Live container with no network. A log parser turns compiler output into readable errors, and the pdf.js viewer supports SyncTeX in both directions plus a selectable text layer. The seeded thesis builds to 16 pages in roughly four seconds in Docker.

Citations: A BibTeX parser with RIS import, duplicate detection, six citation styles, identifier lookup, and an analysis of which references are used, unused or missing.

Paper mode: Reads a project as a submission. Front matter is read and edited in place wherever it lives, checks catch missing citations, broken references, duplicate labels and page limits, and the server builds four archives: submission, arXiv, camera-ready and anonymous. A résumé builder and visual equation, table and figure builders produce plain LaTeX the author can keep editing.

Accounts and access: scrypt-hashed passwords, database-backed sessions where the cookie holds a signed token and the database stores only its SHA-256, throttled sign-in, OIDC single sign-on with PKCE, and two role ladders (project and organisation) with every privileged action written to an audit log.

Platform: Project secrets encrypted with AES-256-GCM, a private registry for organisation .sty, .cls and .bst files, webhooks signed over timestamp and body to block replay, a scoped public API with cursor paging and rate-limit headers, and a dependency-free CLI built entirely on that API (login, clone, push, compile, watch).

BG
Icon
  • Principle

    A writing instrument

  • Verification

    Tested against real systems

Design Decisions & Challenges

The hardest bug was in collaboration: files opened mid-session appeared blank and looked like they had been wiped. The CodeMirror binding only applies changes to shared text, never the text already there, so creating the editor empty against a synced document left it empty for good. The fix was to create the view from the shared document itself, verified by a second client's edit showing up live in the browser.

Secrets reach a build only when shell escape is on. Without it, a document cannot run a program and so cannot read an environment variable, which makes exposing secrets pointless. Private packages ship only the newest version of each name, because TeX has no import versioning.

On Windows, where the Docker engine would not start, compilation runs through a local TeX driver. A TeX install that ships latexmk but no Perl reports itself as available and then fails every build, so the driver needs a working Perl as well, and the package cache has to be warmed before a first large build.

Known gaps are stated openly: rate limiting is per process, there is no password reset because no mail transport is configured, and webhook retries live in process timers, so a deploy during a retry window leaves the delivery pending rather than claiming success. SAML is reported as unconfigured instead of quietly falling back to passwords.