10 ms·
Show HN: Repaint – a WebGL based website builder
Hey HN! We're Ben and Izak, founders of Repaint (YC S23). Repaint is like Figma, but for creating real websites.
It has panning, zooming, and dragging elements around. The settings closely follow html/css. We think an open canvas is a big improvement over other website builders. Everything is easier: styling, consistency, responsiveness…
But making it work was hard! We thought HN would appreciate the tech behind it:
- A custom WebGL rendering engine (w/text, shadows, blurs, gradients, & opacity groups)
- A partial implementation of the css spec
- A custom text editor & text shaper
- A transformer to turn designs into publishable html/css
Repaint is a design tool for html/css. But internally, it doesn’t actually use html/css itself. All your designs live in a single <canvas> element.
We wanted users to be able to see all their content on one screen. We target +60fps, so frames only have 16ms to render. The browser’s layout engine couldn’t handle simple actions, like zooming, with many thousands of nodes on the screen. To fix that, we wrote a rendering engine in WebGL.
Since we use custom rendering, we had to create a lot of built-in browser behavior ourselves.
Users modify a large dom-like data-structure in our editor. Each node in the document has a set of css-like styles. We created a layout engine that turns this document into a list of positions and sizes. We feed these values into the rendering engine. Our layout engine lets us display proper html layouts without using the browser's layout engine. We support both flex and block layouts. We already support multiple layout units and properties (px, %, mins, maxes, etc.).
We also can’t use the browser’s built-in text editor, so we made one ourselves. We implemented all the common text editor features regarding selection and content editing (clicking, selection, hotkeys, inline styling, etc.). The state consists of content and selection. The inputs are keystrokes, clicks, and style changes. The updated state is used to render text, selection boxes, and the cursor.
When you publish a website, we turn our internal document into an html document. We've intentionally structured our document to feel similar to a dom tree. Each node has a 1:1 mapping with an html element. Nodes have a list of breakpoints which represent media-queries. We apply the styles by turning them into selectors. All of the html pages are saved and stored on our fileserver for hosting.
We made a playground for HN, so you can try it yourself. Now that the tech works, we’d love feedback and ideas for improving the product experience.
And we’d love to meet more builders interested in the space. If that’s you, feel free to say hello in the comments! Or you can reach Ben from his website.
Playground: https://app.repaint.com/playground https://app.repaint.com/playground
Demo Vid: https://www.loom.com/share/03ee81317c224189bfa202d3eacfa3c3?sid=094a4888-5ca7-4c4f-ba57-bb24cffe169c https://www.loom.com/share/03ee81317c224189bfa202d3eacfa3c3?...
Main Website: https://repaint.com/ https://repaint.com/
Contact: https://benshumaker.xyz/ https://benshumaker.xyz/
- JaggerJo 2y agoCongrats on launching! What language / toolchain are you using?
- izakfr 2y agoThe whole app is written in Typescript, except the webserver (Golang). We've already started to run into some performance issues on large projects. Eventually we will write the frontend in C++ (using emscripten to compile to JS). The UI will use React, but the canvas state will be in C++. Also, the monolithic backend will be split apart and rewritten in a different language to optimize speed. We have a lot of work to make it more performant, but it's going to be fun to build :)
- garganzol 2y agoLogin to try a website? No, thanks.
- benshumaker0 2y agoThere's a playground in the post if you want to try it without making an account :)
- Exuma 2y agoDude. PLEASE MAKE IT EMBEDDED!!! I need to integrate a "site builder" for a landing page service. I cant use things like the other options out there because they require actually going to the site. It makes it useless where i want a fully self contained "builder" for a number (bunch) of different landing page domains.