Show HN: Extend UI – open-source UI kit for modern document apps
Posted by kbyatnal 6 days ago
We're open-sourcing 14 components & examples today for PDF, DOCX, and XLSX viewers, plus bounding box citations, file upload, e-signature, and more. It's MIT licensed and fully customizable.
Demo video here: https://share.extend.ai/kRmSGKRF
When we started, we tried every file viewer and document component library we could find. Unfortunately, none of them had all the functionality (and polish) that we wanted, so we ended up building our own for https://extend.ai/. It was only ever meant to be internal, but enough customers kept asking for it that we decided to open source it.
It's useful for building document processing agents, real-time user facing document intake flows, or all kinds of internal tooling.
We naively thought this would be a solved problem. Turns out, making PDF/XLSX/DOCX viewers that work at scale is not trivial...we use and maintain it for Extend ourselves, so we've fixed a lot of edge cases that came up while running millions of pages / day through our own system. Our hope is that with our resources + community support, it'll keep getting better over time.
Comments
Comment by lionkor 6 days ago
- no caching for file previews
- no sorting by date in the file picker
- no sorting by size in the file picker
- no sorting by file type in the file picker
- no search in the file picker
- cant enter a folder in the detail view (only expand) in the file picker
- cant go to page (by page number) in the document viewer
- after clicking a button in the document viewer, focus is lost on the document and arrow keys, space, pgup/pgdown dont work until the document is clicked again
- cant select text in the document viewer, unless I search first, in which case it then works
This is after looking at the file picker and document viewer less than 3 minutes(!!!). I gave up after that. Getting 80% of a file picker is easy, getting the last 20% done, so that it's on par with existing software, is not.
Very very odd to have things look this polished, yet be this terrible functionality- and performance-wise. These are not random quirky new ideas I'm having, these have been basics that work in every single file picker and document viewer since the early days of UI, before the web.
Comment by gobdovan 6 days ago
What's more, even if state management should technically be easier with the amount of state libraries, you'll realise sooner or later that the established ones are cleverly immutable where you really just want them to be performant.
I am not saying that it's React at fault for the symptoms you see here, but I would expect any such library made in it to hit exactly these kind of edge cases.
Comment by rrr_oh_man 6 days ago
Can you elaborate on that? What else would you recommend?
Comment by gobdovan 5 days ago
For framework, React wants to own and mediate the DOM via virtual tree, which is a major bottleneck when you need direct control over focus/selection/keyboard routing or hardware accelerated canvases. Instead, look at Svelte or Solid.js, as they integrate nicely with imperative DOM-oriented JS libraries and don't require heavy wrappers or indirect references for the 'unfriendlier' DOM nodes like canvases, scroll containers and so on.
If you're building an OS-like UI, you should also care about state and be sure you have direct control over where your data lives. For example, I usually build with Solid.js and a mix of custom object and lifetime code plus Solid stores for reactive surface state.
I usually end up managing object lifetimes because I end up needing to handle messy edge cases around reference vs value semantics and state merging (e.g. keep cursor position sane after a file sync or track focus across multiple windows, especially after refresh)
For text editing, if you use Monaco, it has so many internal lifecycle hooks you want to be aware of and interact with directly, that you'll see that most of implementation will end up outside classic frontend lib fast and I'd rather build the thing instead of bridges and wrappers to talk with a high-level framework.
All in all, you probably want to own a lot of state and behaviour yourself, and add a cooperating framework on top instead of an all-encompassing one.
Comment by kbyatnal 5 days ago
It has some rough edges as a result, but your suggestions are very valid. We’ll make those improvements (we’re also taking PRs!).
Comment by lionkor 5 days ago
Comment by e12e 6 days ago
[r] Thread was about rewrite in rust, but it made me have a look at the purpose/claims made by the project - and fine-grained, automated memoization for speed seems central.
Comment by andrewlu0 5 days ago
Comment by pea 6 days ago
Comment by dvt 6 days ago
Thanks for releasing publicly.
Comment by andrewlu0 6 days ago
Comment by dvt 6 days ago
[1] https://github.com/J-F-Liu/lopdf
Comment by petilon 6 days ago
Comment by andrewlu0 6 days ago
testing was mostly manual with a test corpus we generated. its not perfect but its pretty close for most files we've seen
Comment by nhatcher 6 days ago
We wrote (should say are writing) our own xlsx parser in Rust on IronCalc:
Comment by CraigJPerry 6 days ago
By quirk of fate i've spent the past 2 days prototyping some stuff on pdfjs. Just trying to figure out a game plan for handling bounding boxes in the face of page zooming, different resolutions etc. etc. I can't see it mentioned whether the components are virtualising pages (as in reusing dom elements as document pages scroll by). I guess i just learned what i'll be exploring tomorrow then...
Comment by andrewlu0 6 days ago
the zoom should work with the bounding box highlights, we're working on adding rotation support
Comment by sails 6 days ago
React/next is limiting, we have rebuilt this for angular and now redid it again using lit for better compatibility. Our old one is very similar to this.
Loading citations for each field across 1000s of pages, colliding citations for all the messy formats, zoom, rotate etc. what a mess!
Great that you took the time to MIT this as it would have saved us many hours, though I think today Fable + Codex makes it pretty quick
I could recreate these in lit as a fork, would be very useful to have the full set
Comment by andrewlu0 5 days ago
Comment by egeozcan 6 days ago
Comment by resurge 6 days ago
Dependency in package.json:
- https://github.com/extend-hq/ui/blob/main/apps/v4/package.js...
Dependencies in some components:
- https://github.com/extend-hq/ui/blob/main/apps/v4/components...
- https://github.com/extend-hq/ui/blob/main/apps/v4/components...
Comment by andrewlu0 5 days ago
None of the ones in the registry should have next as a dependency, please lmk if otherwise
Comment by chrisweekly 6 days ago
Comment by andrewlu0 5 days ago
Comment by andrewlu0 6 days ago
Comment by hju22_-3 6 days ago
Also, add either user interactive loading of components or lazy load the demos, the amount of demos murder performance on phones.
Comment by andrewlu0 6 days ago
on the demos - everything below the fold is lazy loaded but i will see what we can do to improve the mobile perf
Comment by digitaltrees 6 days ago
Comment by iamsaitam 6 days ago
Comment by andrewlu0 5 days ago
Comment by whitephoenix 6 days ago
Comment by andrewlu0 5 days ago
Comment by qreoct 6 days ago
Is this a known issue?
Comment by andrewlu0 5 days ago
Comment by qreoct 5 days ago
Comment by spankalee 6 days ago
Comment by digitaltrees 6 days ago
Comment by ranger_danger 6 days ago
Comment by digitaltrees 5 days ago
Comment by andrewlu0 6 days ago
we hope this can be useful for people building in React though!
Comment by mklifelife 6 days ago
I'm curious whether the primary users are AI-native document products or more traditional SaaS applications.
The document-app niche feels increasingly important with the rise of AI workflows.
Comment by sails 5 days ago
Comment by carlosjobim 6 days ago
Comment by andrewlu0 6 days ago
Comment by carlosjobim 5 days ago
Comment by kalms 4 days ago
Comment by warthog 6 days ago
could not have been easy
Comment by andrewlu0 6 days ago
Comment by lateforwork 6 days ago
Comment by drivingmenuts 6 days ago
Comment by dvt 6 days ago
Comment by hobofan 6 days ago
Comment by andrewlu0 6 days ago
i can't promise its visually 1:1 with Word/Excel but its pretty close on the corpus we tested with
Comment by rolls-reus 6 days ago
Comment by andrewlu0 5 days ago
Comment by rolls-reus 5 days ago
Comment by mkl 5 days ago
Comment by codingconstable 5 days ago
Comment by promiseofbeans 6 days ago
Comment by andrewlu0 6 days ago
We aren’t not trying to reinvent that engine, rather just provide a building block for people to plug in their design system to its controls
Comment by phonon 6 days ago
Comment by andrewlu0 6 days ago
you are welcome to try it with your own documents and see, but its just one example we wanted to show. for the blocks that use the react-docx library, you can always copy the code and use a different method to render the docx file/thumbnails
Comment by cactusplant7374 6 days ago
Comment by Lord_Zero 5 days ago
Comment by plastic041 6 days ago
Comment by andrewlu0 6 days ago
the root page is a bit slow with all the viewers, in practice you probably wont have that many in your app on one page
Comment by stinger 6 days ago
Comment by andrewlu0 6 days ago
Comment by deafpolygon 6 days ago
Comment by grahamstanes17 2 days ago
Comment by KolmogorovComp 6 days ago
On mobile Safari…
Comment by andrewlu0 6 days ago
Comment by dzonga 5 days ago
Comment by greenleafone7 5 days ago
Comment by wu1064442747 6 days ago
Comment by xducn1 4 days ago
Comment by topaitools_xyz 6 days ago
Comment by daohieu91 6 days ago
Comment by bschmidt800 6 days ago
Comment by peteforde 5 days ago
1. I saw it was React
2. Nothing loading, just a page full of spinners
I truly wish React could be launched into the sun.