8 ms·
Show HN: Puck – Open-source visual editor for React
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 https://measured.co and on https://wellpaid.io 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!
- talboren 3y agolooks awesome, a small screenshot in your readme would have helped understand that it's more of a drag and drop component
- deleted 3y ago[deleted]
- Exuma 3y agoAwesome. 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?
- chrisvxd 3y agoIt'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 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/ https://linkedin.com/in/chrisvilla/
- agotterer 3y agoIf 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 https://www.storyblok.com/home.
- Exuma 3y agoDoes 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
- robbiejs 3y agoLooks great, the animations of drag-drop looks really smooth. How is it done?
- jasonjmcghee 3y agoreact-beautiful-dnd https://github.com/measuredco/puck/blob/cae760fbfb8497de09311bb81e3059c07efe75ac/packages/core/package.json#L29 https://github.com/measuredco/puck/blob/cae760fbfb8497de0931...
- chrisvxd 3y agoYup that's the one. Also recommend checking out [dnd-kit](https://dndkit.com https://dndkit.com), which we may migrate to at a later date.
- tebbers 3y agoLooks amazing, great work!
- tmwatson100 3y agolove this
- MuffinFlavored 3y agoI 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 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)
- chrisvxd 3y agoWe 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/adaptor-fetch https://github.com/measuredco/puck/tree/main/packages/adapto...
- MuffinFlavored 3y agoI 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?
- bingemaker 3y agoEven 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
- mono_spaced 3y agoNot 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).
- continuational 3y agoLooks good - does it support callback props, and how do you enter them?
- chrisvxd 3y agoIt 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.
- matfrana 3y agoIs it something like React Bricks?
- chrisvxd 3y agoYeah, similar!
- zoogeny 3y agoThis 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.
- mono_spaced 3y agoScott from Measured here, we're dog-fooding puck on https://measured.co https://measured.co. There's a WIP branch with support for more sophisticated layouts here: https://github.com/measuredco/puck/tree/nested-dropzones 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.
- chrisvxd 3y ago+1 what Scott said Multi-column layouts are incoming very soon And Puck does support either server or client rendering
- nathancahill 3y agoHow 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?
- chrisvxd 3y agoWe 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 https://github.com/measuredco/puck#data
- nathancahill 3y agoI'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).
- chrisvxd 3y agoSorry I got the wrong end of the stick. Please see my other reply to your comment.
- chrisvxd 3y agoI 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.
- chrisvxd 3y agoTracking this here, with proposal: https://github.com/measuredco/puck/issues/41 https://github.com/measuredco/puck/issues/41
- shivekkhurana 3y agoIs 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.
- deleted 3y ago[deleted]
- albert_e 3y agoI 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.
- d0100 3y agoCan 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
- chrisvxd 3y agoYou 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 https://github.com/measuredco/puck#adaptor Example implementation here: https://github.com/measuredco/puck/blob/main/packages/adaptor-strapi/index.ts https://github.com/measuredco/puck/blob/main/packages/adapto... Example usage here: https://github.com/measuredco/puck/blob/main/apps/demo/app/configs/custom/blocks/Hero/index.tsx#L36-L46 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).
- chrisvxd 3y agoThis might be a better example, actually: https://github.com/measuredco/puck/tree/main/packages/adaptor-fetch https://github.com/measuredco/puck/tree/main/packages/adapto...
- simonw 3y agoWow, 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.
- chrisvxd 3y agoThis comment made my day. Thank you
- deleted 3y ago[deleted]
- nvegater 3y agoThis 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?)
- chrisvxd 3y agoThanks! 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/02fc908b8d9177406ae7844eb31b42d40c9d1fb9/puck.config.tsx#L437 https://github.com/measuredco/measuredco-site/blob/02fc908b8...)
- chrisvxd 3y agoIt actually could be interesting to add tiptap for collaboration!
- satvikpendem 3y agoThis 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?
- chrisvxd 3y agoFramer 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.
- teddarific 3y agoCan 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.
- chrisvxd 3y agoTypically marketing sites and blog posts etc. It could probably be extended to applications, but that’s not what we built it for.
- satvikpendem 3y agoFramer 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 https://www.framer.com/developers/#overview
- danr4 3y agoyour 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.
- deleted 3y ago[deleted]
- arek_nawo 3y agoLove it! Good looking, polished UI. I'm probably most impressed by the easy integration and React API. Congrats.
- jameslk 3y agoNice, 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.
- wbarber 3y agoVery 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.
- deleted 3y ago[deleted]
- chrisvxd 3y agoYes, but turns out I don't know enough about it. Related thread: https://news.ycombinator.com/item?id=37395707 https://news.ycombinator.com/item?id=37395707
- omarfarooq 3y agoHow does this compare to https://www.plasmic.app/ https://www.plasmic.app/?
- deleted 3y ago[deleted]
- wbarber 3y agoLooks like we have the same question.
- chrisvxd 3y agoPuck 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.
- yaaang 3y agoHi! 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.
- chrisvxd 3y agoOh 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/ https://linkedin.com/in/chrisvilla/
- albert_e 3y agominor: maybe the HN post title should mention the name of the project "Puck" for future discoverability
- chrisvxd 3y agoGreat idea - might update it once the dust has settled.
- albert_e 3y agoProbably 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.
- chrisvxd 3y agoIt’s probably a cliche but yes, we’ve been thinking about this.
- joseferben 3y agoReally cool!
- manishsharan 3y agoThis looks great. I would love to be able to use this to create UIs if it were to support integration with GraphQL data sources.
- chrisvxd 3y agoYou 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/adaptor-fetch https://github.com/measuredco/puck/tree/main/packages/adapto...
- transformi 3y agoLooks neat! Do you consider adding input elements? (forms,wizards..) if so it will be my goto platform!
- chrisvxd 3y agoPuck 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!
- p2hari 3y agoJust 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.
- chrisvxd 3y agoThank you!
- btown 3y agoThis is really slick! A really fluid and intuitive interface. We use https://react-page.github.io/ 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 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!
- chrisvxd 3y agoThanks 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.
- deleted 3y ago[deleted]
- laurels-marts 3y agoI recall a post of a similar project but for Svelte some time ago I believe. Anyway this looks pretty slick!
- jarek83 3y agoAlternative meaning - Polish city nearby me :) https://en.wikipedia.org/wiki/Puck,_Poland https://en.wikipedia.org/wiki/Puck,_Poland
- deleted 3y ago[deleted]
- chrisvxd 3y agoThe name comes from (ChatGPT-researched) folklore: https://en.wikipedia.org/wiki/Puck_(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.
- pat64 3y agoMy 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.
- chrisvxd 3y agoReact 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.
- madeofpalk 3y agoThis 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.
- promhize 3y agoWell 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?
- chrisvxd 3y agoThanks! 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 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 https://github.com/measuredco/puck/pull/37
- 2pointsomone 3y agoThis 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 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!
- 2pointsomone 3y agoBtw, 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.
- chrisvxd 3y agoGreat idea - could add this as a core field type so you can use it via the fields API, i.e. `{ type: "css", cssProperties: ["color"] }`
- chrisvxd 3y agoOh, awesome. Let me know how you get on!
- nraf 3y agoThis 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...
- chrisvxd 3y agoI'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.
- quadrature 3y agoWhat 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.