LaWrite
A template-driven WYSIWYG academic paper editor — write content, the template guarantees the layout, export a .zip ready to submit.
- Type
- Web
- Role
- Solo
- Status
- Active
- Tech
- Next.js 16 Lexical React 19 TypeScript Tailwind v4 Radix UI KaTeX Framer Motion JSZip next-intl Playwright
- Started
- Feb 2026
LaWrite is a template-first academic paper editor built on Next.js
and Lexical. You pick a preset template (APA 7th, IEEE, etc.),
focus on writing content, and export a .zip whose LaTeX source
matches the template’s layout exactly.
Core idea: you only write the content. The template guarantees the typesetting. Export and submit.
User flow
Landing → Templates → Editor → Export .zip (ready to submit)
↑ |
└── Dashboard ←───────┘
(manage existing docs, create new)
1. Pick a template (/{locale}/templates) — load the preset
from public/templates/{id}/starter.zip, auto-create a project,
land in the editor.
2. Edit (/app/editor/[projectId]) — visual structure + content
editing (headings, paragraphs, tables, images, math). The editor
doesn’t try to preview exact print layout; it guarantees structural
completeness. 2-second debounced autosave to IndexedDB.
3. Export — produce a .zip containing .tex + images. The
exported LaTeX follows the chosen template’s preamble, document
class, and hooks exactly. 100% semantic integrity.
4. Dashboard (/app/dashboard) — grid/list of projects,
continue editing, create new from template, search, delete.
Preset templates
| Template | Document class | Font | Margins | Status |
|---|---|---|---|---|
| APA 7th Edition | apa7 | 12pt | 1in | Enabled |
| General Article | article | 11pt | 1in | In progress |
| CTex 中文排版 | ctexart | 12pt | 25mm | In progress |
Each template ships with its own preamble, metadata field
definitions (which drive the title-page form), export hooks, a
LaTeX↔Lexical conversion rule set, and a starter .zip.
Extensibility: register a new template without writing components
TitlePage and Abstract are generic components driven by metadata definitions. Adding a new template is three steps, zero React work:
- Create a
TemplateDefinitionobject undersrc/templates/definitions/(preamble, metadata fields, export hooks). - Register it in
src/lib/registerTemplates.ts. - Drop a
starter.zipinpublic/templates/{id}/.
That’s it. The fields you declare on metadata.fields appear in
the title-page form automatically (inputType: 'textarea' renders a
multi-line field). The preamble, packages, and \maketitle /
\printbibliography hooks drive the exported LaTeX.
Stack
- Framework: Next.js 16.1.6 with Turbopack
- Editor core: Lexical 0.39.0
- UI: React 19, Tailwind v4, Radix UI
- Math: KaTeX 0.16.28
- Motion: Framer Motion 12
- File: JSZip 3.10.1
- i18n: next-intl 4.8.1
- E2E tests: Playwright 1.58.1
Notable bits
- Schema-driven title page — no per-template React components.
The
metadata.fieldsarray describes the form, and one generic component renders it. Adding IEEE, NeurIPS, ACM SIG is a config-only change. - Semantic-first editing, not visual-first — the editor focuses on correct document structure. Layout is deferred to the template’s LaTeX preamble at export time. This is the opposite of Overleaf’s live-preview approach, and it’s the right tradeoff: you can’t accidentally break a publisher’s mandated spacing rules.
- Offline-first — IndexedDB autosave every 2 seconds means you can write on a plane and the export still works when you land.