Univer puts a spreadsheet, document editor and slides in your app

1 month ago

A real spreadsheet, running inside somebody else's web app. This one is built with Univer, an open source kit you drop into your own product. The same kit also draws documents and slide decks.

Ask about this presentation

Chapters

  1. 0:00Univer · an open source office kit you build into your own app
  2. 0:11A workbook, a document and a slide deck are the same kind of object
  3. 0:33Three answers, and a correction to the pitch
  4. 0:51Three hard problems sit under every grid on a web page
  5. 1:12One door in, and three lines that say which class handles which type
  6. 1:45One runtime under all three, and only one of them is free
  7. 2:04All six types run. One of them is built on the free packages.
  8. 2:43Two kinds of change, and only one crosses into your file
  9. 3:27Four fields carry a batch of saved changes
  10. 4:10A slide takes a different route to the same engine
  11. 4:37Twenty packages ship twice, once without a screen
  12. 5:05The free licence buys the engines. The multiplayer layer is the paid product.
  13. 5:32Open does not mean equally finished
  14. 6:01The hard half is the free half
  15. 6:23Google Sheets can do this today, on Google’s servers
  16. 6:54Where Univer sits among the embeddable spreadsheets
  17. 7:18Sixteen lines to a workbook, or sixty-one
  18. 7:40Who should install Univer this weekend
  19. 8:04Apache-2.0, TypeScript, browser and server
  20. 8:38What is the last app you used that quietly turned into a spreadsheet?
Show transcript
  1. A real spreadsheet, running inside somebody else's web app. This one is built with Univer, an open source kit you drop into your own product. The same kit also draws documents and slide decks.

    Slide text
    the project’s own showcase

    Univer

    The open source office kit: sheets, docs and slides in one runtime you build into your own app
    TypeScript Apache-2.0, free to ship commercially browser and server
    spreadsheet document slide deck
  2. Univer comes from a team called dream-num, and you build it into your own product. Here is the spreadsheet it gives you, running in a browser tab, looking up prices against a product table. Your users get a real spreadsheet, a real document editor and a real slide editor, all three inside your app. And underneath all three sits one kind of object, with a saved state and a number that says which version of the file you are holding.

    Slide text

    One codebase, and a workbook, a document and a slide deck are the same kind of object in it

    The Univer spreadsheet showcase, formula bar and product lookup grid
    the project’s own showcase
    spreadsheet document editor slide editor
    one saved state
    one revision number
    under all three
  3. By the end you'll know what a workbook and a slide deck have in common inside this codebase, and which edits are allowed to touch your saved file. And I'll show you where the free licence actually stops, because the pitch needs a correction. Six document types run in the project's showcase, and one of them runs entirely on the free packages.

    Slide text
    The Univer spreadsheet showcase, dimmed behind the slide copy
    1
    What a workbook and a slide deck share in this codebase
    2
    Which edits reach your saved file, and which never do
    3
    Where the free licence stops
  4. Putting a grid on a web page is a solved problem. Three things after that are hard. Two people typing in one cell without clobbering each other. An undo that knows exactly what to undo. And a formula that still calculates when there is no browser anywhere, on a server. Univer's answer is to solve those three once, underneath, and let the spreadsheet, the document editor and the slide editor all inherit the answer.

    Slide text
    Two people typing in one cell
    An undo that knows what to undo
    A formula that calculates with no browser in sight
    Solve all three once, underneath, and every editor inherits the answer
  5. The door in is eight lines of real code. You ask the runtime to create a unit, and you hand it a type and some data. A unit is one open thing with an id and a saved state, whether that thing is a workbook, a document or a slide deck. Three lines say which class handles which type. Sheet gets Workbook. Document gets DocumentDataModel. Slide gets SlideDataModel. All three extend one base class, and that base class is where the saved state and the revision number live. A revision number is a counter that lets two copies of one file work out which copy is behind. So a workbook and a slide deck differ by one value in a list of type names.

    Slide text
    the whole registry, shortened for the slide
    createUnit(type, data)
    registerCtorForType(UNIVER_SHEET, Workbook) registerCtorForType(UNIVER_SHEET, Workbook)
    registerCtorForType(UNIVER_DOC, DocumentDataModel) registerCtorForType(UNIVER_DOC, DocumentDataModel)
    registerCtorForType(UNIVER_SLIDE, SlideDataModel) registerCtorForType(UNIVER_SLIDE, SlideDataModel)
    core · univer.ts on the project’s dev branch
    every unit carries a saved state
    every unit carries a revision number
    one base class under all three
  6. The project runs all of this in a public showcase, and I opened three of them. The spreadsheet runs on the open packages. The document editor is open too, and its tables and its charts come from the paid plugins. The slide editor is the paid slide package, watermark and all. Three separate editors, one runtime underneath every one of them.

    Slide text
    The Univer spreadsheet showcase with a product lookup grid
    open packages
    The Univer document editor showcase with a decision register table
    open editor, paid tables and charts
    The Univer slide editor showcase, watermarked Univer Office with a License Required line
    paid slide packages
    the project’s own showcase
  7. The repo describes six document types in one runtime. Spreadsheets, documents, slides, boards, relational tables and PDFs. Go to the showcase and all six of them run, across five hundred and forty-seven demos. Then I opened what each demo actually loads. The spreadsheet pulls in three packages, and all three are free and Apache licensed. The slide deck, the PDF, the board and the relational table each pull in packages with pro in the name, and the slide demo is stamped, License Required. The open core registers three document types, and the project's own front page still lists PDFs as coming soon. Six types in the product, one type fully inside the free licence.

    Slide text
    spreadsheets
    open packages
    documents
    open, paid tables and charts
    slides
    packages with pro in the name
    PDFs
    packages with pro in the name
    boards
    packages with pro in the name
    relational tables
    packages with pro in the name
    from the project’s own showcase
    547 demos, all six types
    core · presets · preset-sheets-core
    three types registered in the open core
    PDFs still listed as coming soon
    slides
    PDFs
    boards
    relational tables
  8. Every change in Univer carries a label, and that label decides whether the change reaches your saved file. A saved change goes into the file. The repo's own comment calls a saved change the smallest unit of conflict resolution, and what that means is the smallest piece the software will argue about when two people edit one cell at once. A screen change never enters the file. Where you scrolled to, whether the sidebar is open. Those are real changes to what you see, and the saved file never hears about them. And one action can make several saved changes. Delete a row, and that single action produces the saved change for the delete, the saved change that puts the row back for undo, and the saved change for the cell contents. I made three edits with no screen attached at all, and got three commands, seventeen saved changes, and zero screen changes.

    Slide text
    a command
    a saved change
    a screen change
    what you asked the app to do
    goes into your saved file
    never enters your saved file
    your saved file ends here
    “the smallest unit of conflict resolution”
    the repo’s own comment
    scroll position sidebar open
    delete the row
    delete the row
    put the row back, for undo
    set the cell contents
    3 commands · 17 saved changes · 0 screen changes
    our run, no screen attached
  9. A saved change carries only plain data, small enough to write down and send. The free code already does exactly that. One line forwards saved changes to a background worker, and only saved changes. The format it sends is in the repo too. A unit id, the revision it started from, the revision it produces, and a list of saved changes whose contents are written out as text. So an edit from your keyboard, from a server, or from a piece of software acting for you is the same kind of thing on the wire. The part that hands out revision numbers and merges two people's edits is the collaboration server, and the team sells that one separately. In the free packages the revision counter never moves. Mine stayed at one.

    Slide text
    the wire format, fields elided
    interface IChangeset {
    unitID: string unitID: string
    baseRev: number baseRev: number
    revision: number revision: number
    mutations: IMutation[] mutations: IMutation[]
    } interface IMutation { id: string data: string // serialized params }
    the free packages, sending to a background worker
    if (type === CommandType.MUTATION && ...) { if (type === CommandType.MUTATION && ...) {
    // only sync mutations to the worker thread }
    your keyboard a server software acting for you
    revision numbers and merging two edits
    the paid collaboration server
    in the free packages the counter stayed at 1
    our run
  10. One drawing engine draws every document type. Each open thing gets a scene, and everything inside a scene is the same base object. The spreadsheet and the document editor go further and share one component class, with one draw call between them. A slide is a viewer that holds one scene per page, on that same engine. And I like what that buys you. A document can sit inside a cell, and a spreadsheet can sit inside a document, with no second renderer to negotiate with.

    Slide text
    Engine
    Sceneone per open thing
    BaseObjecteverything drawn in a scene
    RenderComponent
    SceneViewer
    SheetComponent
    DocComponent
    Slideone scene per page
    SheetComponent
    DocComponent
    Slideone scene per page
    one draw call between them
    a document inside a cell
    a spreadsheet inside a document
  11. You can read this project's core rule straight off its folder names. Sixty packages, and forty of them sit in twenty pairs, a logic half and a screen half. The filter is one package and the filter's menu is another. The table of contents, the same. The contributor guide states why. Running with no screen, on a server with no browser, is the same priority as running in the browser. So I ran the logic half on a server runtime with no browser and no page at all, put a sum formula into a cell, and got fifty back.

    Slide text
    logic half
    screen half
    sheets
    sheets-ui
    sheets-filter
    sheets-filter-ui
    docs-toc
    docs-toc-ui
    slides
    slides-ui
    thread-comment
    thread-comment-ui
    … 15 more pairs
    … 15 more pairs
    20 pairs · 40 of 60 packages
    “support of Node.js is at the same priority as browsers”
    the project’s contributor guide
    no browser · no page
    =SUM(A1:A2)*10
    50
    our run
  12. What the free licence gives you is the core, the engines and the plugin set. Real time collaboration, edit history, import and export, printing, charts, pivot tables and calculation on a server are Univer Pro, a separate commercial product you pay for. The team also wrote a boundary rule into its own documentation, saying the open source docs should not imply that paid capabilities are available in the public packages. They drew the line, and then they published it. I have not seen many projects do that.

    Slide text
    In the Apache licence
    core · plugin system
    rendering engine
    formula engine
    themes and adapters
    In Univer Pro
    real time collaboration
    real time collaboration
    edit history
    edit history
    import and export
    import and export
    printing
    printing
    charts and pivot tables
    charts and pivot tables
    calculation on a server
    calculation on a server
    “OSS documentation should not imply that Pro-only capabilities are available in public packages”
    the project’s own README
    and they published that rule themselves
  13. The three open surfaces are at very different stages. Inside the drawing engine, the slides folder holds two source files. The documents folder holds a hundred and fifty-five. The project says the same thing in words. Spreadsheets are its most mature surface today, and the presentation model and its interface packages are under active development. Under the project's own stability policy, that second phrase makes the open slides interface experimental. I would not build a presentation product on this one today.

    Slide text
    documents
    155
    spreadsheets
    22
    slides
    2
    source files in the drawing engine
    “sheets are the most mature product surface today”
    “presentation data model and UI packages under active development”
    the project’s front page
    Under the project’s own stability policy, that makes the open slides interface experimental
  14. Both catches land in the same place if you are the one building. You are getting the part that is genuinely hard to build. The object model, the formula engine, the drawing surface and the edit bus, under a licence that lets you ship all of it in a commercial product. Run several workbooks on one page if you want, and the project's own docs show three at once. What you pay for, when you pay, is the multiplayer layer and the file format compatibility.

    Slide text
    Three Univer workbooks side by side on one page, each with its own toolbar and sheet tabs
    three workbooks on one page, from the project’s docs
    object model formula engine drawing surface edit bus
    multiplayer and file formats, when you pay
  15. Google Sheets already does all of this, and Google publishes a way for your own app to read and write a sheet, which you could wire up this afternoon. That is true, and the difference is where the document lives. With Google Sheets the document lives on Google's servers, inside Google's account system, and your app talks to it across the network. With Univer the document lives in your page and in your own database, and you decide where the edits get routed. I would rather have the document in my own storage. Handsontable and AG Grid hand you the grid. Univer is going after the whole document.

    Slide text
    Google Sheets
    Univer
    on Google’s servers
    on Google’s servers
    in your page and your database
    in your page and your database
    inside Google’s account system
    inside Google’s account system
    inside yours
    inside yours
    edits cross the network to Google
    edits cross the network to Google
    you route the edits
    you route the edits
    Handsontable and AG Grid hand you the grid
  16. Handsontable, paired with HyperFormula, is the embeddable grid with a real formula engine behind it. AG Grid is the enterprise data grid. Grist is an open source relational spreadsheet, and you host it as an app. Univer is the one going after all three document types with one object model. And it is the successor to Luckysheet, from the same team. That repo is archived now, and its description reads, Luckysheet upgraded to Univer.

    Slide text
    Handsontable with HyperFormula
    the embeddable grid with a real formula engine
    AG Grid
    the enterprise data grid
    Grist
    an open source relational spreadsheet you host as an app
    Univer
    sheets, docs and slides on one object model
    Luckysheet, same team, archived
    “Luckysheet upgraded to Univer”
    that repo’s own description
  17. Two ways in, and they are very different lengths. The short path is two packages and one call. Sixteen lines of code, and a workbook appears. The long path, where you pick every piece yourself, is thirteen packages, eleven registration calls and sixty-one lines before an empty workbook shows up. Both paths are in the quick start. I would start short and take the long one the day you actually need it.

    Slide text
    the short path, shortened for the slide
    pnpm add @univerjs/presets @univerjs/preset-sheets-core createUniver({ presets: [UniverSheetsCorePreset()] })
    2 packages · 1 call · 16 lines
    the long path, shortened for the slide
    univer.registerPlugin(UniverRenderEnginePlugin) univer.registerPlugin(UniverFormulaEnginePlugin) univer.registerPlugin(UniverUIPlugin, { container }) … eight more registerPlugin calls
    13 packages · 11 calls · 61 lines
    Both paths are in the quick start
  18. I would reach for Univer if your product needs a real spreadsheet inside it and you want the document in your own storage. And I would start with sheets, not slides. I would wait if you need file import and export, or two cursors in one document on day one, because both of those sit in the paid tier. And I would skip it if what you want is a grid to display rows in. That is a much smaller job than this one, and Handsontable or AG Grid will do it.

    Slide text
    Install now
    your product needs a real spreadsheet in it and you want the document in your own storage
    Wait
    you need file import and export, or two cursors in one document, on day one
    Skip
    you want a grid to display rows in
  19. Apache-2.0, so you can ship it inside a product you sell. It is written in TypeScript, the typed flavour of the language browsers already run. It works in current Chrome, Edge, Firefox and Safari, in Electron, which is the wrapper that turns a web app into a desktop app, and on a server with no browser at all. It is an early build, from a codebase that has been going since 2022, with a 1.0 release candidate out for testing right now and new code landing today. The default install is still the early line, and the release candidate is the one I would watch.

    Slide text
    Licence
    Apache-2.0, free to ship commercially
    Language
    TypeScript
    Browsers
    current Chrome, Edge, Firefox, Safari and Electron
    Server
    Node on a server, no browser needed
    an early build, going since 2022, with a 1.0 release candidate out for testing
  20. What is the last app you used that quietly turned into a spreadsheet? Mine was a project tracker that grew formulas, and then grew a chart. The repo is dream-num slash univer, on GitHub. New repo tomorrow.

    Slide text
    The Univer spreadsheet showcase, dimmed behind the closing question
    What is the last app you used that quietly turned into a spreadsheet?
    dream-num / univer
    github.com/dream-num/univer
    New repo tomorrow

What happened in AI today, in your inbox

One short email each evening. Read it and you’re caught up.

Built with ❤️ in New York