Skip to content

odf-kit — JavaScript/TypeScript library for ODT export from Lexical editor state #488

@GitHubNewbie0

Description

@GitHubNewbie0

Please complete the following checklist (by adding [x]):

  • [X ] I have searched open and closed issues for duplicates
  • This isn't a feature request
  • [X ] This is not a report about my app not working as expected

Context: The Proton community has been requesting ODT support across several UserVoice threads (1, 2, 3). A Proton team member noted in one thread that "there are no libraries whatsoever for ODT processing for browsers." This is no longer accurate.
odf-kit is a pure TypeScript library (Apache 2.0, ESM, zero dependencies beyond fflate) that generates, reads, and converts ODT files entirely client-side — no LibreOffice, no server required. It passes the OASIS ODF validator on every release.
As of v0.12.0 it includes lexicalToOdt() — a function that converts a Lexical SerializedEditorState directly to a valid .odt file. It handles the node types registered in AllNodes.ts: paragraphs, headings, blockquotes, code blocks, lists (including CustomListNode), tables, links, images, horizontal rules, and inline formatting.
The integration point in this codebase is well-defined:
New file: applications/docs-editor/src/app/Conversion/Exporter/EditorOdtExporter.ts
typescriptimport { lexicalToOdt } from 'odf-kit/lexical'
import { EditorExporter } from './EditorExporter'

export class EditorOdtExporter extends EditorExporter {
async export(): Promise<Uint8Array> {
return lexicalToOdt(this.editor.getEditorState().toJSON(), {
pageFormat: 'A4',
fetchImage: async (src) => {
const b64 = await this.callbacks.fetchExternalImageAsBase64(src)
if (!b64) return undefined
const binary = atob(b64.split(',')[1] ?? b64)
return Uint8Array.from(binary, c => c.charCodeAt(0))
},
})
}
}
Edit: ExportDataFromEditorState.ts — add one case:
typescriptcase 'odt':
return new EditorOdtExporter(editorState, callbacks).export()
Edit: DataTypesThatDocumentCanBeExportedAs in @proton/docs-shared — add 'odt' to the union type.
Posting here in case it's useful. Happy to answer any questions about the library.


Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions