Table of Contents

Set Up

Please go to https://github.com/overleaf/overleaf. Clone the repository (https://github.com/overleaf/overleaf.git) in your IDE. The focus of this guided learning is mainly on /services/clsi/app/js. We are focusing the discussion on Common LaTeX Service Interface which is the core thing that helps compile LaTeX codes into PDFs in Overleaf.

Introduction.

This is overleaf. It is a LaTeX editor. On the left-side are what the user edits in, it is a code editor where user writes in LaTeX, on the right side, we have the compiled PDF. When user clicks on the button “Recompile”, it will trigger the compilation of PDF. We are going to investigate into what exactly is happening from the user’s click on Recompile all the way to showing the newly compiled PDF to the user and how exactly was this specific feature built. This feature is made possible through something called CLSI which is developed by the Overleaf community.

Screenshot 2026-01-19 at 6.00.27 PM.png

CLSI

Common LaTeX Service Interface is a A web API for compiling LaTeX documents in the cloud. The Common LaTeX Service Interface (CLSI) provides a RESTful interface to traditional LaTeX tools (or, more generally, any command line tool for composing marked-up documents into a display format such as PDF or HTML).

Architecture Overview

sequenceDiagram
    participant W as Web Service / Editor
    participant A as CLSI API (Express)
    participant M as CompileManager
    participant D as Docker Container (TeX Live)

    W->>A: JSON POST (Project data & compile settings)
    A->>M: Dispatch compilation task
    M->>D: Spawn "Sibling" Container
    Note over D: Runs latexmk to generate PDF
    D-->>A: Writes output files (PDF/Logs)
    A-->>W: Returns File Access URLs

A Closer Look

graph TD
    %% Styling
    classDef controller fill:#d4e1f5,stroke:#333,stroke-width:2px,color:#000;
    classDef manager fill:#ffebcd,stroke:#333,stroke-width:2px,color:#000;
    classDef runner fill:#e1f5fe,stroke:#333,stroke-width:2px,color:#000;
    classDef util fill:#f0f0f0,stroke:#999,stroke-width:1px,color:#000;
    
    %% Nodes
    subgraph "API Layer"
        CC[CompileController]:::controller
        RP[RequestParser]:::util
    end
    
    subgraph "Orchestration"
        CM[CompileManager]:::manager
        LM[LockManager]:::util
    end
    
    subgraph "Resource Management"
        RW[ResourceWriter]:::manager
        RSM[ResourceStateManager]:::manager
        UC[UrlCache]:::manager
    end
    
    subgraph "Execution Engine"
        LR[LatexRunner]:::runner
        CR[CommandRunner]:::runner
        DR[DockerRunner]:::runner
        LCR[LocalCommandRunner]:::runner
    end
    
    subgraph "Output & Caching"
        OCM[OutputCacheManager]:::manager
        OFF[OutputFileFinder]:::util
        CCH[CLSICacheHandler]:::manager
        OFO[OutputFileOptimiser]:::util
        CCM[ContentCacheManager]:::manager
    end
    
    subgraph "Helpers"
        DMM[DraftModeManager]:::util
        TM[TikzManager]:::util
        SOP[SynctexOutputParser]:::util
    end
    
    %% Relations
    CC -- parses request via --> RP
    CC -- triggers --> CM
    CM -- acquires lock from --> LM
    CM -- syncs files via --> RW
    CM -- checks draft mode --> DMM
    CM -- checks tikz --> TM
    CM -- executes compile --> LR
    CM -- handles output --> OCM
    CM -- syncs remote cache --> CCH
    RW -- checks state --> RSM
    RW -- caches URLs --> UC
    LR -- runs command via --> CR
    CR -- "if docker enabled" --> DR
    CR -- "if local" --> LCR
    OCM -- finds files --> OFF
    OCM -- optimizes files --> OFO
    OCM -- manages content --> CCM
    CM -- "on sync request" --> SOP

File by File Walkthrough

Core Files:

app.js

CompileController.js

CompileManager.js

ResourceWriter.js

Execution Layer