Poiesis
A local Overleaf alternative — a LaTeX editor that runs entirely on your machine, with your own GitHub as the backend and an AI you actually control.
pipx install poiesis && poiesis
poiesis (ποίησις) — "to bring into existence." The act of making thought into form.
Poiesis runs entirely on your machine: a FastAPI backend and a React/Monaco frontend. There is no Poiesis server, no account, and nothing to sign up for. Collaboration goes through your own private GitHub repos, and the AI assistant talks to whichever endpoint you point it at — a hosted gateway on your own key, or a model running on your own hardware with no internet at all.
Status: active alpha. Everything listed under What works today is built and used daily, but APIs and UI still move quickly.
Why not Overleaf?
Overleaf is good software, and this isn't a takedown. But the free tier is where most people actually live, and it is where the gaps are.
| Overleaf free tier | Poiesis | |
|---|---|---|
| Full version history | Paid — free keeps 24 hours | Built in, unlimited |
| Collaborators per project | 1 | As many as the GitHub repo has |
| Track changes | Paid | Team chat now, document comments on the roadmap |
| Git / GitHub integration | Paid | Every project is a git repo |
| Compile timeout | Yes | Your machine, your rules |
| AI that fixes compile errors | Yes — 5 AI uses/day, their model | Your endpoint, your key, or fully local |
| What the AI reads | Your document, on their servers | Three privacy stages, down to scrambled text |
| Works offline | No | Yes |
| Account required | Yes | None |
| Where your files live | Their servers | Your disk |
Checked against Overleaf's published free tier on 2026-08-10 — their plans change, so verify before relying on any row. Poiesis is not affiliated with Overleaf.
"Doesn't Overleaf already fix compile errors?"
Yes. Error Assist explains an error, shows a suggested fix and applies it — genuinely the same loop. The difference is not the feature, it's the terms: on the free tier it draws from an allowance of five AI uses per day across all their AI tools, and it runs on their model, on their servers, over your document.
Poiesis puts that loop on an endpoint you choose. Your own key with no daily cap, or Ollama on localhost where the paper never leaves the building.
"Isn't Overleaf open source?"
Community Edition is, under AGPL, and you can self-host it. It's a real option and worth knowing about.
The difference is what you end up running. CE is a Docker stack with MongoDB and
Redis that you maintain; Poiesis is pipx install poiesis. CE ships no AI
features. And Poiesis has no server to host in the first place — it's a local
app, so "self-hosting" is just running it.
If you want one shared instance for a whole department, run Overleaf CE. If you want an editor on your own laptop that syncs through GitHub, that's this.
What works today
- LaTeX editor (Monaco) with syntax highlighting, a formatting toolbar, and
LaTeX-aware autocompletion —
\cite{completes from your.bibfiles,\ref{from every\label{}in the project,\begin{auto-closes its environment, and file paths complete inside\includegraphics{. - Live PDF preview that recompiles as you type and refreshes in place.
- Inline compile diagnostics — log errors become red squiggles in the editor, and "Fix with AI" sends the error plus surrounding source to the assistant, which edits the file and recompiles until it builds.
- SyncTeX — click the PDF to jump to the source line, and vice versa.
- Swappable compile backend — Tectonic
by default (auto-downloads packages, no multi-GB TeX install), with
latexmk/pdflatexas a fallback. - AI assistant — an in-app chat that reads and edits files in your project. Bring your own endpoint: save as many OpenAI-compatible connections as you like (hosted gateways, a lab server, or Ollama / LM Studio / llama.cpp running locally with no key at all) and switch between them. The model list is read from the endpoint itself, and the assistant is scoped to workspace tools rather than a raw shell.
- Three privacy stages for what the assistant may see, shown in the chat
header so you always know which one is live:
- Open — it reads the whole project.
- Selective — hide any file from its row in the file tree, or a single passage with Ctrl+Shift+H in the editor.
- Structure only — every word in every
.texand.bibis replaced by a meaningless one of the same length and all assets are withheld, so the model can still debug syntax, packages, references and line numbers without reading a sentence. Enforced on file reads, the file listing, the outline, compile logs and the Python tool alike. A model running locally is the only arrangement where nothing leaves your machine at all.
- Data figures the assistant draws itself — point it at the CSV or Excel
file already in your project and it reads the data, plots it with matplotlib,
saves the image into
assets/and includes it in the document. It stays in TikZ for diagrams and small hand-typed plots, and reaches for Python only when the figure is real data. Switch it off under Settings › Permissions and every figure it makes is TikZ. - Version history — commit list per project, per-file diffs, one-click restore. Works on synced projects and on local-only ones.
- Citation picker — searchable
\citeinsert over your.bibfiles; paste a DOI or arXiv link to fetch the BibTeX, append it, and cite it in one step. - arXiv-ready export — comment-stripped sources,
.bblwhen present, styles and graphics only. - Multi-file projects with a file tree and a workspace hub.
Collaboration (GitHub sync)
Poiesis uses GitHub as an invisible backend for collaboration — each project becomes its own private GitHub repo. No Poiesis servers, and every file stays on your machine.
- One-click GitHub sign-in via OAuth Device Flow — click Sign in with GitHub, authorize once, and you're connected forever. No client IDs, secrets, or config (the public client ID is embedded; nothing sensitive ships).
- Share a project to a new private repo and sync automatically in the background (pure-Python git via dulwich — no system
gitrequired). - Invite collaborators with a github.com-style username autocomplete (type a few letters, pick from a live dropdown of GitHub users).
- See your team — collaborator profile pictures appear on each shared project card in the hub.
- Team chat per project — a sidebar chat where collaborators talk and leave comments, stored persistently as comments on a dedicated GitHub Issue in the repo (history syncs to everyone, survives restarts).
- Real-time co-editing (optional) — live cursors and shared editing via Yjs/WebRTC, end-to-end encrypted between repo members.
- Conflict resolution — a visual, per-hunk merge picker (Mine / Theirs / Both) when two people edit the same lines.
Architecture
src/poiesis/
├── web.py # `poiesis` entry point: serve + open a browser or window
├── server.py # stable import surface; re-exports from api/
├── api/
│ ├── app.py # builds the FastAPI app and mounts the frontend
│ ├── routes/ # endpoints by feature: compile, files, projects,
│ │ # history, intel, snippets, sync, engines, ai
│ ├── assistant/ # the AI tool layer: prompt, tools, dispatch, skills
│ ├── workspace.py # the open project and its path-containment rules
│ └── runtime.py # background sync daemon + activity ledger
├── services/
│ ├── chat_service.py # in-app AI assistant (OpenAI-compatible, stdlib urllib)
│ ├── sync_service/ # GitHub-as-backend sync: OAuth device flow, dulwich git,
│ │ # collaborators, team chat (Issue comments), conflicts
│ ├── privacy_service/ # what the assistant may see: redaction, hidden passages
│ ├── python_runner.py # runs one matplotlib script in a sandboxed subprocess
│ ├── compile_service.py # LaTeX compile pipeline
│ ├── synctex_service.py # PDF ↔ source position mapping
│ └── history_service.py # per-project commit list, diffs, restore
├── documents/ # template spec, renderers, new-project scaffolding
├── core/ # compiler backends, document model, paths
├── static/ # built frontend (generated; not in git)
└── ui/ # legacy PySide6 desktop shell (app.py / main_window.py)
frontend/src/
├── App.tsx # editor shell, routing, shared state
├── Chat.tsx # AI assistant panel
├── PdfPreview.tsx # live preview + inline PDF editing
├── FileTree.tsx # project tree, context menus, drag/drop
├── latexIntelligence.ts # completions, compile-log parsing, editor markers
├── index.css # import manifest; the rules live in styles/
├── styles/ # the stylesheet, split by UI area (order matters)
├── chat/ # assistant panel internals: messages, thought trail
├── sync/ # GitHub sign-in, Share & Sync, collaborators
├── settings/ # settings modal: engines, connections, privacy
├── modals/ # shared dialogs (create item, unsaved changes, ...)
├── tikz/ # TikZ figure builder canvas and interactions
├── pdfEdit/ # direct-on-PDF text editing
├── TeamChat.tsx # per-project team chat panel
├── ConflictResolver.tsx # visual per-hunk merge picker
└── realtime.ts # Yjs/WebRTC live co-editing
Design principle: separation of concerns. The frontend talks only to the
FastAPI backend over HTTP. The sync engine never imports the server (it's wired in
via callables), GitHub REST/OAuth calls use only the stdlib, and git mechanics are
hidden behind a small API. A legacy PySide6 desktop shell (poiesis.app) is still
in the tree but the web app is the primary interface.
poiesis.server used to hold all of this in one 4,000-line module. It is now a
thin re-export over poiesis.api and stays put because it is the import string
uvicorn is pointed at — but new code should import from the module that actually
defines the name.
Requirements
- Python 3.10+
- A LaTeX engine — but you don't have to install one yourself. On first run,
if nothing is found, Poiesis offers to fetch its own private copy of
Tectonic (~20 MB), which downloads
LaTeX packages on demand instead of installing several gigabytes up front.
An engine already on your
PATH— Tectonic,latexmkorpdflatexfrom TeX Live or MiKTeX — is used in preference and skips the prompt. - (Optional) For the AI assistant: any OpenAI-compatible endpoint, added in-app. A hosted one needs an API key; a local runtime such as Ollama needs neither a key nor an internet connection.
- Node.js 18+ — only to develop the frontend. Installing Poiesis does not need it; the UI ships prebuilt.
Install
pipx install poiesis
poiesis
That's it — poiesis opens the editor in its own window, not a browser tab.
The UI ships prebuilt inside the package, so Node is not required to run it.
The window is the webview your OS already ships — WebView2 on Windows, WKWebView
on macOS, WebKitGTK on Linux — so Poiesis bundles no second browser engine.
poiesis-app is the same thing with no console behind it, which is what you
want on a shortcut.
poiesis |
native window (falls back to the browser if none is available) |
poiesis --browser |
your web browser instead |
poiesis --no-browser |
serve only, open nothing |
--host, --port |
change where it binds |
pip install poiesis works too; pipx just keeps it out of your global
environment.
Linux: the window needs a GTK binding that pip does not pull in by
default. Install the system packages first (sudo apt install python3-gi gir1.2-webkit2-4.1 on Debian/Ubuntu), then pip install 'pywebview[gtk]'. Skip it if you don't care — without a usable webview,
Poiesis opens your browser instead of failing. macOS and Windows need nothing
extra.
Run from source (development)
git clone https://github.com/tygopoodt/Poiesis
cd Poiesis
python -m venv .venv && .venv\Scripts\activate # macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"
python dev.py # FastAPI backend (:8000) + Vite dev server (:5173)
Then open http://localhost:5173. dev.py runs npm install on first launch.
The backend API docs live at http://127.0.0.1:8000/docs.
To build the frontend into the package the way a release does:
python build_frontend.py && poiesis
A legacy PySide6 desktop shell is still in the tree:
pip install poiesis[desktop], thenpoiesis-desktop. New features land in the web app.
Testing
pytest # backend
cd frontend && npm run build # typecheck + build
CI runs both on every push, then builds a wheel, installs it into a clean environment and checks that it actually serves the app.
Roadmap
- LaTeX-aware spell check (ignoring commands, math and preamble).
- Comments anchored to line ranges in the document.
- Zotero integration in the citation picker.
- A WYSIWYG editing mode.
- Threaded replies / reactions in team chat.
- A guided tour of the keyboard shortcuts on first run.
- Packaged installers (
.exe/.dmg) via GitHub Actions.
Contributing
Issues and pull requests are welcome — the project is early enough that most things are still up for discussion. Good places to start are labelled good first issue.
License
MIT — see LICENSE.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file poiesis-0.1.8.tar.gz.
File metadata
- Download URL: poiesis-0.1.8.tar.gz
- Upload date:
- Size: 2.8 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
adc2aa4028d53bc618497a894a3198cf7e21f992a3c474087b72d580fcd6e20f
|
|
| MD5 |
d5292fb40d2a9100733cbc0a28ad43f3
|
|
| BLAKE2b-256 |
b5d992e4c929911d298bfe68284c80490182a4f520115ca857c408d29288bedf
|
Provenance
The following attestation bundles were made for poiesis-0.1.8.tar.gz:
Publisher:
release.yml on tygopoodt/Poiesis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
poiesis-0.1.8.tar.gz -
Subject digest:
adc2aa4028d53bc618497a894a3198cf7e21f992a3c474087b72d580fcd6e20f - Sigstore transparency entry: 2412599287
- Sigstore integration time:
-
Permalink:
tygopoodt/Poiesis@47807f085079ffa15868148c3b6013335562d750 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/tygopoodt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@47807f085079ffa15868148c3b6013335562d750 -
Trigger Event:
push
-
Statement type:
File details
Details for the file poiesis-0.1.8-py3-none-any.whl.
File metadata
- Download URL: poiesis-0.1.8-py3-none-any.whl
- Upload date:
- Size: 2.8 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
cbf5b764f580debe4862f2988fe5c5a46045f30e6b4e2ff1bf7d769c8b7801ad
|
|
| MD5 |
2da11ec16b690fb41e372e15300ab91c
|
|
| BLAKE2b-256 |
b18d15f4ded4f7b285f9d03a51284ace791594f73ccdd3f8f20d6ba4791b5be7
|
Provenance
The following attestation bundles were made for poiesis-0.1.8-py3-none-any.whl:
Publisher:
release.yml on tygopoodt/Poiesis
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
poiesis-0.1.8-py3-none-any.whl -
Subject digest:
cbf5b764f580debe4862f2988fe5c5a46045f30e6b4e2ff1bf7d769c8b7801ad - Sigstore transparency entry: 2412599394
- Sigstore integration time:
-
Permalink:
tygopoodt/Poiesis@47807f085079ffa15868148c3b6013335562d750 -
Branch / Tag:
refs/tags/v0.1.8 - Owner: https://github.com/tygopoodt
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@47807f085079ffa15868148c3b6013335562d750 -
Trigger Event:
push
-
Statement type: