Hacker News new | past | comments | ask | show | jobs | submit login
Show HN: Puck – Open-source visual editor for React (github.com/measuredco)
451 points by chrisvxd on Sept 5, 2023 | hide | past | favorite | 95 comments
Hey hackers, OP here!

I've been dipping in and out of this problem space for the last few years with many of my clients.

Puck sits somewhere between an old-school WYSIWYG-powered CMS and headless one, allowing content teams to author content using real React components.

Traditional CMS solutions were flexible but often resulted in page that completely broke the brand guidelines. Headless CMS solutions are a fantastic way of controlling brand by restricting UI changes to developers, but makes layout changes restrictive and slow as developers often need to get involved.

Puck provides a visual editor for React that can sit on top of your existing headless CMS (or act as standalone). We've been dog-fooding it on a few pages at https://measured.co and on https://wellpaid.io. So far, so good

The API is built for React, which allows FE devs to quickly integrate their existing component and add some form fields for author input, or connect it to a headless CMS of choice.

It's open-source under MIT, and pairs nicely with Next.js (check out the demo application). Next in the pipeline: support for multi-column layouts, richer demos, new plugins.

Looking forward to hearing your comments!




Wow, I've seen so many of these kinds of things over the years but this one is really special: extremely intuitive design, really powerful and flexible, and MIT licensed too. Super impressed.


This comment made my day. Thank you


Awesome. I've literally been tasked with building something exactly like this, and it's a pain in the ass nothing exists like this for Vue so I have to do it from scratch.

I plan to make it more like builder.io/demo however where CSS can be arbitrary, that way basic landing pages can be built.

Do you have any tips of things you wish you did differently, or what was more painful than you expected, as well as anything that might help in this?


It's such a common problem, I'm amazed there aren't more solutions out there.

A sound data model really helps things out. I'd go API-first.

Drag and drop is a PITA. Specifically multi-column layouts, which require nested dropzones and a bunch of "intuitive" UX. A good library can help here, but not do everything (we're using react-beautiful-dnd which is a bit out of date - dnd-kit might have been a better shout). This hasn't landed in our main branch yet, but you can see it under the nested-dropzones branch (https://github.com/measuredco/puck/tree/nested-dropzones).

If you could write React wrappers for your Vue components, you could potentially leverage Puck directly. That would save a lot of time. And even if not, you might be able to fork it or reuse the data model.

Happy to give you more pointers. If you want to DM, I'm @chrisvxd on Twitter/GitHub and here's my LinkedIn: https://linkedin.com/in/chrisvilla/


I just published a dnd library for nested tree structures (https://www.npmjs.com/package/vue-tree-dnd), and I can't believe how much of a PITA dnd is! Working on browser-compatibility took me back to pre-jquery days...


Interesting.. do you think it's a good use case for a drag an drop editor compared to other DND out there?


It's not for editing UIs like the OP's post. This is for editing nested lists. So it's probably not what you're looking for. But I made it because when I looked for a vue library that could do what I needed, I didn't find one that I wanted to use/thought would work.


I'm assuming you researched a lot of other DND libraries when building. Did any stand out to you that were better than the rest? IE supporting nested structures, and looked to be programmed well. In my research I found about 8-10 of them and just thought... ugh, I will do this later, to decide between them


Well, there are obvious leading contenders like `https://sortablejs.github.io/Sortable/` and, within the `vue` space, `https://sortablejs.github.io/vue.draggable.next/`. Most of the stuff I looked at was unmaintained (lots not updated for vue3).

I really disliked the vuedraggable was handling nesting, and it's just a wrapper around a sortable. At the end of the day, my problem was simple enough that I didn't want a 500kb dependency. If you're wanting to do something like the OP but with nesting, I'd definitely start by looking at Sortable, though (maybe wrapping it the way you want).


If you're open to hosted service, is the best commercial visual + headless CMS I've come across that supports React - https://www.storyblok.com/home.


Does it allow embedding in an actual app? Thats the problem I have with these is they all require some weird form of going to their domain. I need the editor (AND the rendered page) to be 100% on my own domain. I wish they had some editor as an open source library and id just pay to have an API key or something


Are there more details on the data model? I'm actually building something like this but not for React, so it might be useful to reuse the data model as you say.


The data model is detailed here in the docs: https://github.com/measuredco/puck#data

There's not an awful lot to it.


Take a look at the Vue Designer [0] (it is our app), an editor that let's you visually build Vue projects, not just using existing components. You can even build components with the editor.

[0] https://vuedesigner.com


Take a look at grapesjs -- it's a bit janky in places but it's self hosted and overall works pretty well. It can output plain HTML so I think it could be integrated with vue.


The problem with that one is I want to completely avoid parsing/rendering HTML. That creates huge headaches when you want to create some kind of "component" but then once the html is rendered, it cant be re-parsed into its original state without adding a bunch of junk to it, like helper classes etc. It's just very brittle for what I want to do


Plasmic.app works with vue - why not just use that?


This was what I said previously, which I'm assuming plasmic doesnt do:

> Does it allow embedding in an actual app? Thats the problem I have with these is they all require some weird form of going to their domain. I need the editor (AND the rendered page) to be 100% on my own domain. I wish they had some editor as an open source library and id just pay to have an API key or something


This is just so fantastic, I have been looking for something like this for the open-source edtech app builder Flow (https://github.com/opencurriculum/flow) for the past year! Talked to the WebStudio guy and did so much research, but nothing was just right. This feels JUST. RIGHT.

Thank you for all the hardwork!


Btw, a very easy big win for you would be to port the side styles/interactions panel of WebStudio into this. And by port I mean extracting the code to make a common open-source library with the correct license and putting it in Puck.


Great idea - could add this as a core field type so you can use it via the fields API, i.e. `{ type: "css", cssProperties: ["color"] }`


Oh, awesome. Let me know how you get on!


This looks decent and the idea is sound. I was looking at headless CMS recently and it only vaguely struck me that what is needed is the front-end builder component.

Looking at the comments from the dev in this thread it seems this really only supports vertically stacked layouts right now? At least the demos were responsive but each component seems to assume that it fills the width of the screen. Making responsive components in a columnar layout might be more challenging for this kind of toolset to handle.

Looking at the recipe for next.js app I noticed that the component where the page is rendered appears to be in `[...puckPath]/client.tsx` which is a "use client" component. That makes me wonder about the entire framework and whether or not it actually renders the pages on the client or the server.

If those two things are true then this might have limited application. Finding a way to handle responsive layout for columnar and/or grid based pages will be non-trivial. Finding how to mix server and client components effectively will be non-trivial.

That aside, it seems useful and decently structured. In places where we I've worked where there is a lot of customization desired, having a UI builder that customizes page layout in some data format (json or xml) has been very helpful.


Scott from Measured here, we're dog-fooding puck on https://measured.co.

There's a WIP branch with support for more sophisticated layouts here: https://github.com/measuredco/puck/tree/nested-dropzones

And I think `use client` is a Next 13 thing. Not sure of the details, but Puck definately does render server-side.


+1 what Scott said

Multi-column layouts are incoming very soon

And Puck does support either server or client rendering


Just love this. And trust me, I have seen many of these kinds , but this is really different in the right sense. So easy to add custom components and get going. Well done. Will definitely try more. Thanks for this.


Thank you!


looks awesome, a small screenshot in your readme would have helped understand that it's more of a drag and drop component


"open source visual editor" doesn't really comply with "The self-hosted drag and drop editor for React."


Hey, thanks for the feedback! We're still figuring out the wording and will take this on board.


I would've expected some kind of WYSIWYG functionality for "make this API call and map the fields/properties of the response into the components"

Like on the demo where it says https://puck-editor-demo.vercel.app/edit Users Reached 20M+, I thought instead of static text, it would've shown some kind of {{template}} that shows JSON query format like `jq` does to pluck fields from arrays/objects of fetch() response bodies (how React would pass along props/state)


We don't natively support templating strings, but since it's rendered by React, you can always add that when integrating Puck.

However you can use an adaptor if you need to pull data in via a third party API: https://github.com/measuredco/puck/tree/main/packages/adapto...


I was trying to give feedback on how you might make your product "more attractive"/increase value proposition to the type of person you are aiming to help this with: people who want to make a React UI through a GUI instead of in a text editor.

I know how to pull data in via React/JavaScript "code". If I can do that, I'm technical enough to not need a GUI to help me make a UI... do I?


Not the OP, but our company Measured is building Puck as an open source project, so I'll try and answer.

Puck is targetted at content/CMS use cases, rather than general UI building. So the ability to establish guardrails in the editor experience is intentional. For best effect, we envisage Puck being used alongside a well-considered library of on-brand composable components. The aim is to enable non-developer editors/authors to freely update and build content, whilst keeping the UI consistent and on-brand.

This is a problem area we've encountered many times in our client work, hence why we wanted to scratch this itch.

Having said that, I do believe the Puck editor GUI _can_ be configured to work with remote data somewhat as you describe, using the adaptor linked above (but there's currently no demo for this feature).


Even if you are technical enough, you might still need a GUI to avoid any surprises. Also the end user of this tool is not tech people, but content managers


How do you keep the saved data props/values (title, description) in sync with the component props in the code? Let's say I change `description` to `subtitle` in the code, what happens to that information?


I just re-read your comment and realised I didn't answer it first time around.

The best way to handle this is in the render function you pass to Puck, which can continue to support the old prop (`description`) and map into the new prop (`subtitle`), even if it's not provided by the author.

We don't have a system for migrating props in the actual data yet, but it's something we could look into.


Tracking this here, with proposal: https://github.com/measuredco/puck/issues/41


We let the user decide how they want to store the data via the `onSave` and `onChange` callback props you provide to the `<Puck>` component. So you would likely save to your own database in the callback.

The data shape is detailed here: https://github.com/measuredco/puck#data


I'm trying to understand if the layout immediately becomes brittle once the data is saved (unless someone goes in to the saved data and patches it by hand when the layout is updated).


Sorry I got the wrong end of the stick. Please see my other reply to your comment.


This is exactly what Framer did before pivoting to a website builder, it might be worth looking into them. How will you be different than them?


Framer is a design tool, but Puck is a content tool. We're focused on allowing content teams to create pages using existing on-brand components. Like a WYSIWYG with guard-rails.

We built it because we couldn't find something that would let our clients' content teams produce content for their sites without 1) either going off-brand or 2) pestering their devs for layout changes.


Can you elaborate what you mean by "content" tool? Are your ideal users creating marketing sites, blog posts, or other?

In my experience, most of what content teams work with are some forms of CMS, and the design tools usually deal with layout and creating generic sites that work with the data structure inside the CMS.


Typically marketing sites and blog posts etc. It could probably be extended to applications, but that’s not what we built it for.


Framer also has a CMS and you can import React components [1]. They pivoted because there wasn't much traction in that use case.

[1] https://www.framer.com/developers/#overview


your pivot comments seem irrelevant as he is not selling this as a product, he is using it as a white-label solution for his clients.


Nice, this looks pretty good.

It's always been my dream of having something like Retool, but using your own components and completely open source. Retool is a backend layer too, so that's partially what's missing to complete the picture. But if we had that as something like a framework, we'd start getting close to the days of drag-and-drop UIs.


Can I make my own prop editor?

Ex. instead of an input for the prop `name` I want a picker that fetches data from some API


You can use adaptors for this. Adaptors let you request a third party API via the `adaptor` field type.

Docs are limited, but there's a reference data shape here: https://github.com/measuredco/puck#adaptor

Example implementation here: https://github.com/measuredco/puck/blob/main/packages/adapto...

Example usage here: https://github.com/measuredco/puck/blob/main/apps/demo/app/c...

You can either use it for a specific prop (i.e. `name`) or spread the result of the API call across your entire component (use the magic `_data` prop).


This might be a better example, actually: https://github.com/measuredco/puck/tree/main/packages/adapto...


minor:

maybe the HN post title should mention the name of the project "Puck" for future discoverability


Great idea - might update it once the dust has settled.


What are the performance implications of this setup?. I dont know much about web stuff, but it seems like most of the markup would be hidden from the browser and so it wouldn't have much control over optimizing the rendering.


This looks very nice ! How would you compare it with slatejs, tiptap or lexical ? Is this only for layouts but not for content ? (Would it be very hard to include some rich text and make it work like a cms with rich text editing?)


Thanks! It’s possibly I’m misunderstanding, but I believe Puck is a different problem space to the other solutions you’ve mentioned -

Puck enables content teams to produce web pages using existing React components produced by their React developers in a fixed and predictable manor that keeps them within the brand guidelines.

You can’t inject arbitrary blocks and can only interact with components that are defined by your developers.

You can render fully fledged pages or even, in theory, applications.

Regarding content, Puck supports inline editing or pulling in data via an API adaptor (such as from a headless CMS).

We don’t have a rich text field type currently, but I’m not opposed to adding it. (Internally, we’ve added a markdown component to enable some basic formatting and longer form content: https://github.com/measuredco/measuredco-site/blob/02fc908b8...)


It actually could be interesting to add tiptap for collaboration!


This looks very cool. Is anyone aware of something similar for Angular? We have a half-baked version that's been in pre-alpha for our webapp, but if there's something out of the box that we could leverage...


I'm not aware of anything. You could potentially use Puck directly if you wrap your Angular components inside React components for the purpose of editing, and build a custom version of `<Render>` that walks the data object and renders straight to angular.


Well done. This looks great!

A couple of questions:

1. How easy is it to customise and extend the interface of the editor while still using the core of Puck?

2. This looks like it could be used to build an editor similar to Shopify's theme editor or is that a stretch?


Thanks! Some answers for you:

1. You can override a bunch of stuff using React-like APIs. `renderHeader` allows you to take over the header, and the plugin API allows you to wrap the root of the preview content page and take over the fields area on the right hand side. We don't yet support full take-overs, but we'll continue to work on these. Plugin API: https://github.com/measuredco/puck#plugins

2. I think you should be able to mimic a bunch of the behaviours. The main missing piece is multi-column support, which is landing soon via the `nested-dropzones` branch: https://github.com/measuredco/puck/pull/37


This looks great. I would love to be able to use this to create UIs if it were to support integration with GraphQL data sources.


You can certainly configure it to work with GraphQL if you need to. See this adaptor for an example on how to integrate with external data sources: https://github.com/measuredco/puck/tree/main/packages/adapto...


Love it! Good looking, polished UI. I'm probably most impressed by the easy integration and React API. Congrats.


I recall a post of a similar project but for Svelte some time ago I believe. Anyway this looks pretty slick!


Looks neat! Do you consider adding input elements? (forms,wizards..) if so it will be my goto platform!


Puck is for integrating with your existing component library, so not completely no code.

Having said that, a developer could add any type of form input as a type of component!


Is it something like React Bricks?


Yeah, similar!


Looks great, the animations of drag-drop looks really smooth. How is it done?



Yup that's the one. Also recommend checking out [dnd-kit](https://dndkit.com), which we may migrate to at a later date.


Looks good - does it support callback props, and how do you enter them?


It pretty much supports anything that React supports, but it's not possible to pass callback props in directly via Puck's authoring form.

However, you might be able to either wrap your component inside the `render` function and define your callback there, or use context to pass in a function from higher up the tree.

If you share your use case, I might be be able to help you out.


Looks amazing, great work!


Very cool. Are you familiar with plasmic.app? I'm expecting to integrate it into my next site build and would be curious for your take having built something in the same general category.


Yes, but turns out I don't know enough about it. Related thread: https://news.ycombinator.com/item?id=37395707


Really cool!


love this


This is really slick! A really fluid and intuitive interface.

We use https://react-page.github.io/ (also MIT licensed) extensively at my startup; it attacks the same problem, and it's been incredibly effective (and hackable!).

Generally speaking, owning your own CMS data, in your own database, with a well-documented JSON data format, and adding the ability to take any React component you've written (that itself may interact with your own data) and make it not only reusable as part of a content editing system but also WYSIWIG, opens up a huge number of opportunities - including adding your own logic to transform content before display.

https://builder.io is another alternative that's very effective at the adapting-custom-components-to-WYSIWIG side of things, but does keep the data in its own cloud storage.

I'm really excited to see innovation in this space, and I'll be following Puck closely!


Thanks for sharing react-page! I hadn't come across this before.

Builder.io is great but the hosted nature made it a non-starter for us.


Is anyone here who has shifted exclusively to visual react builders ?

I have been writing react since version 0.11 and am considering shifting to a visual for day to day development.


I am probably your opposite ... I recently learnt basic React in a weekend and built a functional MVP webapp by hand.

For a second iteration of the app, I asked ChatGPT (Plus) to help me. Gave it existing code and gave increasingly specific UI and behavior requirements. After a few hours of pair programming ... I had a working new page (with backend API integration). The UI behavior I wanted went fairly deep -- with a lot of conditional logic to render styles, handle double clicks on text to make them editable form fields, etc.

I am impressed with this approach at least for prototyping and MVPs.

The resulting page was surely not very maintainable due to the complexity of embedded logic and conditionals ... but again I wouldnt have managed to manually code such complexity myself. Maybe if forced to do it manually i would have learnt more, modularized my code more, but spend a week instead of a day achieving the result. I am not a career developer -- so for my use case I will take this productivity boost.

I think there is a great opportunity to merge a visual UI builder like this (puck) and an LLM backend/interface to radically improve productivity and make prototyping as well as building real apps (production grade, modularized, maintainable) much more easier to build.


Alternative meaning - Polish city nearby me :) https://en.wikipedia.org/wiki/Puck,_Poland


The name comes from (ChatGPT-researched) folklore: https://en.wikipedia.org/wiki/Puck_(folklore)

Puck is a... fairy... [that takes on] the shape of animals

Puck is also a little, er, mischievous and sometimes seen as a demon. But we prefer the first interpretation.


How does this compare to https://www.plasmic.app/?


Puck is focused on providing a solution for non technical folk to build on-brand web pages with their team’s existing React components. This enables them to build web pages with guard rails that respect their brand guidelines.

Plasmic is a no-code tool for building websites and applications from scratch. A great solution for a different problem.


Hi! I work on Plasmic. Plasmic's most common use case is actually the same one, letting content editors build pages in your existing website using your React components.

Congrats on this release! We are actually open sourcing Plasmic soon, would love to discuss any possible ways to collaborate.


Oh that's fantastic. I wasn't aware and applaud the decision to go open source.

Happy to discuss/collaborate. I'm @chrisvxd on GH/Twitter, and here's my LinkedIn: https://linkedin.com/in/chrisvilla/


Looks like we have the same question.


Probably ia cliche now but ...

Have you considered integrating an LLM to expand the functionality?

Based on some recent experimentation I was able to get some fairly complex React UI and behavior out of a pair programing session ... without having a lot of React experience and skill myself. Seemed ripe with potential.


It’s probably a cliche but yes, we’ve been thinking about this.


My only major gripe with it is React. Either go all the way and build something for Svelte that does this lowering the bar to the bottom on both creation and understanding of the UI layer or

Do this with Rust and target Wasm abstracting away the hard / tedious parts of working with lower level languages and creating graphical applications.

Like this + Tauri would be an absolute powerhouse but as good as it is, it’s still just another React maker.


This seems like a weird gripe. There's probably a high chance that a team/company has a bunch of React components already built, or they have a bunch of devs who know React, and just need an editor for it.


React is what we needed for our use case, but maybe we can eventually evolve it to a place where it can be used with different frameworks.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: