Tldraw – a tiny little drawing app
tldraw.com
tldraw.com
A few notes:
- I post a _lot_ about tldraw on Twitter. If you're curious about how this came together, or want to follow along as we ship new features, check out my timeline (https://twitter.com/steveruizok).
- The whole tldraw project is MIT licensed and open source (https://github.com/tldraw). And it's still in development! If you'd like to contribute, join the Discord channel (https://discord.gg/SBBEVCA4PG) or drop by the repo (https://github.com/tldraw/tldraw).
- The multiplayer is using a pre-release version of Liveblocks (https://liveblocks.io/)—and honestly isn't using it in a very clever way—and so can have some desync issues. Consider this part of the app an early beta.
- We also ship a Visual Studio Code extension that lets you use tldraw inside of VS Code! (https://marketplace.visualstudio.com/items?itemName=tldraw-o...)
A little more about the project itself:
The tldraw project has a few different layers.
At the bottom, there is a renderer named @tldraw/core (https://github.com/tldraw/core) that is essentially a "put React components on a canvas UI" engine. You give it a data model along with a set of utilities to interpret that data model. Simple but very fast, very flexible, and packed with helpers for building these kinds of apps. It's already being used for some pretty ambitious projects apart from tldraw itself.
The main library, @tldraw/tldraw (https://github.com/tldraw/core), exports the whole tldraw "app" as a React component named <Tldraw/>. This component can be embedded in any React project. It can be controlled either by props or by its own API (ie `app.selectAll().duplicate()`).
The website is a very thin Next.js app that embeds the <Tldraw/> component.
There are also a few other libraries: @tldraw/vec for the vector math and @tldraw/intersect for intersections. If you like to work on these kinds of projects, definitely bookmark those libraries! They contain a lot of useful code.
As for its development, I've taken off a few months between jobs to work on this full time. Until now, the site has been accessible only to my Github sponsors, but it's now free and open to everyone. If If you'd like to support the project's continued development, you can sponsor me here: https://github.com/sponsors/steveruizok.
I'll answer questions here but if you want to contact me directly, my DMs are open @steveruizok.
How tied to React is this? Could it be used without it, or adapted to that?
At the moment it's pretty tied to React, however the "app" itself—the big state machine that responds to events—is independent. It would take some effort to make it work with other libraries but it could be done.
Double click on the shape in the toolbar to keep it selected!
I would expect Cancel to cancel the new project rather than losing the current work, and would expect a "No" option instead to mean lose the current project.
Just use SVG-edit & draw each stoke on separate "Layer".
``` Simply stated, the “Sponsorware” model for releasing a project is made up of a few simple steps:
Build something people want! – This is easier said than done, but we believe this model works best for open source projects with significant pre-release hype. The more interest you are able to build in your product before launch, the better your results are likely to be.
Make it available only to “sponsors” – These “sponsors” are people who give you recurring revenue. This can be through any of the big sponsorship platforms (i.e. - GitHub Sponsors, Patreon, OpenCollective, etc.) or it can be a system you roll yourself. The important parts are A) that the revenue is recurring, and B) that either your number of sponsors or your net revenue is publicly viewable
Set a sponsorship threshold, and after crossing it, make your thing freely available to the world! – This can be a number of monthly sponsors, an amount of monthly revenue, or whatever you like. It should be PUBLIC though. Transparency is huge in this process and people need to be able to see progress toward the goal.
``I'm up to 211 sponsors, about $1700 per month.
Many of those sponsors are one-time donations. At the beginning, I set the minimum one-time donation to $1; once I reached 100 sponsors, I bumped the minimum up to $10.
The larger sponsors come mostly from digital ink library perfect-freehand (https://github.com/steveruizok/perfect-freehand), also MIT licensed, which is being used by many products such as Next.js live, Milanote, Clover, etc.
[1]: https://unglue.it/
The main difference between the two is that Excalidraw renders to HTML canvas, while tldraw renders to a regular DOM tree. There are tradeoffs but this lets us make things like sticky notes or other types of complex embedded content without too much difficulty.
I like the ui better than Tldraw, I think. I'll have to try it more and see what I think.
If you want it to stick with the same shape, double click the shape in the toolbar!
And yeah, I've spent so much time thinking about how to do an eraser right! I think it will need to wait until the next version of my digital ink library. https://twitter.com/steveruizok/status/1458712896620404742
Looking forward to exploring your other projects!
A few feature requests: - double click to insert text - `?` to open a shortcut page - reasonable shortcuts (not just numbers) - `del` to delete
* When resizing a group of strokes, the resizing happens per stroke instead of as a group which is contrary to what I expected.
* Also during resizing and other operations, it would be good to see the selection outline, at the moment it hides itself which makes it difficult to know how far you've gone from the original position.
* I was expecting the Del key to work for deleting objects.
Thank you for making.
One feature request would be that if I start typing when a box or circle is selected, it would put text in that object. I realize that this might be difficult with hotkeys, but I use that feature in Visio all the time and I love it for quick diagrams.
Next best would be if you select the text button (or '7') when an object is selected, it would insert the text in that object.
- can't select menu items with pen
- an undo button on the hotbar would be nice
- a way to control the return to select mode after drawing a shape - I often want to draw a few boxes and then connect them with arrows, but having to keep hitting the shape select is a bit painful
As far as the select mode, try double-tapping one of the tools! That will keep that tool selected until you manually select a different one.
I think it's more refined than Tldraw.
My favorite feature to build was the Rewind feature, so you could see people draw something together over the course of months.
has drawing tools become a hot space of late? there seem to be a lot of options (i usually use diagrams.net, but have also heard of lucidchart), so would be great to have some sort of comparison b/w the various tools
Please don't bloat it
Starts immediately and works on my phone as well as my laptop. No sign up or anything - just straight to business as it should be.
It is open source and interestingly packaged as a library:
Works on VS Code for Desktop, github.dev, vscode.dev, GitHub Codespaces.
https://marketplace.visualstudio.com/items?itemName=tldraw-o...
Some thoughts on the extension and workflows are here: https://twitter.com/seflless/status/1446892923661045767?s=20
Not sure that this would work for most people , but would for sure for individuals who think I’m sticky notes
By the way, Tldraw somehow remembered my unsaved drawing — that's impressive!
https://www.googletagmanager.com/gtag/js?id=G-
what does this do ?
There is no link transparently talking about this.
What API is used to track Shift/Ctrl/Alt keys state?
You need to listen for the pointer events because some devices such as Wacom tablets do not dispatch proper keyboard events when you press a button that has a modifier key role assigned to it.
On Apple devices event.metaKey represents the state of the command key, so in most scenarios you would be storing the state as: let ctrlOrCmd = (isAppleDevice ? event.metaKey : event.ctrlKey);
From the console I see this each time I try to draw a line: Unexpected value NaN parsing x attribute. react dom.production.min.js:23:234 Unexpected value NaN parsing y attribute.
When this project kicked off, I wanted something that could be saved alongside code as version-controlled documentation, and that was the first time I noticed the "tldr" in "tldraw". So I just used tldraw.com and stole the name!
any chance you'll add colors at all?
tldraw is a separate project. The big difference is that Excalidraw renders to HTML canvas while tldraw renders to a regular DOM tree. There's a trade off: canvas can have better performance on some machines, while my approach with tldraw makes it easier to implement more complex embedded content. I wouldn't expect any changes, so use whichever you prefer!
Not an intuitive location (I was expecting it in File > Save As), but its there.