Typst Editor online

Code

Export

The PDF comes straight from the Typst compiler: the same pages as in the preview, with real text that can be selected and searched, links and the document's title.

My documents

Click a document to open it. They are stored only in this browser - nothing is uploaded. Clearing the browser's site data removes them, so download the ones you want to keep.

AI Assistant

Any AI can write with you - ChatGPT, Claude, Gemini, Copilot.

  1. Click Copy prompt.
  2. Paste it into your AI and say what it should write.
The AI should

The document travels in the link after the “#”, which no server sees. What you paste into your AI is handled by its provider.

Save to your server

The editor can send each saved version to your own server (a webhook), so your work is kept where you want it. Nothing is sent until you enter an address here.

What your server receives

A POST request with JSON (your server must allow CORS from https://typst.giit.ch):

{ "editor": "typst", "event": "save", "id": "…", "name": "Report",
  "content": "#set page(paper: \"a4\") …",
  "assets": { "logo.png": "data:image/png;base64,…" },
  "updated": "2026-01-15T09:30:00.000Z" }
Embed the editor in your website
<iframe src="https://typst.giit.ch/?embed=1" style="width:100%;height:80vh;border:0"></iframe>
<script>
const frame = document.querySelector('iframe');
addEventListener('message', e => {
  if (e.origin !== 'https://typst.giit.ch' || e.source !== frame.contentWindow) return;
  if (e.data.type === 'typsteditor:ready')
    frame.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Report',
      content: '= Report\\n…', assets: {} }, 'https://typst.giit.ch');
  if (e.data.type === 'typsteditor:save') saveOnYourServer(e.data.content, e.data.assets);
});
</script>

Also possible: ?src=<URL of a .typ file> opens a file, &webhook=<URL> saves this document there. The editor can also open in a window of its own (?embed=window), and your page can hand it its own AI prompt and a session key so the AI sends its result to your server (typsteditor:ai, typsteditor:key-request) - see "Use the editor on your own website" below the editor. Details are in llms.txt.

Help

How it works

  1. Write Typst on the left - or start with New and one of the templates. The real Typst compiler runs in your browser and shows the pages as you type.
  2. Click text on the page to edit it right there: a field opens with the cursor where you clicked, and the code's cursor goes to the same place. Enter or a click elsewhere writes the change into the code (one step for Undo), Escape cancels. A click on math, a picture or text made by code jumps to its place in the code instead. The place where the code cursor is gets a frame on the page.
  3. Document on the right sets paper, font, margins and numbering (it edits the #set rules); Insert has ready-made pieces (lists, tables, math, symbols); Pictures holds the pictures and data files of the document; Outline lists the headings.
  4. The compiler's errors and warnings are listed above the code with line, column and hint - click one to go there.
  5. My documents (the folder button at the top left) lists every document kept in this browser.
  6. Export makes a PDF (from the Typst compiler, with real text) and pictures of the pages (PNG, JPG, WebP, SVG). Download .typ saves the code.

Packages from Typst Universe (#import "@preview/…") are not downloaded - nothing is loaded from other servers. Fonts: Libertinus Serif, New Computer Modern, DejaVu Sans Mono and the fonts you add to a document.

Keyboard shortcuts

Ctrl + B / I / U
Bold / italic / underline the selected text
Ctrl + M
Math: $…$ around the selection
Ctrl + /
Comment lines in or out (//)
Ctrl + Enter
Show the cursor's place on the pages
Tab / Shift + Tab
Indent / outdent
Ctrl + Z / Y
Undo / redo
Ctrl + S / E
Save (download .typ, or to your server) / export
Ctrl + O
My documents
Ctrl + P
Print the pages
Ctrl + mouse wheel, Ctrl + + -
Zoom the preview
Page Up / Page Down
Previous / next page (in the preview)

Enter in a list continues it (-, +, 1.); Enter on an empty item ends it. Brackets, $, * and _ go around a selection.

Write Typst online, with the real compiler

The Typst Editor shows your code and the compiled pages side by side. It runs the real Typst compiler in your browser as WebAssembly, so the pages look exactly like they will in the PDF - headings, lists, tables, math, figures, footnotes, references and your own #set and #show rules. A click on any text on the page takes you to its place in the code, and you can edit the text right on the page.

Everything runs in your browser. Documents are not uploaded, there is no sign-up and no advertising.

What the editor can do

Code with highlighting

Markup, code, math, strings and comments in their own colors, line numbers, lists that continue on Enter, and the compiler's errors with line, column and hint.

The real Typst compiler

Typst 0.14 compiled to WebAssembly runs in a worker next to the editor and compiles a moment after each change - typing stays smooth.

Edit on the page

Click text on the page to change it there; the change goes into the code. A click on math or a picture jumps to its place in the code.

Document settings

Paper, margins, columns, font, size, language, justified text, numbered headings and page numbers - the settings edit the #set rules of your code.

Pictures and data files

Add pictures, CSV, JSON, YAML, bibliographies, fonts and other .typ files to a document and use them with image, csv, json or #import.

Export

A PDF from the compiler with real, selectable text, every page as PNG, JPG, WebP or SVG, or the .typ source with its files as ZIP.

How it works

  1. Start - choose a template under "New", open a .typ file or paste Typst code.
  2. Write - type in the code; the pages on the right follow. Use "Insert" for tables, lists and math.
  3. Export - save a PDF, pictures of the pages or the .typ file.

Use the editor on your own website

Any https page (and localhost) can embed the editor with an <iframe> and ?embed=1 - no sign-up, no key. Embedded, the editor hides this text and shows a Save button. There are two ways to get the document in and out.

1. Open a file from a link, save to your server

src= opens a file (your server must allow CORS), webhook= makes "Save" (Ctrl+S) send the document to that address. Add &token=… for an Authorization: Bearer … header and &auto to save after every change.

<iframe src="https://typst.giit.ch/?embed=1&src=https://your-site.com/docs/flyer.typ&webhook=https://your-site.com/save.php"
        allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>

The webhook gets a POST with JSON { editor, event: "save", id, name, content, assets, updated }. A small PHP script that stores it:

<?php
header('Access-Control-Allow-Origin: https://typst.giit.ch');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Methods: POST, OPTIONS');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') exit;
if (($_SERVER['HTTP_AUTHORIZATION'] ?? '') !== 'Bearer SECRET') { http_response_code(403); exit; }
$d = json_decode(file_get_contents('php://input'), true);
$name = preg_replace('/[^\w\- ]/u', '_', $d['name']);
file_put_contents(__DIR__ . "/docs/$name.typ", $d['content']);
echo '{"ok":true}';

2. Your page holds the document (postMessage)

The editor says typsteditor:ready, your page answers with typsteditor:load, the editor reports typsteditor:loaded, typsteditor:change on real edits and typsteditor:save when the user saves. Your page may send typsteditor:get (the current state) or typsteditor:save (press Save). Saving then goes through your own login and session.

<iframe id="ed" src="https://typst.giit.ch/?embed=1" allow="clipboard-write" style="width:100%;height:800px;border:0"></iframe>
<script>
const ed = document.getElementById('ed');
const ORIGIN = 'https://typst.giit.ch';

addEventListener('message', async e => {
  if (e.source !== ed.contentWindow || e.origin !== ORIGIN) return;
  const m = e.data;
  if (m.type === 'typsteditor:ready') {             // the editor is ready: hand it the document
    ed.contentWindow.postMessage({
      type: 'typsteditor:load',
      name: 'Flyer',
      content: await (await fetch('/docs/flyer.typ')).text(),
      assets: { 'logo.png': 'data:image/png;base64,…' }   // optional pictures and data files
    }, ORIGIN);
  }
  if (m.type === 'typsteditor:change') document.title = '● not saved';   // a real edit
  if (m.type === 'typsteditor:save') {              // the user clicked "Save"
    await fetch('/api/save', { method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ name: m.name, content: m.content, assets: m.assets }) });
    document.title = 'Saved';
  }
});

// A save button on your own page: the answer comes as typsteditor:save
function saveNow() { ed.contentWindow.postMessage({ type: 'typsteditor:get' }, ORIGIN); }
</script>

AI Assistant inside your page: it works in the frame too. With allow="clipboard-write" on the iframe, "Copy prompt" uses the clipboard directly (otherwise the editor falls back to the old copy command, or shows the prompt to copy by hand). A link the AI sends cannot reach an editor inside another website, so the editor tells the AI and the user to paste the AI's whole answer into the editor instead - or open the editor in a window of its own.

3. In a window of its own

window.open("https://typst.giit.ch/?embed=window", "typsteditor-17") opens the full editor in its own window and speaks the same messages with window.opener. Links from an AI reach it there. typsteditor:load may also carry context: { host, title, rules } - the AI prompt then says where the document belongs and follows your rules - and hook: { url, token, assets: false }, a webhook for this document only that is never stored. Closing the window with unsaved changes sends typsteditor:closing. typsteditor:pdf asks for the PDF of the page's document and gets it back as a data URI, made by the Typst compiler with real, selectable text.

4. AI through your own server

Hand the editor your own prompt, an address on your site and a key for this editor session. The AI dialog then shows "Connected to" your site, what you tell the AI, and the choice change the current document or make a new one; Copy prompt puts it all together. The AI posts its result with the key to your server, and your page opens it in the editor - a new document opens separately and stays in the user's browser. One key per editor session: it stays valid while the editor is open, and only while it has none the editor asks for it with typsteditor:key-request. The editor never sends the key itself and never stores it; the address must be https on your own host or a subdomain of it.

const key = async () => (await fetch('/api/ai-key.php?doc=17')).json();   // one key per editor session
const k = await key();
ed.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Flyer', content, ai: {
  label: 'My Site', prompt: 'Keep the [[placeholders]]. Write in German.',
  endpoint: 'https://your-site.com/api/ai-result.php', key: k.key } }, ORIGIN);
// remember the id from typsteditor:loaded and ignore change/save/closing with another id
// only while the editor has no key:
if (m.type === 'typsteditor:key-request') { const k = await key(); ed.contentWindow.postMessage({ type: 'typsteditor:ai', key: k.key }, ORIGIN); }
// while the editor is open, tell your server every minute; closing the editor or the page voids the key
setInterval(() => fetch('/api/ai-key.php?alive=' + k.key.slice(0, 8)), 60000);
// your server has a result (polling, SSE …): target is "current" or "new"
ed.contentWindow.postMessage({ type: 'typsteditor:load', name: 'Flyer', content: draft, from: 'ai', target }, ORIGIN);
<?php // api/ai-key.php - the key of this editor session of the logged-in user (your page calls it)
session_start();                                     // check that the user may edit this document
$key = bin2hex(random_bytes(24));
$_SESSION['ai'][hash('sha256', $key)] = ['doc' => (int)$_GET['doc'], 'seen' => time()];  // or in your database; ?alive= sets seen again
echo json_encode(['key' => $key]);

<?php // api/ai-result.php - the AI posts here (no CORS headers: AIs call it from a server)
$key = preg_replace('/^Bearer\s+/', '', $_SERVER['HTTP_AUTHORIZATION'] ?? '');
$row = find_key(hash('sha256', $key));               // your database: not voided, seen in the last 3 minutes
if (!$row) { http_response_code(401); exit('{"ok":false,"error":"key not valid"}'); }
$d = json_decode(file_get_contents('php://input', false, null, 0, 2000000), true);
save_draft($row['doc'], $d['content'], $d['target'] === 'new' ? 'new' : 'current');   // your page shows it with typsteditor:load
echo '{"ok":true}';

Make keys with at least 128 random bits, store only their hash, bind each to the logged-in user, the document and this editor session, make one per session, keep it valid only while your page reports the session as open, and void it when the editor or the page closes.

The whole protocol is in llms.txt - give it to an AI and it builds the connection for your system. The LaTeX Editor works the same way with the prefix latexeditor: - latex.giit.ch.

Frequently asked questions

Is my document uploaded?

No. The editor and the Typst compiler run entirely in your browser. Your documents, pictures and files are never sent to a server, unless you set up a webhook to your own server yourself.

Is this the real Typst compiler?

Yes. The editor runs Typst 0.14 compiled to WebAssembly (typst.ts), so the pages and the PDF are the same as with the Typst command line. It is loaded once (about 11 MB) and then kept by your browser.

How do I get a PDF?

Click "Export", choose PDF and click "Download". The PDF comes straight from the Typst compiler, with real text that can be selected and searched.

Can I use packages from Typst Universe?

Not directly: the editor loads nothing from other servers, so #import "@preview/…" reports a problem that names the package. You can add the .typ files of a package to the document in the Pictures tab and import them by file name.

Which fonts are there?

The fonts Typst ships: Libertinus Serif (the default), New Computer Modern and its math font, and DejaVu Sans Mono for code. Add your own .otf or .ttf files to a document and use them with #set text(font: "Name").

How do I add pictures?

Drag or paste a picture into the editor, or add it in the Pictures tab on the right. It is stored with the document in your browser and used by #image("name.png"). CSV, JSON, YAML and .bib files work the same way.

Can an AI write in the Typst Editor?

Yes, any AI - ChatGPT, Claude, Gemini, Copilot or the AI in your coding tool. Click "AI Assistant", then "Copy prompt", paste it into your AI and say what it should write. The AI answers with a link; click it and the document appears in your editor. "Undo" takes every change back.

Can I use the editor on my own website?

Yes. Embed it with an iframe and exchange documents with postMessage, or let it send every saved version to your server with a webhook. See Use the editor on your own website for examples.

Does the Typst Editor cost anything?

No. The editor is free, without ads and without sign-up.