<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Matteo Frana</title>
    <description>The latest articles on DEV Community by Matteo Frana (@matfrana).</description>
    <link>https://dev.to/matfrana</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F318816%2F5994e94d-a36e-44c8-a8ac-762f46a0abd2.jpg</url>
      <title>DEV Community: Matteo Frana</title>
      <link>https://dev.to/matfrana</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/matfrana"/>
    <language>en</language>
    <item>
      <title>CMS vs AI: The Content Battle Begins</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Tue, 16 Dec 2025 14:58:09 +0000</pubDate>
      <link>https://dev.to/matfrana/cms-vs-ai-the-content-battle-begins-de</link>
      <guid>https://dev.to/matfrana/cms-vs-ai-the-content-battle-begins-de</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Lee Robinson recently announced that the Cursor team no longer uses a CMS for the Cursor website, opting instead to rely on AI to generate the site directly in code. As he put it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“I migrated cursor.com from a CMS to raw code and Markdown. I had estimated it would take a few weeks, but was able to finish the migration in three days with $260 in tokens and hundreds of agents.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;At first glance, this feels like a natural evolution, as AI is increasingly good at writing both code and content.&lt;/p&gt;

&lt;p&gt;At the same time, CMS vendors have been quick to respond, publishing articles that reaffirm the value of structured content, editorial workflows, and long-established CMS capabilities.&lt;/p&gt;

&lt;p&gt;So who is right?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;em&gt;AI-first&lt;/em&gt; camp?&lt;/li&gt;
&lt;li&gt;The &lt;em&gt;CMS-first&lt;/em&gt; camp?&lt;/li&gt;
&lt;li&gt;Both?&lt;/li&gt;
&lt;li&gt;Or perhaps… neither?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Is it possible to combine structured content, a headless architecture, and full-page, context-aware AI content generation?&lt;/p&gt;

&lt;p&gt;Spoiler: yes. (See the video below.)&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/XOUzBK1wtQ8"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;




&lt;h2&gt;
  
  
  Common Ground
&lt;/h2&gt;

&lt;p&gt;In March 2025, I published an article titled &lt;a href="https://dev.to/matfrana/common-ground-a-framework-for-human-ai-collaboration-516l"&gt;&lt;em&gt;“Common Ground: A Framework for Human–AI Collaboration”&lt;/em&gt;&lt;/a&gt;, where I defined &lt;strong&gt;Common Ground&lt;/strong&gt; as a shared format, medium, or interface that enables effective cooperation between humans, and between humans and AI.&lt;/p&gt;

&lt;p&gt;Classic examples of strong common ground include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Code&lt;/strong&gt; in software development
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Text&lt;/strong&gt; in copywriting
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In my August talk at Decoupled Days in New York, I refined this idea further by identifying three characteristics that a good common ground must have to support creative collaboration.&lt;/p&gt;

&lt;p&gt;A good common ground must have a &lt;strong&gt;structure&lt;/strong&gt; that is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Visible&lt;/strong&gt; — every actor in the system can see it
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understandable&lt;/strong&gt; — every actor can understand it
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editable&lt;/strong&gt; — every actor can modify it directly, without increasing information entropy at each review cycle
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Text and code are excellent examples: the structure &lt;em&gt;is&lt;/em&gt; the content. Both humans and AI can read it, understand it, and edit it directly.&lt;/p&gt;

&lt;p&gt;Now consider Content Management Systems. CMSs sit at the intersection of &lt;strong&gt;code&lt;/strong&gt; (the platform and frontend rendering logic) and &lt;strong&gt;content&lt;/strong&gt;—two areas where AI is already highly effective. This overlap raises the question: is AI about to replace CMSs, or expose their current limitations?&lt;/p&gt;

&lt;p&gt;To answer this question, we'll now dive into content management and AI, in search of common ground.&lt;/p&gt;




&lt;h2&gt;
  
  
  Content Management
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Good Ol’ Days
&lt;/h3&gt;

&lt;p&gt;In the early days of the web, websites were written directly in HTML. In 1997, when a client wanted to change their website, they called me and I edited the code.&lt;/p&gt;

&lt;p&gt;Later came tools like Microsoft FrontPage, which allowed non-technical users to generate HTML through a visual, word-processor-like interface. Unfortunately, these tools produced unmaintainable code (think deeply nested tables for layout), while giving users unrestricted design freedom: I still have memories of Comic Sans title in neon green on a purple background!&lt;/p&gt;

&lt;h3&gt;
  
  
  The Headless Days
&lt;/h3&gt;

&lt;p&gt;Fast forward to today’s headless CMS landscape.&lt;/p&gt;

&lt;p&gt;Content editors work with server-side, form-based interfaces to enter structured data into a database. Frontend applications retrieve this data via REST or GraphQL APIs and render HTML using modern frameworks and component-based “template languages” such as React, typically within Next.js or Astro.&lt;/p&gt;

&lt;p&gt;This model clearly separates responsibilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; build the frontend, define components, and control how content is rendered
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content editors&lt;/strong&gt; create content by filling abstract fields in the CMS forms
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both roles can use AI, but in very different ways, and with very different results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Developers use AI inside their IDE to generate or refactor frontend code&lt;/li&gt;
&lt;li&gt;Editors use AI tools (standalone or CMS-integrated) to generate copy, but only for individual text fields
&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  The Decoupling Problem
&lt;/h2&gt;

&lt;p&gt;By definition, a headless CMS is decoupled from the frontend. As a result, it does not know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;How content will actually be presented&lt;/strong&gt; in the frontend UI
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Which pieces of content end up on which pages&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because of this, AI operating inside a traditional headless CMS can generate individual text fragments, but it cannot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Generate full pages
&lt;/li&gt;
&lt;li&gt;Understand page-level context
&lt;/li&gt;
&lt;li&gt;Choose which components to use on a page&lt;/li&gt;
&lt;li&gt;Adapt the copy tone to the semantic role of each section
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The CMS has no awareness of the page composition, and no knowledge of the design system. Consequently, &lt;strong&gt;AI is limited to generating isolated text values rather than coherent, contextual page content&lt;/strong&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Visual Headless Paradigm
&lt;/h2&gt;

&lt;p&gt;Let’s take a step back and look at the decoupling problem from a different angle. Even before AI entered the picture, content editors already faced similar challenges. They were asked to edit abstract entities in a CMS interface (sometimes with an async preview), while mentally mapping those entities to sections of real pages.&lt;/p&gt;

&lt;p&gt;Since late 2019, a new paradigm has emerged: &lt;strong&gt;Visual Headless CMS&lt;/strong&gt;, introduced by &lt;a href="https://www.reactbricks.com" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In a visual headless CMS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; build a design system with &lt;strong&gt;composable React components&lt;/strong&gt; ("Lego bricks" for content)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editors compose pages visually&lt;/strong&gt; using those bricks, editing text and images inline, directly on the page&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This approach solves both the major problems of a decoupled architecture:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Editors work directly on the final page, not abstract forms&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The mapping between content and presentation&lt;/strong&gt; becomes explicit and intuitive, like a word processor&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For developers, the benefits are equally strong:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The frontend is a modern&lt;/strong&gt;, typed React application (Next.js, Astro, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The design system is fully enforced&lt;/strong&gt;: editors can only change what developers explicitly allow&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Content remains decoupled&lt;/strong&gt; and is stored as pure JSON, delivered via APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each page is represented as a structured list of blocks, each mapped to a React component and its properties (text, images, visual options). Both the CMS interface and the frontend render the same components, passing in the properties from the APIs.&lt;/p&gt;

&lt;p&gt;The result:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Developers&lt;/strong&gt; are productive (it's just React!)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Designers&lt;/strong&gt;' brand guidelines and design systems are protected&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editors&lt;/strong&gt; work visually and confidently&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now—AI enters the scene.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI-Powered Visual Headless CMS
&lt;/h2&gt;

&lt;p&gt;In May 2025, during the &lt;a href="https://www.boye-co.com/blog/2025/5/react-bricks-wins-european-cms-idol-25" rel="noopener noreferrer"&gt;European CMS Idol competition in Frankfurt&lt;/a&gt;, I presented a preview of an AI-powered full-page generation feature of React Bricks—an approach that helped secure first place in the contest.&lt;/p&gt;

&lt;p&gt;From an AI perspective, a visual headless CMS provides exactly the missing context.&lt;/p&gt;

&lt;p&gt;AI now has access to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;UI awareness&lt;/strong&gt; — the AI can understand the React-based design system, enriched with semantic metadata (what are hero sections, CTAs, FAQs, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Page context&lt;/strong&gt; — the page is a first-class entity, with its current structure and content fully known&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This enables a powerful, multi-pass generation pipeline:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Plan the page structure&lt;/strong&gt; by selecting appropriate bricks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Generate text&lt;/strong&gt; for each block with the correct tone and intent
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose images&lt;/strong&gt; from the DAM or copyright-safe external sources &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Select icons&lt;/strong&gt; from the design system's approved collections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set allowed visual properties&lt;/strong&gt; (layout, background, spacing)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result is high-quality, on-brand, contextual content that fully respects the design system.&lt;/p&gt;

&lt;p&gt;The output remains &lt;strong&gt;structured content&lt;/strong&gt;, which editors can refine visually at any time.&lt;/p&gt;




&lt;h2&gt;
  
  
  In Search of Common Ground
&lt;/h2&gt;

&lt;p&gt;Let’s revisit the three qualities of a good common ground.&lt;/p&gt;

&lt;p&gt;The bricks (the visually editable React components) are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Visible&lt;/strong&gt;: editors see the brick's visual interface; AI sees the component schema and properties&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Understandable&lt;/strong&gt;: both humans and AI understand the semantics of components and properties (either inline editable texts and images or values set via sidebar controls)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Editable&lt;/strong&gt;: both can edit the content (visually or via structured JSON) without increasing the information entropy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What began as a very good common ground between developers and editors, naturally extends to AI.&lt;/p&gt;

&lt;p&gt;If you layer MCPs, SEO automation, keyword-driven content generation on top of this foundation, entirely new workflows become possible.&lt;/p&gt;




&lt;h2&gt;
  
  
  AI vs CMS: Who Wins?
&lt;/h2&gt;

&lt;p&gt;Using AI to directly code a complex enterprise website is no smarter than letting customers edit HTML with FrontPage—or even a modern visual site builder.&lt;/p&gt;

&lt;p&gt;Corporate websites require far more than raw content generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Brand and design system safeguards
&lt;/li&gt;
&lt;li&gt;Roles and permissions
&lt;/li&gt;
&lt;li&gt;Editorial workflows and approvals
&lt;/li&gt;
&lt;li&gt;Scheduling and version history
&lt;/li&gt;
&lt;li&gt;Backups and audit trails
&lt;/li&gt;
&lt;li&gt;Internationalization
&lt;/li&gt;
&lt;li&gt;Integrations with external systems
&lt;/li&gt;
&lt;li&gt;Enterprise-grade security
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;AI cannot replace a CMS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI should operate &lt;em&gt;inside&lt;/em&gt; a CMS.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And for AI to generate full pages—not just fragments—it needs a CMS that understands pages, components, and design systems.&lt;/p&gt;

&lt;p&gt;That CMS is a &lt;strong&gt;Visual Headless CMS&lt;/strong&gt;, lightly coupled to the frontend through a shared design system: Lego bricks for content.&lt;/p&gt;

&lt;p&gt;A true common ground for developers, designers, editors—and AI.&lt;/p&gt;




&lt;h2&gt;
  
  
  The AI-Only Sweet Spot
&lt;/h2&gt;

&lt;p&gt;It’s important to acknowledge that &lt;strong&gt;there are scenarios where AI-only content generation is a good solution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a small startup with a team of two or three developers, no dedicated marketing team, and a simple website, using AI to generate and maintain the website directly in code can be an excellent choice. In this case, speed matters more than governance and long-term content scalability.&lt;/p&gt;

&lt;p&gt;It is the same class of use cases where visual site builders like Webflow or Framer work well: few abstractions, fast iteration, minimal overhead.&lt;/p&gt;

&lt;p&gt;The key point is not that AI-only is wrong—it’s that it is optimal for a very specific organizational shape. &lt;strong&gt;As soon as content becomes a shared responsibility&lt;/strong&gt; across marketers, designers, and developers, and as soon as &lt;strong&gt;brand consistency, approval workflows, and scale&lt;/strong&gt; start to matter, the limitations of the AI-only approach quickly surface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;CMSs are not going away.&lt;/p&gt;

&lt;p&gt;Modern websites require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI
&lt;/li&gt;
&lt;li&gt;CMS
&lt;/li&gt;
&lt;li&gt;Modern frontend frameworks &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But more than that, they require &lt;strong&gt;alignment&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Alignment between humans and AI. Between structure and flexibility. Between speed and control.&lt;/p&gt;

&lt;p&gt;The real question is not “CMS vs AI?” but &lt;strong&gt;“Where is the common ground where AI can safely and effectively operate?”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If your CMS cannot understand pages, components, and design intent, AI will always be constrained to generating fragments. If it can, AI becomes a true collaborator.&lt;/p&gt;

&lt;p&gt;The future of content is not raw prompts writing raw code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It is structured creativity, powered by AI, grounded in design systems, and expressed through Lego bricks for content.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’re building for teams—not just for demos—that’s the battle worth winning.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>webdev</category>
      <category>architecture</category>
      <category>contentwriting</category>
    </item>
    <item>
      <title>Common Ground: A Framework for Human-AI Collaboration</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Tue, 04 Mar 2025 19:54:27 +0000</pubDate>
      <link>https://dev.to/matfrana/common-ground-a-framework-for-human-ai-collaboration-516l</link>
      <guid>https://dev.to/matfrana/common-ground-a-framework-for-human-ai-collaboration-516l</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Recently I've been thinking about how AI, developers, and end users can efficiently collaborate in content management.&lt;/p&gt;

&lt;p&gt;At the same time, Matt Biilmann, CEO of Netlify, who &lt;a href="https://biilmann.blog/articles/introducing-ax/" rel="noopener noreferrer"&gt;introduced the term AX&lt;/a&gt; (Agent Experience), wrote about &lt;a href="https://biilmann.blog/articles/ax-creativity-and-the-human-web/" rel="noopener noreferrer"&gt;AX, Creativity and the Human Web&lt;/a&gt;. I frequently find myself aligned with Matt's vision. In this case too, I strongly agree with his perspective that we must find a balance between automation and human creativity, ensuring AI can enhance—rather than constrain—human expression.&lt;/p&gt;

&lt;p&gt;I believe that true creativity can only emerge from genuine collaboration between humans and AI. Creativity is an iterative process grounded in a medium: think of a painter sketching on canvas or a composer playing notes on a piano and transcribing them to a music score. This is why I believe humans should not only provide abstract feedback to AI, but also be able to directly modify the creative work in progress. &lt;/p&gt;

&lt;p&gt;To address this need, this article introduces the concept of "common ground."&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Ground
&lt;/h2&gt;

&lt;p&gt;Common Ground is a shared medium, such as a file, text, canvas, or interactive interface, where multiple parties can collaborate as peers on intellectual work. It serves as a shared format or interface enabling effective cooperation between humans, and between humans and AI.&lt;/p&gt;

&lt;h3&gt;
  
  
  Good Common Ground Examples
&lt;/h3&gt;

&lt;p&gt;When considering effective human-AI collaboration, two examples spring to my mind: software development and copywriting.&lt;/p&gt;

&lt;p&gt;In software development, &lt;strong&gt;code&lt;/strong&gt; serves as an excellent common ground, as both developers and AI can understand and iteratively modify it.&lt;/p&gt;

&lt;p&gt;In copywriting, the &lt;strong&gt;text&lt;/strong&gt; itself acts as the common ground, allowing both content editors and AI to read and directly refine the work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bad Common Ground Examples
&lt;/h3&gt;

&lt;p&gt;When AI produces output in formats that humans cannot easily modify, the collaboration becomes less effective and ultimately constrains human creativity. &lt;/p&gt;

&lt;p&gt;Imagine if AI always produced &lt;strong&gt;low-level assembly code&lt;/strong&gt;, or highly optimized but unreadable code without comments. The collaboration would become a one-way process: after AI creates the code, only AI could modify it. Developers would be limited to providing prompts and crossing their fingers. No common ground → no true collaboration.&lt;/p&gt;

&lt;p&gt;Consider &lt;strong&gt;AI-generated music&lt;/strong&gt; (as a "composer myself, I'll set aside my reservations about AI-generated music): while AI can create perfectly mixed instrumental and vocal tracks, humans cannot directly modify them.&lt;/p&gt;

&lt;p&gt;The same applies to &lt;strong&gt;images and video&lt;/strong&gt;: humans can only provide feedback and eventually settle for the results, even when the outcome differs from their original vision. This happens simply because they cannot make further improvements through prompts, and the absence of common ground prevents them from directly "sketching" their ideas.&lt;/p&gt;

&lt;h2&gt;
  
  
  Characteristics of Effective Common Ground
&lt;/h2&gt;

&lt;p&gt;Finding a good common ground is straightforward in some cases, but challenging in others. When multiple approaches exist, we should aim for the one that offers the most effective common ground. A big LLM can work easily with unstructured output and refine it, but &lt;strong&gt;human brain’s neural network needs to work on structured schemas.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For AI-generated music, a &lt;strong&gt;musical score&lt;/strong&gt; would serve as a better common ground than audio tracks. This would enable humans to directly edit harmony, melody, and lyrics and quickly test their changes, with fully mixed tracks generated only as a final step (and even for this step, it would be better to have the raw tracks as well so that compression or effects could be tweaked by a human).&lt;/p&gt;

&lt;p&gt;Another example: now that AI can generate entire full-stack applications, I propose that an AI-driven data-intensive app generator should establish common ground through an &lt;strong&gt;augmented database structure&lt;/strong&gt;. This structure would include metadata for each field, indicating whether it should appear in list or detail views, what type of editing control works best, relevant permission rules, and so on. This approach would enable developers to easily modify properties without wading through AI-generated code or relying trial-and-error prompting for simple changes.&lt;/p&gt;

&lt;p&gt;These examples demonstrate that an effective common ground between AI and humans is typically a well-structured format—such as a JSON file, programming code, or a musical score. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A structured common ground has two advantages&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;It makes complex problems more manageable for humans&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It provides a set of good constraints for AI&lt;/strong&gt;, so that the output stays predictable and manageable&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As a former jazz player, I'd like to make a parallel to improvisation: when you play a jazz standard, you have a well-defined structure—the sequence of chords and their harmonic function. When you improvise over this chord structure, you follow certain rules and use specific scales for each chord. This doesn't limit your freedom; quite the opposite, it provides helpful rails and a framework to express creativity. Moreover, the shared chord structure provides all band members with a solid common ground for creating music together. Within this framework, they can listen to each other and collaboratively create something new.&lt;/p&gt;

&lt;p&gt;This is true for art in general: good rules provide guidance, and artists need to know them even when they intend to break them. &lt;strong&gt;Good constraints don't limit creativity—they help it flourish.&lt;/strong&gt; Try this simple test: invent a line of poetry. Difficult, isn't it? Now, invent a line of poetry with the word "key". Your brain immediately starts working, right?&lt;/p&gt;

&lt;p&gt;By providing a framework within which both humans and AI can work, we create space for innovation while maintaining coherence and consistency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;The concept of Common Ground offers a valuable framework for understanding and improving human-AI collaboration. As AI becomes increasingly integrated into creative work, establishing effective shared mediums will be essential for a truly collaborative process.&lt;/p&gt;

&lt;p&gt;The most effective collaborations occur when both parties work within a well-structured format that balances flexibility with constraints.&lt;/p&gt;

&lt;p&gt;Structured formats like a component’s interface, a well-defined JSON object, or musical notation provide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clear syntax and rules that both humans and AI can understand&lt;/li&gt;
&lt;li&gt;The right level of flexibility for creative expression&lt;/li&gt;
&lt;li&gt;A schema that make complex problems manageable&lt;/li&gt;
&lt;li&gt;Good constraints leading to predictable output that supports iterative refinement&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As we design tools and workflows for human-AI collaboration, &lt;strong&gt;we should prioritize creating robust, structured common grounds that amplify human creativity rather than constrain it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In a forthcoming article, I'll explore how these Common Ground principles apply specifically to content management systems, examining which approaches provide the most effective collaboration environment for developers, content editors, and AI.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>productivity</category>
      <category>programming</category>
      <category>discuss</category>
    </item>
    <item>
      <title>The Mystery of Tailwind Colors (v4)</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Thu, 20 Feb 2025 19:07:56 +0000</pubDate>
      <link>https://dev.to/matfrana/the-mystery-of-tailwind-colors-v4-hjh</link>
      <guid>https://dev.to/matfrana/the-mystery-of-tailwind-colors-v4-hjh</guid>
      <description>&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;This article explores how Tailwind CSS v4 has adopted OKLCH color notation and why this change is significant for web developers and designers. You'll discover the fundamentals of color spaces, learn why OKLCH offers better color manipulation than HSL, and understand how to replicate Tailwind's color system for your own custom colors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Tailwind CSS &lt;a href="https://tailwindcss.com/blog/tailwindcss-v4" rel="noopener noreferrer"&gt;recently released v4&lt;/a&gt; with several new features. A key change is that &lt;strong&gt;colors are now defined using OKLCH notation&lt;/strong&gt;, such as &lt;code&gt;oklch(0.685 0.169 237.323)&lt;/code&gt;. I had never encountered this color notation before and I saw that it enabled more vivid colors. My nerd curiosity kicked in, leading me to explore high-gamut color spaces and discover why OKLCH notation is better than HSL.&lt;/p&gt;

&lt;p&gt;During this time, I also needed to create custom colors for a Tailwind CSS project. This presented the perfect opportunity for learning and some late-night hacking sessions. The result was &lt;a href="https://www.uihue.com" rel="noopener noreferrer"&gt;uihue.com&lt;/a&gt;. In this article, I'll share what I learned and explain the algorithm I developed to generate color hues.&lt;/p&gt;

&lt;h2&gt;
  
  
  A bit of Color Theory
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://www.w3.org/TR/css-color-4" rel="noopener noreferrer"&gt;CSS color module level 4&lt;/a&gt; specification introduces new syntax for expressing colors in the standard sRGB color space with &lt;code&gt;rgb(…)&lt;/code&gt; or &lt;code&gt;hsl(…)&lt;/code&gt;. The modern syntax separates color components with &lt;strong&gt;spaces&lt;/strong&gt; instead of commas, uses a &lt;strong&gt;slash&lt;/strong&gt; for the optional alpha value, and allows mixing &lt;strong&gt;percentages&lt;/strong&gt; with numbers. For example, &lt;code&gt;rgba(255, 0, 0, 0.5)&lt;/code&gt; becomes &lt;code&gt;rgba(100% 0% 0% / 50%)&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;More significantly, this specification introduces &lt;strong&gt;new ways to define colors&lt;/strong&gt; using different color spaces. But what exactly is a color space?&lt;/p&gt;

&lt;h3&gt;
  
  
  Understanding Color Spaces: how we see and define colors
&lt;/h3&gt;

&lt;p&gt;Let's start with what a color is. A &lt;strong&gt;color&lt;/strong&gt; is our visual perception of matter based on its electromagnetic spectrum (the amount of light at each visible frequency that travels from an object to our eyes). For objects that don't emit light, color depends on the spectrum of the light hitting them and how they absorb and reflect it. For objects that do emit light, we must also consider their emission spectrum—how much light they emit at each visible frequency.&lt;/p&gt;

&lt;p&gt;The CSS specification defines color as "a definition (numeric or textual) of the human visual perception of a light or a physical object illuminated with light." For the specification's purposes, what matters is &lt;strong&gt;how a color can be expressed as a string or number&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;In this regard, the specification defines a &lt;strong&gt;color space&lt;/strong&gt; as "an organization of colors with respect to an underlying colorimetric model, such that there is a clear, objectively measurable meaning for any color in that color space." A single color can be expressed in different color spaces, though some colors may only be represented in certain color spaces.&lt;/p&gt;

&lt;h3&gt;
  
  
  Color Gamut: from sRGB to Modern Display Standards
&lt;/h3&gt;

&lt;p&gt;No display can reproduce all the colors that the human eye can perceive. The range of colors a display can produce is called a "&lt;strong&gt;gamut&lt;/strong&gt;." Most modern displays show colors in the "sRGB" color space's gamut, which covers about 35% of all human-visible colors. These colors can be expressed using the &lt;code&gt;rgb(…)&lt;/code&gt; or hex notation (e.g. &lt;code&gt;#f65a8e&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Modern devices, particularly Apple computers and phones, can display a broader range of colors—usually more saturated ones. This capability requires new color spaces and notation forms to express these wider gamuts.&lt;/p&gt;

&lt;p&gt;Color spaces, arranged from smallest to largest gamut, are: &lt;strong&gt;sRGB&lt;/strong&gt; ⇒ &lt;strong&gt;Display&lt;/strong&gt; &lt;strong&gt;P3&lt;/strong&gt; ⇒ Adobe RGB 98 ⇒ &lt;strong&gt;REC.2020&lt;/strong&gt; ⇒ ProPhoto RGB. Current Apple devices can usually display colors up to the REC.2020 color space gamut.&lt;/p&gt;

&lt;h3&gt;
  
  
  Color Space Components and Notation
&lt;/h3&gt;

&lt;p&gt;Colors in a CSS color space notation are represented as a list of &lt;strong&gt;color components&lt;/strong&gt; (also called "channels") that represent components along the &lt;strong&gt;axes in the color space&lt;/strong&gt;. Each channel has a minimum and maximum value, and any color with values outside these ranges is considered &lt;strong&gt;invalid&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;
  Note about Alpha
  &lt;p&gt;We won't discuss the additional alpha component, which controls transparency, as it can be considered a post-processing operation that blends a color with whatever is beneath it. &lt;/p&gt;

&lt;/p&gt;

&lt;h4&gt;
  
  
  Examples of color notations:
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rgb()&lt;/code&gt; defines colors in the sRGB color space using &lt;strong&gt;red, green, and blue&lt;/strong&gt; channels&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;hsl()&lt;/code&gt; defines colors in the sRGB color space using &lt;strong&gt;hue, saturation, and lightness&lt;/strong&gt; in the HSL cylindrical coordinate model&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;CSS level 4 introduces additional color notations: &lt;code&gt;hwb&lt;/code&gt; for sRGB, &lt;code&gt;lab&lt;/code&gt; and &lt;code&gt;lch&lt;/code&gt; for CIELAB, and &lt;code&gt;oklab&lt;/code&gt; and &lt;code&gt;oklch&lt;/code&gt; for Oklab, along with a general &lt;code&gt;color&lt;/code&gt; function for various color spaces. &lt;/p&gt;

&lt;p&gt;In this article, we'll focus on &lt;strong&gt;oklch&lt;/strong&gt;—the most relevant option and the one Tailwind v4 uses for its predefined colors. We won't delve into technical topics like the differences between CIE Lab and Oklab color spaces or cartesian versus cylindrical coordinates.&lt;/p&gt;

&lt;h2&gt;
  
  
  OKLCH: A Better Way to Express Color
&lt;/h2&gt;

&lt;p&gt;The OKLCH color notation is based on the Oklab color space, designed to enhance perceptual uniformity, hue and lightness prediction, and color blending. It was &lt;a href="https://bottosson.github.io/posts/oklab/" rel="noopener noreferrer"&gt;introduced by Björn Ottosson&lt;/a&gt; in December 2020. OKLCH represents colors using cylindrical coordinates in the Oklab color space.&lt;/p&gt;

&lt;p&gt;Here are the three key aspects of the OKLCH notation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It allows colors to be expressed in the P3 or REC.2020 gamut&lt;/strong&gt;—colors beyond what &lt;code&gt;rgb()&lt;/code&gt;, &lt;code&gt;hsl()&lt;/code&gt;, or hex formats can represent. This future-proof notation can even define colors that current devices cannot yet display.&lt;/li&gt;
&lt;li&gt;Its coordinates are:

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;L (Perceived Lightness)&lt;/strong&gt;: ranges from 0 to 1, or 0% to 100%&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;C (Chroma, or saturation)&lt;/strong&gt;: ranges from 0 to infinity (but it always stays below 0.37 in the P3 color space)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;H (Hue)&lt;/strong&gt;: ranges from 0 to 360 degrees&lt;/li&gt;
&lt;/ol&gt;


&lt;/li&gt;

&lt;li&gt;It uses &lt;strong&gt;perception-based lightness and saturation&lt;/strong&gt;, solving major perceptual issues found in HSL notation and enabling easier color manipulation (see next section)&lt;/li&gt;

&lt;/ol&gt;

&lt;h3&gt;
  
  
  HSL's Perceptual Limitations
&lt;/h3&gt;

&lt;p&gt;Let's explore the two major perceptual limitations of HSL and the sRGB color space.&lt;/p&gt;

&lt;h4&gt;
  
  
  Variable Maximum Saturation
&lt;/h4&gt;

&lt;p&gt;In HSL, the maximum saturation remains constant across all hues. However, in reality, maximum saturation varies depending on both hue and lightness—this applies to both displays and the human eye.&lt;/p&gt;

&lt;p&gt;I recommend checking out the excellent OKLCH color picker at &lt;a href="https://oklch.com" rel="noopener noreferrer"&gt;oklch.com&lt;/a&gt;. Be sure to enable the "Show 3D" switch (because who doesn't love going full nerd?) to view the 3D model of the color space. At the "base" of these "color mountains" you'll find a Hue/Lightness diagram with zero Chroma (showing only grays), while the mountains' heights represent the maximum Chroma available across different hues and lightness levels.&lt;/p&gt;

&lt;p&gt;You can see from these two images of the 3D OKLCH color space (from &lt;a href="https://oklch.com" rel="noopener noreferrer"&gt;oklch.com&lt;/a&gt;) how greens have a higher maximum chroma compared to yellows and how blue reaches its highest chroma at low lightness levels.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxmqqgu0a7fkhrt6z20b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbxmqqgu0a7fkhrt6z20b.png" alt="Oklch color space 3D" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Non-Uniform Lightness in HSL
&lt;/h4&gt;

&lt;p&gt;A critical issue with HSL is that its lightness values don't align with human visual perception across different hues. Two colors can have the same HSL lightness value yet appear completely different in brightness to our eyes.&lt;/p&gt;

&lt;p&gt;The Oklch notation in the Oklab color space solves this problem by ensuring that identical lightness values create the same perceived brightness.&lt;/p&gt;

&lt;p&gt;The example below illustrates this difference: colors with the same HSL lightness can look dramatically different in brightness. However, when we change only the hue in Oklch while keeping the lightness constant, all colors appear equally bright.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3dohbmdpp9xn8uq7tow.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp3dohbmdpp9xn8uq7tow.png" alt="HSL non-uniform lightness issue" width="800" height="401"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  OKLCH in Practice: Three Game-Changing Benefits
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Better Color Manipulation
&lt;/h4&gt;

&lt;p&gt;As we saw, OKLCH ensures that Lightness and Chroma values are perceptually consistent across all hues. This enables &lt;strong&gt;better mathematical color manipulation&lt;/strong&gt;. When you need a specific lightness level to ensure sufficient contrast with white text, OKLCH provides reliable results, unlike HSL. This makes color adjustment functions like darken/lighten more reliable.&lt;/p&gt;

&lt;h4&gt;
  
  
  Better Color Gradients
&lt;/h4&gt;

&lt;p&gt;While HSL gradients tend to create unwanted gray areas when colors mix, OKLCH's perceptually uniform model produces smooth, visually balanced gradient transitions.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtex5pnnp5nyu9fnniw3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvtex5pnnp5nyu9fnniw3.png" alt="OKLCH better color gradients" width="800" height="283"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Wider Gamut
&lt;/h4&gt;

&lt;p&gt;OKLCH lets us express and use colors with a higher gamut, producing more vibrant, eye-catching designs that modern devices can display. While the image on the left appears more saturated, it has been converted to sRGB due to Dev.to's image processing, but it still illustrates the concept.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9yv7zq5lw7divqc91al.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd9yv7zq5lw7divqc91al.png" alt="OKLCH Wider Gamut P3 REC.2020" width="800" height="176"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Browser Compatibility and Fallback Strategy
&lt;/h3&gt;

&lt;p&gt;With all these advantages of OKLCH in mind, you might wonder about browser support. The good news is that as of early 2025, OKLCH enjoys full support across all major modern browsers. And when colors fall outside a display's gamut, browsers automatically handle the conversion to a supported gamut.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Decoding Tailwind's Color Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Do you know how many color types (different hues) Tailwind includes? You might guess 10 or 12? Maybe 15?&lt;/p&gt;

&lt;p&gt;Actually, there are 22! They are: Red, Orange, Amber, Yellow, Lime, Green, Emerald, Teal, Cyan, Sky, Blue, Indigo, Violet, Purple, Fuchsia, Pink, Rose, Slate, Gray, Zinc, Neutral, and Stone—plus black and white, making it 24 in total.&lt;/p&gt;

&lt;p&gt;Each of these color types has a palette of 11 different shades (50, 100, 200, 300, 400, 500, 600, 700, 800, 900, 950). The 50 shade represents the lightest color, while 950 represents the darkest.&lt;/p&gt;

&lt;p&gt;Before Tailwind v4, these colors were defined in the sRGB color space using HSL or HEX format. With Tailwind v4, colors are now defined using the OKLCH format in the Oklab color space. This change allowed Tailwind expert designers to choose colors outside the sRGB gamut—in fact, you will find some more saturated colors that exist only in the P3 gamut.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonxm59bii16icmitkmtv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fonxm59bii16icmitkmtv.png" alt="Tailwind v4 Sky color palette with some P3 colors" width="800" height="87"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Anatomy of a Tailwind Color Palette&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You might expect the hue and saturation to remain constant across the whole palette, and the lightness to decrease linearly from 50 to 950—especially since the Oklab model is perceptually uniform, right?&lt;/p&gt;

&lt;p&gt;I am sorry to disappoint you: all these assumptions are wrong. You can see the charts for all the new Tailwind colors, showing how lightness, chroma, and hue change across different shades, here: &lt;a href="https://www.uihue.com/tailwind-colors-charts" rel="noopener noreferrer"&gt;https://www.uihue.com/tailwind-colors-charts&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here are three examples:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f72iksg7z0lzjm31dlq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6f72iksg7z0lzjm31dlq.png" alt="Tailwind colors' palettes LCH charts lightness chroma hue" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As you can see, none of these diagrams follows a linear pattern. I stumbled upon this surprising discovery while trying to replicate Tailwind's palette-building approach for custom color palettes.&lt;/p&gt;

&lt;p&gt;Don't worry though—let's try to break down the underlying patterns.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lightness
&lt;/h4&gt;

&lt;p&gt;The Lightness follows a non-linear curve that remains fairly consistent across color palettes, though grays show a steeper decrease in the darker shades.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chroma
&lt;/h4&gt;

&lt;p&gt;The chroma (saturation) follows a Gaussian curve pattern, peaking between the "400" and "600" shades, with a sharper decrease in the lighter shades (toward the left side).&lt;/p&gt;

&lt;h4&gt;
  
  
  Hue
&lt;/h4&gt;

&lt;p&gt;In the charts, hue values have been normalized by subtracting the minimum hue value. Without this normalization, hues near 0° (like reds) would show larger min-max differences than higher hues (like violet). This normalization allows you to better compare hue variations across the entire spectrum.&lt;/p&gt;

&lt;p&gt;Looking at &lt;a href="https://www.uihue.com/tailwind-colors-charts" rel="noopener noreferrer"&gt;all the charts&lt;/a&gt;, you'll notice that hue remains fairly consistent across different shades, with two notable exceptions: yellows shift toward orange in darker shades, and blues shift toward violet in darker shades.&lt;/p&gt;

&lt;h3&gt;
  
  
  From Analysis to Algorithm: Recreating Tailwind's Colors
&lt;/h3&gt;

&lt;p&gt;My mathematical mind's first instinct was to derive three &lt;strong&gt;average curves&lt;/strong&gt;—for lightness, chroma, and hue—across all colors (maybe with separate rules for colors and grays). I planned to use a Fourier transform to approximate these curves and create a clean rule for generating new colors.&lt;/p&gt;

&lt;p&gt;However, this approach wouldn't work. I wanted to achieve the highest possible fidelity in replicating Tailwind colors, but averaging would have flattened the subtle hue differences that make each palette special. I would have lost crucial nuances, like how yellows become more orange when darker, or how azure shifts toward blue-violet. Then a much simpler idea struck me.&lt;/p&gt;

&lt;p&gt;I could simply identify the nearest Tailwind color for any given input color and apply the same rules that Tailwind uses for that nearest color. So, the first step was to find the nearest Tailwind color to the user's chosen color.&lt;/p&gt;

&lt;h4&gt;
  
  
  Finding the Nearest Color
&lt;/h4&gt;

&lt;p&gt;Given a collection of colors and a target color, how do we determine which color in the collection is closest to our target? Simple: we test each color, measure the distance, and choose the one with the minimum distance. But this raises another question: how do we define the &lt;a href="https://en.wikipedia.org/wiki/Color_difference" rel="noopener noreferrer"&gt;distance between two colors&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;The simplest approach uses &lt;a href="https://en.wikipedia.org/wiki/Euclidean_distance" rel="noopener noreferrer"&gt;Euclidean distance&lt;/a&gt; across the N axes of the color representation (essentially applying the Pythagorean theorem in N dimensions). In the sRGB color space, for example, we could calculate the Euclidean distance using the R, G, and B axes:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="katex-element"&gt;
  &lt;span class="katex-display"&gt;&lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;distance=(R2−R1)2+(G2−G1)2+(B2−B1)2
distance = \sqrt{(R_2-R_1)^2 + (G_2-G_1)^2 + (B_2-B_1)^2}
&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord mathnormal"&gt;d&lt;/span&gt;&lt;span class="mord mathnormal"&gt;i&lt;/span&gt;&lt;span class="mord mathnormal"&gt;s&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mord mathnormal"&gt;an&lt;/span&gt;&lt;span class="mord mathnormal"&gt;ce&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mrel"&gt;=&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord sqrt"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span class="svg-align"&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;R&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;G&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;+&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;−&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;1&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose"&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;2&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="hide-tail"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;


&lt;p&gt;Unfortunately, this distance calculation isn't very effective. Consider the example in the following image: blue and violet have a greater Euclidean distance than yellow and orange, even though they appear much more similar to our eyes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsqz2dq6342gp42ly9kv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwsqz2dq6342gp42ly9kv.png" alt="Color difference with euclidean distance on sRGB" width="800" height="309"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we switch to a perceptually uniform color space, such as Lab, the Euclidean distance becomes much more reliable.&lt;/p&gt;

&lt;p&gt;I then learned about a family of algorithms called "DeltaE" (&lt;a href="https://en.wikipedia.org/wiki/Color_difference#CIELAB_%CE%94E*" rel="noopener noreferrer"&gt;DeltaE&lt;/a&gt;) (ΔE), specifically designed to calculate the difference between two colors. The first version, the CIE 1976 formula, simply used the Euclidean distance of colors in the Lab color space. However, when Lab proved less perceptually uniform than initially thought, the algorithm went through several revisions in &lt;a href="https://en.wikipedia.org/wiki/Color_difference#CMC_l:c_(1984)" rel="noopener noreferrer"&gt;1984&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Color_difference#CIE94" rel="noopener noreferrer"&gt;1994&lt;/a&gt;, and finally &lt;a href="https://en.wikipedia.org/wiki/Color_difference#CIEDE2000" rel="noopener noreferrer"&gt;2000&lt;/a&gt;—resulting in the most accurate, though most complex, Lab-based DeltaE algorithm to date.&lt;/p&gt;

&lt;p&gt;I used the DeltaE 2000 algorithm implementation from the &lt;a href="https://colorjs.io" rel="noopener noreferrer"&gt;Colorjs.io&lt;/a&gt; library to iterate through the Tailwind CSS colors and find the nearest match. I'm also interested in testing a simpler Euclidean distance calculation in a more advanced color space like &lt;a href="https://www.color.org/events/prague/MuhammadSafdar2017.pdf" rel="noopener noreferrer"&gt;JzCzhz&lt;/a&gt;.&lt;/p&gt;

&lt;h4&gt;
  
  
  Generating Color Palettes: The Algorithm
&lt;/h4&gt;

&lt;p&gt;Now that we have the nearest Tailwind color (let's say it's "sky-700"), we can proceed with generating a complete palette.&lt;/p&gt;

&lt;p&gt;The user's selected color becomes the "700" shade in the palette—our "base shade." From there, we need to generate both lighter and darker shades.&lt;/p&gt;

&lt;p&gt;A simple approach would be to take the hue of the user's selected color and apply the same lightness and chroma values from the nearest Tailwind color for each shade.&lt;/p&gt;

&lt;p&gt;However, this would cause us to lose the unique characteristics of the user's color, for example lower saturation or slightly lower lightness compared to the Tailwind color. &lt;/p&gt;

&lt;p&gt;Simply applying Tailwind's lightness and chroma deltas from the base shade seemed promising, but this approach could produce completely desaturated colors at the extreme ends of the palette.&lt;/p&gt;

&lt;p&gt;Instead, I applied these deltas with a smoothing effect as we approach the extreme light and dark hues. This preserves the color's distinctive features where they matter most—in the middle shades—while ensuring balanced results for the lightest and darkest shades.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2aoblnrc2s5ln55ghp4o.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2aoblnrc2s5ln55ghp4o.png" alt="Generate Tailwind-like color palettes" width="800" height="238"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Name that Color!
&lt;/h2&gt;

&lt;p&gt;As developers, we know naming things is one of the hardest tasks. When I needed to give each user's color pick in uihue a beautiful name, I faced quite a challenge.&lt;/p&gt;

&lt;p&gt;Initially, I considered using the standard &lt;a href="https://en.wikipedia.org/wiki/Web_colors#Extended_colors" rel="noopener noreferrer"&gt;HTML 4.01 named colors&lt;/a&gt; like "red," "lime," "aliceblue," or "papayawhip." But with only 148 named colors available, this wouldn't provide enough unique names for the vast spectrum of possible colors.&lt;/p&gt;

&lt;p&gt;I then found &lt;a href="https://www.npmjs.com/package/color-name-list" rel="noopener noreferrer"&gt;a massive list&lt;/a&gt; containing over 30k colors. However, calculating 30k color distances for each color pick would be unnecessarily resource-intensive. Instead, I settled on using &lt;a href="https://chir.ag/projects/ntc/" rel="noopener noreferrer"&gt;NTC colors&lt;/a&gt;—a collection of 1,566 names that provides enough variety to find beautiful color names without excessive CPU usage.&lt;/p&gt;

&lt;h2&gt;
  
  
  User-Friendly OKLCH Color Selection
&lt;/h2&gt;

&lt;p&gt;As far as I know, there's just one dedicated color picker for the OKLCH color space: the excellent tool at &lt;a href="https://oklch.com" rel="noopener noreferrer"&gt;oklch.com&lt;/a&gt;. While it's really great and features the neat 3D representation of the color space, this kind of interface might intimidate users who aren't familiar with how OKLCH works.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdmriak1hi4bgk9h8vid.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frdmriak1hi4bgk9h8vid.png" alt="OKLCH Color Picker from oklch.com" width="800" height="460"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead, I decided to implement a standard HSL color picker in the sRGB color space, convert the color to OKLCH, and then let users increase the chroma with a simple slider. The interface clearly shows when colors enter higher gamuts like P3 or REC2020.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faigxbtnkbi6vdg681max.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faigxbtnkbi6vdg681max.png" alt="uihue OKLCH color picker with sRGB + chroma adjustment" width="800" height="240"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'm very satisfied with the result: users find it both user-friendly and fun to use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing Accessible Color Contrast
&lt;/h2&gt;

&lt;p&gt;In the &lt;a href="https://www.uihue.com" rel="noopener noreferrer"&gt;uihue.com&lt;/a&gt; app, I display color shade numbers over the colored squares of the generated palette, using either light or dark text.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6wn5e7qqtf5nztf0ctz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff6wn5e7qqtf5nztf0ctz.png" alt="Accessible Color Contrast" width="800" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do I determine which text color provides better contrast against each shade's background? Simple—I measure the contrast ratio for both options and choose the higher one.&lt;/p&gt;

&lt;p&gt;As you might expect, there's science behind this. Several &lt;a href="https://colorjs.io/docs/contrast" rel="noopener noreferrer"&gt;algorithms exist&lt;/a&gt; for calculating contrast between text and background colors, including: &lt;a href="https://en.wikipedia.org/wiki/Contrast_(vision)#Weber_contrast" rel="noopener noreferrer"&gt;Weber contrast&lt;/a&gt;, &lt;a href="https://en.wikipedia.org/wiki/Contrast_(vision)#Michelson_contrast" rel="noopener noreferrer"&gt;Michelson contrast&lt;/a&gt;, &lt;a href="https://github.com/Myndex/SAPC-APCA" rel="noopener noreferrer"&gt;Advanced Perceptual Contrast Algorithm&lt;/a&gt; (APCA), Lightness difference in the CIE Lightness L* space, Delta Phi Star (ΔΦ*), and &lt;a href="https://www.w3.org/TR/WCAG21" rel="noopener noreferrer"&gt;WCAG 2.1&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I chose to implement the APCA algorithm (through the &lt;a href="https://colorjs.io" rel="noopener noreferrer"&gt;Colorjs.io&lt;/a&gt; library), as it offers the best performance and is being considered for inclusion in version 3 of the W3C Web Content Accessibility Guidelines (WCAG).&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this journey through color spaces and Tailwind's color system, we've explored the advantages of OKLCH over traditional color notations, particularly in web development. The transition to OKLCH in Tailwind v4 represents a significant step forward in how we handle colors in modern web design, offering better perceptual uniformity, wider gamut support, and more reliable color manipulations.&lt;/p&gt;

&lt;p&gt;As display capabilities improve, the OKLCH color space will become increasingly important. It enables us to create more vibrant, accessible, and visually appealing designs while maintaining precise control over color relationships and contrast ratios.&lt;/p&gt;

&lt;p&gt;Through the development of &lt;a href="https://www.uihue.com" rel="noopener noreferrer"&gt;uihue.com&lt;/a&gt;, we've seen how understanding color spaces and implementing smart color-matching algorithms can bridge the gap between technical color theory and practical web development needs. The complexity behind Tailwind's carefully crafted color palettes reveals that even seemingly simple color choices involve intricate patterns and thoughtful design decisions.&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.uihue.com/" rel="noopener noreferrer"&gt;uihue: Tailwind CSS v4 Oklch Palette Generator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://oklch.com/" rel="noopener noreferrer"&gt;OKLCH Color Picker &amp;amp; Converter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/TR/css-color-4/" rel="noopener noreferrer"&gt;CSS Color Module Level 4&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bottosson.github.io/posts/oklab/" rel="noopener noreferrer"&gt;Björn Ottosson - A perceptual color space for image processing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://evilmartians.com/chronicles/oklch-in-css-why-quit-rgb-hsl" rel="noopener noreferrer"&gt;Evil Martians - OKLCH in CSS: why we moved from RGB and HSL&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>frontend</category>
      <category>tailwindcss</category>
    </item>
    <item>
      <title>The WordPress, WP Engine and ACF Drama</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Mon, 14 Oct 2024 21:46:02 +0000</pubDate>
      <link>https://dev.to/matfrana/the-wordpress-wp-engine-and-acf-drama-5h88</link>
      <guid>https://dev.to/matfrana/the-wordpress-wp-engine-and-acf-drama-5h88</guid>
      <description>&lt;p&gt;In this article, I aim to provide a clear explanation of the ongoing situation involving WordPress, WP Engine, and more recently, the ACF plugin. I want to emphasize that I'm not affiliated with any of the parties involved. Text enclosed in double quotation marks or block quotes is directly quoted from the original source.&lt;/p&gt;

&lt;p&gt;As a web developer since 1996, I've witnessed WordPress's early days and used it for some time. Now, I find myself saddened and disappointed by the recent events. That's why I've chosen to present a &lt;strong&gt;comprehensive account of the facts to date&lt;/strong&gt;, followed by a brief personal reflection at the end.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Actors involved
&lt;/h1&gt;

&lt;h2&gt;
  
  
  1. WordPress
&lt;/h2&gt;

&lt;p&gt;You're likely familiar with WordPress, as it is one of the most popular platforms for building websites, &lt;strong&gt;powering more than 40% of sites on the Internet&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;WordPress began as an open-source PHP project launched in 2003 by &lt;a href="https://en.wikipedia.org/wiki/Matt_Mullenweg" rel="noopener noreferrer"&gt;Matt Mullenweg&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Mike_Little" rel="noopener noreferrer"&gt;Mike Little&lt;/a&gt;. Initially a blogging platform, it evolved into a more versatile Content Management System (CMS) with a powerful themes and plugins system. By 2011, it had become the most popular CMS worldwide.&lt;/p&gt;

&lt;p&gt;As an open-source PHP project, &lt;strong&gt;WordPress can be self-hosted&lt;/strong&gt; on any server with PHP and MySQL available. The official website for the open-source project is &lt;a href="http://WordPress.org" rel="noopener noreferrer"&gt;WordPress.org&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. WP Engine
&lt;/h2&gt;

&lt;p&gt;Hosting companies can offer plans with WordPress pre-installed. One of these companies is Automattic, owned by Matt Mullenweg (one of WordPress's original founders), which provides hosted WordPress services through &lt;a href="http://WordPress.com" rel="noopener noreferrer"&gt;WordPress.com&lt;/a&gt; (note the difference from the &lt;a href="http://WordPress.org" rel="noopener noreferrer"&gt;WordPress.org&lt;/a&gt; domain of the open-source platform). &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WP Engine is another company providing WordPress hosting services&lt;/strong&gt;. They claim to be the #1 platform for WordPress. Indeed, they're a significant player in the industry, with an annual revenue of around half a billion dollars. In 2018, WP Engine secured a $250 million investment from &lt;a href="https://www.silverlake.com/" rel="noopener noreferrer"&gt;Silver Lake&lt;/a&gt;, a global private equity firm specializing in technology investments.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. ACF
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.advancedcustomfields.com/" rel="noopener noreferrer"&gt;Advanced Custom Fields (ACF)&lt;/a&gt; is a &lt;strong&gt;very popular WordPress plugin&lt;/strong&gt;. Created by &lt;a href="https://www.elliotcondon.com/" rel="noopener noreferrer"&gt;Elliot Condon&lt;/a&gt; and later acquired by &lt;a href="https://deliciousbrains.com/" rel="noopener noreferrer"&gt;Delicious Brains&lt;/a&gt; in June 2021, &lt;strong&gt;ACF simplifies the management of structured data on WordPress pages&lt;/strong&gt;. It allows developers to create custom field sets through an intuitive interface and retrieve their values in PHP code. Content editors can then populate these fields using the familiar WordPress admin interface.&lt;/p&gt;

&lt;p&gt;ACF comes in two versions: a free version and a premium "Pro" version. The Pro version unlocks additional features, including the Repeater field, the Flexible Content field, and the Gallery field.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In June 2022, WP Engine acquired Advanced Custom Fields (ACF)&lt;/strong&gt; along with the other WordPress plugins from Delicious Brains.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Battle Unfolds: A Three-Act Drama
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Act 1: The WordCamp Showdown
&lt;/h2&gt;

&lt;p&gt;On September 20th, during &lt;strong&gt;WordCamp US 2024&lt;/strong&gt; in Portland, Oregon, Matt Mullenweg spoke about Silverlake, the company behind WP Engine.&lt;br&gt;
&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/fnI-QcVSwMU"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;He claimed that Silverlake contributes to WordPress for 47 hours per week (decreasing to 40), while Automattic contributes 3,786 hours weekly. Mullenweg asserted that Silverlake "doesn't give a dang about your open source ideals, it just wants return on capital." &lt;/p&gt;

&lt;p&gt;He then posed a provocative question to the audience: "Who are you giving your money to: someone who is going to nourish the ecosystem or someone who is going to frack every bit of value out of it until it withers?".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The talk was followed, on September 21st, by a &lt;a href="https://wordpress.org/news/2024/09/wp-engine/" rel="noopener noreferrer"&gt;post&lt;/a&gt; by Matt Mullenweg&lt;/strong&gt; titled "&lt;a href="https://wordpress.org/news/2024/09/wp-engine/" rel="noopener noreferrer"&gt;WP Engine is not WordPress&lt;/a&gt;" where he claims that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;WP Engine is causing confusion with the "WordPress" trademark&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;WP Engine generates half a billion dollars in revenue from WordPress hosting, yet only &lt;strong&gt;contributes back just 40 hours per week&lt;/strong&gt; to the community;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;WP Engine disables content revisions&lt;/strong&gt; by default to reduce storage costs. Mullenweg writes: “They are strip-mining the WordPress ecosystem, giving our users a crappier experience so they can make more money”. And after, “&lt;strong&gt;they are a cancer to WordPress&lt;/strong&gt;, and it’s important to remember that unchecked, cancer will spread”.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Act 2: WP Engine's Response
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;In response, on September 23, 2024, WP Engine sent a &lt;a href="https://wpengine.com/wp-content/uploads/2024/09/Cease-and-Desist-Letter-to-Automattic-and-Request-to-Preserve-Documents-Sent.pdf" rel="noopener noreferrer"&gt;"Cease and Desist" letter&lt;/a&gt; to Automattic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The litigation counsel for WP Engine made startling claims in this document. &lt;/p&gt;

&lt;p&gt;They alleged that:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;In the days leading up to Mr. Mullenweg's September 20th keynote&lt;/strong&gt; address at the WordCamp US Convention, &lt;strong&gt;Automattic suddenly began demanding that WP Engine pay Automattic large sums of money&lt;/strong&gt;, and if it didn't, Automattic would wage a war against WP Engine.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Furthermore, they asserted that during the conference, Mullenweg sent text messages to WP Engine's CEO and board members, "&lt;strong&gt;threatening that if WP Engine did not agree to pay up prior to the start of Mr. Mullenweg's livestreamed keynote address at 3:45pm on September 20, he would go 'nuclear' on WP Engine&lt;/strong&gt;."&lt;/p&gt;

&lt;p&gt;All these alleged messages can be found on pages 3 and 4 of the &lt;a href="https://wpengine.com/wp-content/uploads/2024/09/Cease-and-Desist-Letter-to-Automattic-and-Request-to-Preserve-Documents-Sent.pdf" rel="noopener noreferrer"&gt;document&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 3: Automattic's Countermove
&lt;/h2&gt;

&lt;p&gt;The day after, on September 24, 2024, &lt;strong&gt;Automattic sent their own &lt;a href="https://automattic.com/2024/wp-engine-cease-and-desist.pdf" rel="noopener noreferrer"&gt;”Cease and Desist” letter&lt;/a&gt; indicating that WP Engine’s hosting services “improperly use our Client’s WORDPRESS and WOOCOMMERCE trademarks in their marketing”.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;In this context, the "Client" refers collectively to Automattic, Inc. and WooCommerce, Inc. &lt;br&gt;
While the "WordPress" trademark registration is owned by The WordPress Foundation (a charitable organization), Automattic holds the exclusive commercial rights to use, enforce, and sublicense it. &lt;/p&gt;

&lt;p&gt;In the Cease and Desist letter, Automattic's lawyers demand that WP Engine stops all allegedly unauthorized use of the WordPress trademark and pay compensation for "unauthorized use of their intellectual property and unfair competition". The letter states that the specific amount will be determined once WP Engine provides an accounting as requested. It then adds, "even a mere 8% royalty on WP Engine's $400+ million in annual revenue equates to more than $32 million in annual lost licensing revenue for our Client".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The WordPress Foundation also revised its &lt;a href="https://wordpressfoundation.org/trademark-policy/" rel="noopener noreferrer"&gt;Trademark Policy page&lt;/a&gt;, specifically changing the section about "WP" and addressing "WP Engine" directly:&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The abbreviation “WP” is not covered by the WordPress trademarks, but please don’t use it in a way that confuses people. For example, many people think WP Engine is “WordPress Engine” and officially associated with WordPress, which it’s not. They have never once even donated to the WordPress Foundation, despite making billions of revenue on top of WordPress.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just a few days before, the same page contained a more permissive statement regarding the use of the abbreviation "WP":&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The abbreviation “WP” is not covered by the WordPress trademarks and you are free to use it in any way you see fit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For those interested in the legal aspects, you can also read the &lt;a href="https://wpengine.com/wp-content/uploads/2024/10/Complaint-WP-Engine-v-Automattic-et-al-with-Exhibit.pdf" rel="noopener noreferrer"&gt;official lawsuit&lt;/a&gt; filed by WP Engine on October 2, 2024.&lt;/p&gt;

&lt;h1&gt;
  
  
  The Escalation: A Dramatic Three-Act Sequel
&lt;/h1&gt;

&lt;p&gt;Until this point, the conflict had been limited to words, spoken or written, and many WordPress developers were still unaware of the situation, but events were about to take a dramatic turn.&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 1 - The Great Block
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On September 25&lt;/strong&gt;, Matt Mullenweg escalated the issue by publishing a new post on WordPress.org titled &lt;strong&gt;"&lt;a href="https://wordpress.org/news/2024/09/wp-engine-banned/" rel="noopener noreferrer"&gt;WP Engine is banned from WordPress.org&lt;/a&gt;"&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The opening sentence was: "Any WP Engine customers having trouble with their sites should contact WP Engine support and ask them to fix it". This would be quite hilarious if it weren't so alarming: how could WP Engine possibly fix a block that WordPress.org intentionally implemented to restrict WP Engine's customers?&lt;/p&gt;

&lt;p&gt;The post continued:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;WP Engine wants to control your WordPress experience, they need to run their own user login system, update servers, plugin directory, theme directory, […]. Their servers can no longer access our servers for free.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Following this announcement, WordPress.org took action by &lt;strong&gt;blocking WP Engine's customers from accessing its resources, particularly&lt;/strong&gt; &lt;strong&gt;the marketplace that enables updating and installing plugins and themes&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This ban effectively prevented WP Engine customers from accessing security updates, too&lt;/strong&gt;, leaving their websites vulnerable to potential threats.&lt;/p&gt;

&lt;p&gt;Of course, the community didn’t appreciate this. Consider also that even public administration websites could potentially be left vulnerable, unable to update their plugins or access important security updates. This marked the moment when I, along with many other developers, became  aware of the unfolding "WordPress drama".&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 2 - The On-Again, Off-Again Ban
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The ban was lifted on September 27&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On September 30&lt;/strong&gt;, WP Engine updated its website footer to explicitly state its lack of affiliation with the WordPress Foundation. The revised footer now clarifies that their use of the WordPress, Woo, and WooCommerce names is solely for identification purposes and does not imply endorsement by either the WordPress Foundation or WooCommerce, Inc.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On October 1&lt;/strong&gt;, WP Engine &lt;a href="https://x.com/wpengine/status/1840910240801316924" rel="noopener noreferrer"&gt;announced&lt;/a&gt; they had implemented their own solution to enable plugin and theme updates and installations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The same day, the ban was reinstated&lt;/strong&gt;. As of this writing, it remains in effect.&lt;/p&gt;

&lt;h2&gt;
  
  
  Act 3 - The Checkbox
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;On October 8&lt;/strong&gt;, David Heinemeier Hansson (aka "DHH", creator of Ruby on Rails and co-founder of 37signals) wrote an article titled &lt;a href="https://world.hey.com/dhh/automattic-is-doing-open-source-dirty-b95cf128" rel="noopener noreferrer"&gt;&lt;strong&gt;"Automattic is doing open source dirty"&lt;/strong&gt;&lt;/a&gt;. In it, he argues that "Automattic demanding 8% of WP Engine's revenues because they're not 'giving back enough' to WordPress is a wanton violation of general open source ideals and the specifics of &lt;a href="https://www.gnu.org/licenses/old-licenses/gpl-2.0.en.html" rel="noopener noreferrer"&gt;the GPL license&lt;/a&gt;".&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The same day, WordPress.org added a new checkbox to their contributors' login page, requiring people to declare they have no association with WP Engine.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When I first saw a screenshot of this, I thought it was a joke. It wasn't.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62g5vw8hqsmhxd6nghj4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F62g5vw8hqsmhxd6nghj4.png" alt="WordPress Login WP Engine checkbox" width="800" height="589"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image credits: WordPress.org&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Last-minute update (October 14)&lt;/strong&gt;: Just as I was about to hit publish, Matt Mullenweg responded to DHH's post. I'll refrain from summarizing or commenting on it: &lt;a href="https://ma.tt/2024/10/on-dhh/" rel="noopener noreferrer"&gt;Read it yourself&lt;/a&gt; 😳&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Matt has since removed the post. To provide a glimpse of its content, I'll share a couple of key sentences:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;DHH claims to be an expert on open source, but his toxic personality and inability to scale teams means that although he has invented about half a trillion dollars worth of good ideas, most of the value has been captured by others&lt;/p&gt;

&lt;p&gt;David, perhaps it would be good to explore with a therapist or coach why you keep having these great ideas but cannot scale them beyond a handful of niche customers. I will give full credit and respect. 37signals inspired tons of what Automattic does! We’re now half a billion in revenue. Why are you still so small?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Things get worse with ACF
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;On October 12, &lt;a href="http://WordPress.org" rel="noopener noreferrer"&gt;WordPress.org&lt;/a&gt; &lt;a href="https://x.com/wp_acf/status/1845169499064107049" rel="noopener noreferrer"&gt;took over the Advanced Custom Fields (ACF) plugin&lt;/a&gt;&lt;/strong&gt;. What does this mean? WordPress forked ACF—one of the most popular WordPress plugins—&lt;strong&gt;renamed it "Secure Custom Fields," and published it under ACF's original slug&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgimo51istxxan2pg5ysc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgimo51istxxan2pg5ysc.png" alt="Advanced Custom Fields replaced by Secure Custom Fields" width="800" height="474"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Image credits: WordPress.org&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;You can verify this yourself at &lt;a href="https://wordpress.org/plugins/advanced-custom-fields/" rel="noopener noreferrer"&gt;https://wordpress.org/plugins/advanced-custom-fields/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The page appears identical, but now it displays "Secure Custom Fields by WordPress.org" instead of "Advanced Custom Fields". &lt;strong&gt;This means they've inherited ACF's 2M+ download count and high ratings. More critically, users with ACF installed will automatically update to the "new" Secure Custom Fields plugin.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The Advanced Custom Fields team &lt;a href="https://x.com/wp_acf/status/1845169499064107049" rel="noopener noreferrer"&gt;stated on X&lt;/a&gt; "A plugin under active development has never been unilaterally and forcibly taken away from its creator &lt;strong&gt;without consent&lt;/strong&gt; in the 21-year history of WordPress."&lt;/p&gt;

&lt;p&gt;To draw a hypothetical parallel, imagine if Microsoft were to fork an &lt;a href="https://www.npmjs.com/" rel="noopener noreferrer"&gt;npm&lt;/a&gt; package and publish their fork under the same name, effectively wresting control from the original publisher, with no clear justification. Wouldn’t it be scary?&lt;/p&gt;

&lt;h1&gt;
  
  
  Personal Reflections
&lt;/h1&gt;

&lt;p&gt;We've moved on from WordPress and are no longer a digital agency—as you'll read in the next section. So you might think I'd feel "safe" from all this WordPress drama. Instead, I'm deeply concerned about these unfolding events as they are creating ripples of uncertainty across the entire development ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a hosting company&lt;/strong&gt;, I'd be concerned about offering WordPress hosting services. I might face challenges in advertising them—especially considering the WordPress Foundation's trademark applications for "managed WordPress" and "hosted WordPress"—or feel compelled to remain small to avoid drawing Automattic's attention. See the &lt;a href="https://tsdr.uspto.gov/#caseNumber=98646183&amp;amp;caseSearchType=US_APPLICATION&amp;amp;caseType=DEFAULT&amp;amp;searchType=statusSearch" rel="noopener noreferrer"&gt;Managed WordPress trademark application&lt;/a&gt; and &lt;a href="https://tsdr.uspto.gov/#caseNumber=98646185&amp;amp;caseSearchType=US_APPLICATION&amp;amp;caseType=DEFAULT&amp;amp;searchType=statusSearch" rel="noopener noreferrer"&gt;Hosted WordPress trademark application&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a plugin development company&lt;/strong&gt;, I'd be concerned that if my plugin becomes successful, WordPress might take control of it, eliminating the possibility of a viable freemium model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a WordPress developer&lt;/strong&gt;, I'd worry that my chosen hosting platform could inadvertently infringe on trademarks, preventing me from providing timely updates to my clients.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;As a corporation with a WordPress website&lt;/strong&gt;, I'd be anxious about potential inability to access security updates or having plugins whose development slows down or stops entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For the open source community at large&lt;/strong&gt;, I feel a widespread unease about the WordPress ecosystem's current state. Open source is wonderful, but there's often a company behind these projects that might make decisions contrary to the community's wishes. While open source licenses like MIT or GPL have stood the test of time, murky areas around trademarks or contribution requirements could be discouraging. Typically, a contract with a company offers more explicit guidelines about what's allowed and what's not.&lt;/p&gt;

&lt;p&gt;Although I'm not directly involved as a hosting company, WordPress or plugin developer, or a corporation using WordPress, these recent events have left me feeling somewhat uneasy about the broader implications for the tech ecosystem.&lt;/p&gt;

&lt;h1&gt;
  
  
  My Journey with WordPress
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;I began developing websites in 1996&lt;/strong&gt; at the age of 17, using my Pentium 120 with Windows 95. In 2004, while still in university, I launched my own company—I was a happy "webmaster"!&lt;/p&gt;

&lt;p&gt;As a digital agency, we primarily created complex web applications and custom e-commerce systems (initially in ASP.NET, then Node.js and React). But occasionally, clients requested websites too, and &lt;strong&gt;WordPress became our go-to choice&lt;/strong&gt;, because of its ready-made content administration. Advanced Custom Fields became our ally. It helped us overcome the challenges of a blank canvas—where clients might unleash the horrors of green text on red backgrounds in Comic Sans—by providing a more structured and clean WordPress experience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;By leveraging ACF and the ability to fetch data from REST APIs, we could create a self-hosted headless CMS&lt;/strong&gt;. We paired this with modern React frontend frameworks like Next.js or Gatsby, offering a solid solution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;However, we eventually realized that the gray forms of ACF or a pure headless CMS weren't delivering the optimal user experience for our clients&lt;/strong&gt;. This realization led us to develop &lt;a href="https://www.reactbricks.com/" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;, a visual headless CMS based on React, transforming us from a service-based agency into a product company. But that's a tale for another time :)&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>wpengine</category>
      <category>acf</category>
      <category>drama</category>
    </item>
    <item>
      <title>What is a Universal CMS?</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Thu, 10 Oct 2024 13:33:23 +0000</pubDate>
      <link>https://dev.to/matfrana/what-is-a-universal-cms-28n4</link>
      <guid>https://dev.to/matfrana/what-is-a-universal-cms-28n4</guid>
      <description>&lt;h1&gt;
  
  
  1. Definition
&lt;/h1&gt;

&lt;p&gt;A "universal CMS" is a headless CMS that sacrifices a small degree of "purity" (in terms of complete backend-frontend decoupling) to provide a much better content editing experience. This improvement is primarily achieved through inline visual editing.&lt;/p&gt;

&lt;p&gt;The term "Universal CMS" first appeared in Preston So's March 2024 article, "&lt;a href="https://preston.so/writing/universal-cms-the-death-of-pure-headless-cms/" rel="noopener noreferrer"&gt;Universal CMS: The death of pure headless CMS.&lt;/a&gt;" However, this concept mirrors the vision of a new CMS type I proposed in my article &lt;strong&gt;"&lt;a href="https://dev.to/matfrana/the-shape-of-the-cms-to-come-4i2e"&gt;The shape of the CMS to come&lt;/a&gt;", published on Dev.to in January 2020&lt;/strong&gt;. As the CEO of &lt;a href="https://www.reactbricks.com/" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;, I introduced this idea alongside our initial MVP release. We subsequently launched the platform's first official version in March 2020, which can be considered as the first universal CMS ever released.&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Types of CMS
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fob43yvj7v37b73ajyqrn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fob43yvj7v37b73ajyqrn.png" alt="Univeral CMS - Types of CMS" width="800" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Before delving into the need for Universal CMSs, let's explore the main types of content management systems available today.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.1 Monolithic CMS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A monolithic CMS integrates content storage, management interface, and presentation layer into a single software package&lt;/strong&gt;. Consider a traditional WordPress website as an example. It uses PHP files within the same project for both the content administration interface (which writes to the database) and the template files (which generate HTML from the database content).&lt;/p&gt;

&lt;h2&gt;
  
  
  2.2 Headless CMS
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;A headless CMS, in contrast, manages only the backend—content storage and management&lt;/strong&gt; &lt;strong&gt;and&lt;/strong&gt; &lt;strong&gt;exposes content through HTTP APIs&lt;/strong&gt; (typically REST or GraphQL). &lt;/p&gt;

&lt;p&gt;A decoupled frontend web application, which can be built using any modern frontend framework, can consume these APIs. Headless CMSs also allow easy serving of multiple channels, all consuming the same JSON content.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.3 Hybrid CMS
&lt;/h2&gt;

&lt;p&gt;Hybrid CMSs are monolithic CMSs' response to the multichannel capabilities of headless CMSs. Essentially, &lt;strong&gt;monolithic CMSs added HTTP APIs&lt;/strong&gt; to allow external web or mobile applications to access their content, while maintaining the web frontend coupled within the CMS.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.4 Website Builders
&lt;/h2&gt;

&lt;p&gt;Website builders, such as Wix or Webflow, are typically &lt;strong&gt;hosted SaaS services that allow content editors to visually edit content&lt;/strong&gt;. While they may have a decoupled internal structure, end users experience them as a &lt;strong&gt;unified solution&lt;/strong&gt; where content is edited, stored, and served. These platforms often provide APIs as well, making them similar to hybrid CMSs—they offer a tightly coupled web content management solution with APIs for third-party use.&lt;/p&gt;

&lt;h2&gt;
  
  
  2.5 Universal CMS
&lt;/h2&gt;

&lt;p&gt;A Universal CMS offers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A decoupled backend&lt;/strong&gt; service for content storage, accessible through APIs&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A library or SDK for frontend code, enabling visual editing of content&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We'll explore how Universal CMSs work in more detail later in this article.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. The need for a Universal CMS
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9kw1ym1ynm5fgaeft8gi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9kw1ym1ynm5fgaeft8gi.png" alt="Universal CMS vs Headless CMS vs Site Builder" width="800" height="349"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  3.1 The problem
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3.1.1 Monolithic CMS
&lt;/h3&gt;

&lt;p&gt;Monolithic CMSs are falling out of favor today for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;They don't support modern frontend frameworks&lt;/strong&gt;, making them unappealing to web developers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They lack multi-channel&lt;/strong&gt; content distribution capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They require self-hosting&lt;/strong&gt;, burdening developers. Moreover, their coupled infrastructure prevents independent scaling of backend and frontend.&lt;/li&gt;
&lt;li&gt;They often rely heavily on &lt;strong&gt;third-party plugins&lt;/strong&gt;, raising concerns about stability and security.&lt;/li&gt;
&lt;li&gt;Their &lt;strong&gt;user interface&lt;/strong&gt; is limited—often appearing outdated and lacking customization options.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  3.1.2 Hybrid CMS
&lt;/h3&gt;

&lt;p&gt;Adding APIs to a monolith—which leads to a hybrid CMS, doesn’t solve the problems highlighted above, but for the multichannel capability.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1.3 Headless CMS
&lt;/h3&gt;

&lt;p&gt;This is why in the past decade we witnessed the rise of headless CMSs. Headless CMSs are an excellent solution for developers. However, since they're decoupled from the frontend, &lt;strong&gt;their editing interface consists of aseptic gray forms&lt;/strong&gt;, losing the visual editing capabilities that monolithic CMSs offered. In this transition, &lt;strong&gt;content editors were left behind&lt;/strong&gt;, as their editing experience significantly deteriorated. Some headless CMSs offer a "preview" feature, allowing users to see a page almost immediately after editing content. However, the editing process still takes place in gray forms, making the content editor's experience far from truly visual.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1.4 A bit of history
&lt;/h3&gt;

&lt;p&gt;Throughout the history of content management, we've repeatedly encountered a &lt;strong&gt;dichotomy&lt;/strong&gt; &lt;strong&gt;between visual&lt;/strong&gt; &lt;strong&gt;editing layers&lt;/strong&gt; (great for content editors but not developers) &lt;strong&gt;and structured data&lt;/strong&gt; (great for developers but not content editors). &lt;/p&gt;

&lt;p&gt;We saw this with early visual tools like Microsoft &lt;strong&gt;FrontPage&lt;/strong&gt;, which gave content editors too much power, leading to a return to structured content with &lt;strong&gt;CGI&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;We witnessed it again with full-fledged monolithic CMSs like &lt;strong&gt;WordPress&lt;/strong&gt;, where editors could either have a blank canvas—potentially resulting in Comic Sans green text on a red background—or be restricted by the austerity of ACF gray forms.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1.5 Visual Site Builders
&lt;/h3&gt;

&lt;p&gt;This pattern persists today. &lt;/p&gt;

&lt;p&gt;Visual website builders like Wix or Webflow are very easy to use, but &lt;strong&gt;they lack the flexibility developers need&lt;/strong&gt; to create pixel-perfect corporate designs. At the same time, paradoxically, &lt;strong&gt;they give content editors too much freedom&lt;/strong&gt;, allowing them to make design choices that may compromise brand consistency—a deal-breaker for corporate clients. &lt;/p&gt;

&lt;p&gt;On the other hand, headless CMSs, as mentioned earlier, present content editors with austere, user-unfriendly gray forms, prioritizing developer experience at the expense of user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  3.2 Requirements for a new solution
&lt;/h2&gt;

&lt;p&gt;This is why we need to finally find a good solution for every actor involved that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Allows developers to use a decoupled architecture&lt;/strong&gt; with a modern frontend framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gives content editors an easy-to-use inline visual editing interface&lt;/strong&gt;, as simple as a word processor&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enables developers to set appropriate constraints&lt;/strong&gt; on what content editors can do, ensuring the corporate identity and design system remain intact&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A Universal CMS is the answer to these requirements.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. How does a Universal CMS work?
&lt;/h1&gt;

&lt;p&gt;In this section, I'll explore how a Universal CMS works, based on the architecture and functioning of &lt;a href="https://www.reactbricks.com/" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;—the Universal CMS built by my team and me. As of October 2024, React Bricks is the only Universal CMS available on the market.&lt;/p&gt;

&lt;h2&gt;
  
  
  4.1 “Lego bricks” of content
&lt;/h2&gt;

&lt;p&gt;Close your eyes and travel back in time to your childhood. Imagine yourself playing with Lego bricks. &lt;strong&gt;You had a limited set of unmodifiable, atomic bricks, yet you could create anything!&lt;/strong&gt; We’ve borrowed this concept, adding a touch of Lego magic to our CMS. Developers can create custom "content bricks" within their preferred modern framework (React-based, in the case of React Bricks), deciding how much freedom to grant content editors. Content Editors then use these bricks to visually compose pages.&lt;/p&gt;

&lt;p&gt;This approach addresses all three requirements mentioned earlier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Developers can leverage modern frameworks like Next.js, Remix or Astro&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content editors enjoy the best possible inline visual editing experience&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Developers set appropriate constraints in the bricks' code, ensuring the corporate identity remains intact&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4.2 Architecture
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmcklhkwq19i6bu65chu6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmcklhkwq19i6bu65chu6.png" alt="Universal CMS Architecture" width="800" height="564"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Developers create their own custom set of "content bricks" in their repository&lt;/strong&gt;, using components from the universal CMS's library to enable visual editing (for example Text, Image, Repeater, etc.). Each brick has a unique name within the design system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The backend APIs are unaware of how content bricks are created in code&lt;/strong&gt; or how they look. They simply store a JSON representation of the content for every page or entity. You can think of the content for each page as an array of blocks, each containing the name of the corresponding brick in code and all the properties edited by content editors. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The library matches the content in the database with the bricks in the code repository, rendering the correct brick and passing it the necessary properties to display the content&lt;/strong&gt;. This happens both in the Admin (content management interface) and in the Page Viewer (used in the frontend pages).&lt;/p&gt;

&lt;h2&gt;
  
  
  4.3 Content Management Interface
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytbehhbk9m10fbqvilpw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fytbehhbk9m10fbqvilpw.png" alt="Universal CMS Content management interface" width="800" height="403"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As illustrated in the architecture diagram, in a Universal CMS like React Bricks &lt;strong&gt;the content management interface resides within the frontend project&lt;/strong&gt;, sharing the same repository as the bricks and frontend pages. This allows customers to host the website and the content management interface on their preferred hosting platform. This approach differs from the typical headless CMSs, which usually provide a hosted content management interface.&lt;/p&gt;

&lt;h1&gt;
  
  
  5. React Bricks
&lt;/h1&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/vled1PA-8uI"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.reactbricks.com/" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt; is the pioneer of Universal CMS, currently leading the market&lt;/strong&gt;. As of October 2024, it serves over 10,000 users worldwide, powering websites for major corporations like The Weather Channel and Deel. Its client base includes major banks in Italy and France, as well as large e-commerce platforms and corporate websites globally.&lt;/p&gt;

&lt;p&gt;In React Bricks, &lt;strong&gt;"content bricks" are implemented as React components&lt;/strong&gt;. Developers can quickly scaffold a complete project using a single CLI command, choosing from popular frameworks like Next.js, Remix, Gatsby, and—in the near future—Astro.&lt;/p&gt;

&lt;p&gt;Within the React component’s JSX, the developer can use the &lt;strong&gt;visual editing components&lt;/strong&gt; of React Bricks, like Text, RichText, Image, Repeater, etc. choosing what can be edited visually, the rich text styles allowed for each text, and providing render functions for each style.&lt;/p&gt;

&lt;p&gt;Moreover, a brick’s component has a &lt;code&gt;schema&lt;/code&gt; property which defines, among other things, &lt;strong&gt;the brick's unique name, default properties and the sidebar controls&lt;/strong&gt;. These controls allow content editors to change component properties as needed.&lt;/p&gt;

&lt;p&gt;React Bricks, currently in version 4, offers &lt;strong&gt;enterprise-grade features&lt;/strong&gt;. These include localization, complete Digital Asset Management (DAM), scheduled publishing, advanced SEO capabilities, approval workflows and Single Sign-On (SSO). The platform also provides granular permissions, seamless integration with external data sources, real-time collaboration tools, content versioning, page templates, and automatic backup of content and assets to the customer's S3 storage.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Conclusion
&lt;/h1&gt;

&lt;p&gt;In the coming years, I anticipate a significant evolution in the CMS landscape. The emergence of Universal CMSs is expected to gain momentum, marking the beginning of a gradual but steady &lt;strong&gt;transition from the headless paradigm towards the more user-friendly “universal” paradigm&lt;/strong&gt;. As developers and content creators alike recognize the benefits of this new approach, we can expect to see increasing adoption across various industries and sectors.&lt;/p&gt;

&lt;p&gt;If you're eager to stay at the forefront of this technological shift and provide your customers with cutting-edge content management solutions, I invite you to explore React Bricks. As a pioneer in the Universal CMS space, &lt;strong&gt;React Bricks offers a unique blend of developer flexibility and content editor ease-of-use&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;To learn more about how React Bricks can revolutionize your content management workflow, visit our website at &lt;a href="https://www.ReactBricks.com" rel="noopener noreferrer"&gt;ReactBricks.com&lt;/a&gt;. Create a free account to experience the power of true visual editing combined with the flexibility of a headless architecture.&lt;/p&gt;

&lt;p&gt;And, of course, let me know your thoughts about universal CMSs!&lt;/p&gt;

</description>
      <category>react</category>
      <category>universalcms</category>
      <category>headlesscms</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>Where do React Server Components fit in the history of web development?</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Fri, 26 Jan 2024 23:07:39 +0000</pubDate>
      <link>https://dev.to/matfrana/where-do-react-server-components-fit-in-the-history-of-web-development-1l0f</link>
      <guid>https://dev.to/matfrana/where-do-react-server-components-fit-in-the-history-of-web-development-1l0f</guid>
      <description>&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;In this article, I explain why React Server Components were introduced, in the light of the history of web applications development. Understanding where we come from is key to understand the challenges we currently face and the specific issues that Server Components aim to address.&lt;/p&gt;

&lt;h2&gt;
  
  
  ASP, PHP, what?
&lt;/h2&gt;

&lt;p&gt;When I began developing websites in 1996, I created static HTML websites. These were just HTML files saved on a web server. When a browser sent a GET request, the web server would return the file, and the browser would parse it and display the page on the screen.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkelmc5b3y69zzivd1eh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwkelmc5b3y69zzivd1eh.gif" alt="Early days websites GET request and HTML response"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then customers started requesting product catalogs or e-commerce systems. To accomplish this, you need a database and the capability to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read from the database and generate HTML pages based on the database content.&lt;/li&gt;
&lt;li&gt;Write data from HTML forms into the database (for example, to update a product or place an order).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In the beginning, I used a technology called &lt;a href="https://en.wikipedia.org/wiki/Common_Gateway_Interface" rel="noopener noreferrer"&gt;CGI&lt;/a&gt; to develop server applications written in &lt;a href="https://www.perl.org/" rel="noopener noreferrer"&gt;Perl&lt;/a&gt;. This technology was later replaced by Microsoft’s &lt;a href="https://en.wikipedia.org/wiki/Active_Server_Pages" rel="noopener noreferrer"&gt;ASP (Active Server Pages)&lt;/a&gt; and then &lt;a href="https://www.php.net/" rel="noopener noreferrer"&gt;PHP&lt;/a&gt;. PHP, which you may already know, is still powering over 77% of all the websites as of the time of writing (ever heard of WordPress?).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk26qq2os0b15ai29buw.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzk26qq2os0b15ai29buw.gif" alt="Website generated based on database query"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Interactivity happened essentially server-side: sending a request to the server and receiving a response. JavaScript was used for small interactions or animations, such as form validation, image change on hover, image carousels, etc.&lt;/p&gt;

&lt;h2&gt;
  
  
  The early days of SPA
&lt;/h2&gt;

&lt;p&gt;With the increase of interactivity on websites and complex web applications, developers began to directly interact with the server from JavaScript using Ajax calls (the golden era of jQuery ;). For example, let's consider a form submitted by JavaScript. In this case, the server should no longer return an HTML page, but rather structured data intended to be read by the JavaScript script (such as just "ok" or "error").&lt;/p&gt;

&lt;p&gt;As these techniques were used more often, a significant shift in paradigm emerged. This shift had a fundamental impact on both the client and server technologies, changing forever the way web applications were built.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Client-side, new frameworks emerged, to simplify the way HTML (the DOM) is updated in response to interactions or data from the server. The imperative approach of jQuery was not suitable for large client applications, so declarative frameworks were introduced to facilitate one-way or two-way data binding between data and DOM elements. I used Knockout.js for some time, then switched to Angular.js, and eventually settled on React.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Server-side, we witnessed the emergence of APIs, which no longer returned HTML pages but structured data. Initially data was XML sent over the SOAP protocol, and later JSON directly over HTTP, taking advantage of the REST architecture.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Applications created in this way are referred to as &lt;a href="https://en.wikipedia.org/wiki/Single-page_application" rel="noopener noreferrer"&gt;Single Page Applications&lt;/a&gt;, or SPAs. &lt;/p&gt;

&lt;p&gt;This is because all paths are served by a single HTML page (e.g. index.html), where a JavaScript client-side router reads the browser location and renders the appropriate page.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxroslz4hz0p4xwbw7z8j.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxroslz4hz0p4xwbw7z8j.gif" alt="Single Page Application"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Initially, Single Page Applications (SPAs) were primarily used for data-intensive web applications that required a login interface, such as the admin interface of an e-commerce or production management system. However, the architecture quickly became appealing for creating websites, as well, for several reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It allows for a clear separation of concerns between backend and frontend roles.&lt;/li&gt;
&lt;li&gt;From a security point of view, the attack surface of APIs is reduced and well-defined.&lt;/li&gt;
&lt;li&gt;When using a Node.js server, the JavaScript language can be used across the entire stack.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Problems of SPAs
&lt;/h2&gt;

&lt;p&gt;Single Page Applications have 2 problems, especially for public websites.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. SEO
&lt;/h3&gt;

&lt;p&gt;As we saw, the web server returns just a skeleton or empty page, and the actual content is loaded by the JavaScript application. If a search engine's web crawler doesn’t execute JavaScript, it will just see an empty page without any content. This is not ideal for achieving a high ranking in search results, right?&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Perceived performance
&lt;/h3&gt;

&lt;p&gt;Before the user can see the page content, the following steps take place:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The HTML page is fetched.&lt;/li&gt;
&lt;li&gt;The JavaScript file of the single-page application is fetched, parsed and executed.&lt;/li&gt;
&lt;li&gt;The SPA requests data from a server and waits for the response.&lt;/li&gt;
&lt;li&gt;The SPA renders the HTML based on the received data.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Meanwhile, the user is presented with a blank page or a spinner. &lt;/p&gt;

&lt;p&gt;This can be problematic, especially in cases where the application is large, resulting in a longer loading time for the JavaScript file, or if the API server is slow to respond.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Rendering to the Rescue
&lt;/h2&gt;

&lt;p&gt;As we saw, Single Page Applications have two issues due to the fact that the page is generated on the client-side using JavaScript executed by the browser, without any content in the HTML sent by the server.&lt;/p&gt;

&lt;p&gt;Server-side rendering is a solution to this problem.&lt;/p&gt;

&lt;p&gt;If you have a server running Node.js, you can execute JavaScript code on the server. In particular, the server can fetch data, run the React code and render the HTML page. This allows users to immediately see the page as soon as it is fetched from the web server and enables search engines to correctly index the content.&lt;/p&gt;

&lt;p&gt;How does it work? Instead of fetching data on the client, each React view (the top component of a route) can declare a static property called, for example, "getData", which is a function that retrieves the necessary data from APIs. &lt;/p&gt;

&lt;p&gt;This function is called on the server side and the result is made available to the top component of the view. In this way the entire tree of components for the route can be rendered on the server using ReactDOMServer.renderToString(). &lt;/p&gt;

&lt;p&gt;I have used this approach before Next.js was created, for an e-commerce system that is still used by over 300 pharmacies in Italy. In Next.js, the equivalent function for “getData” is "getServerSideProps" (or "getStaticProps" for SSG, which will be discussed later).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu61ttou3t55dhomrj33.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftu61ttou3t55dhomrj33.gif" alt="Server-side rendering"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You see the situation is very similar to what happens with a PHP page, but we are missing a piece: hydration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Hydration
&lt;/h2&gt;

&lt;p&gt;What we receive from the server is not just a static HTML page with no JavaScript and no interactivity. After the user receives the server-generated page, it continues to work as a Single Page Application, with client interactivity, client-based routing, and so on. How does this work?&lt;/p&gt;

&lt;p&gt;Well, the script tag that points to the JavaScript bundle of our app is still present in the HTML code. As a result, it gets downloaded and executed by the browser. However, this time, React takes a different approach. After running the entire app and building the virtual DOM for a specific route, instead of directly writing it to the "root" div, React compares it with the server-generated DOM to ensure they are identical (have you ever seen hydration errors?). Then, React attaches the event handlers that enable interactivity to the DOM. This process is known as "hydration," as if the water of interactivity was being poured into the static HTML page.&lt;/p&gt;

&lt;p&gt;If you have a global state manager like Redux (as I did in my e-commerce application) and need to initialize it with the server's status after rendering, from the server code you can inject a script into the HTML page. This script sets a global variable in the window object, where you can store the initial status, serialized as a string. When the app is loaded, it can read this status from the global variable and initialize the client's status (in my example, the Redux store).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eodjt38s9qqjrbbonmu.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7eodjt38s9qqjrbbonmu.gif" alt="Server-side rendering and hydration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  A note about Static Site Generation (SSG)
&lt;/h2&gt;

&lt;p&gt;Static Site Generation (SSG) is similar to server-side rendering (SSR), but instead of happening on the public web server that serves your website, it can occur on any machine running Node.js before publishing each new version of the website.&lt;/p&gt;

&lt;p&gt;Think of it as having a person visit all the pages of your website on your development machine, saving the generated HTML pages, and then sending them via FTP to the actual web server. This web server can now be a “stupid” server or a content delivery network (CDN) that serves static files without the need of running Node.js.&lt;/p&gt;

&lt;p&gt;Typically, the static generation process occurs on a cloud service (such as Netlify or Vercel) connected to your Git repository. Whenever there are code changes in the repository, the cloud service triggers a rebuild and serves the resulting build through a CDN.&lt;/p&gt;

&lt;p&gt;Regardless of whether a page is pre-generated by SSG or generated on the fly by SSR, the client-side hydration process remains the same. From now on, when I mention SSR, I am referring to both SSR and SSG.&lt;/p&gt;

&lt;p&gt;If you want to learn more about SSR vs SSG (and another concept called ISR), please read my article &lt;a href="https://dev.to/matfrana/server-side-rendering-vs-static-site-generation-17nf"&gt;SSR vs SSG vs ISR&lt;/a&gt;. It was written in 2020, but the concepts are still valid.&lt;/p&gt;

&lt;h2&gt;
  
  
  Problems of Server-Side Rendering
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Hydration
&lt;/h3&gt;

&lt;p&gt;Reading the paragraph above about hydration, it is clear that the hydration process can be quite burdensome. It consumes time and resources, increasing the "Time-to-interactive" of your website, which negatively impacts page speed metrics. This is the main issue with Server-Side rendering.&lt;/p&gt;

&lt;p&gt;Furthermore, when considering that the primary use case for SSR is not interactive web applications, but rather websites, it becomes apparent that the entire hydration process is largely unnecessary, since most components are non-interactive.&lt;/p&gt;

&lt;p&gt;After the initial rendering, does a hero unit component really require interactivity or the execution of React code? Not at all, it could simply be plain static HTML!&lt;/p&gt;

&lt;p&gt;Server components were designed to address this problem and eliminate the need for hydration when it is not required.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Useless bundle size on the client
&lt;/h3&gt;

&lt;p&gt;Since many components are not interactive and should never re-render, sending to the browser the JavaScript code for these components is completely useless.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Fetching at component level
&lt;/h3&gt;

&lt;p&gt;Another issue with SSR is that the root component of each route must declare its "getData" function and then make the data accessible to all components in the component tree. This limitation prevents us from fetching data in any component lower down in the tree, as it can only be done at the top level. While we can fetch data using an effect, this would only happen on the client-side, resulting in a loss of the SEO performance advantage provided by SSR.&lt;/p&gt;

&lt;h2&gt;
  
  
  React Server components
&lt;/h2&gt;

&lt;p&gt;Server components are designed to prevent hydration when it is not necessary. &lt;/p&gt;

&lt;p&gt;So, when is hydration necessary? Whenever we have interactions or the need to re-render. For an image carousel, for example, client-side React is required for the animation and user interaction, so the hydration is necessary. &lt;/p&gt;

&lt;p&gt;Server Components are rendered just once, on the server, and they don’t have any  JavaScript code that can be executed on the client. Therefore, we cannot use hooks like useState or useEffect in server components. &lt;/p&gt;

&lt;p&gt;This is why, when adopting Server Components, it is important to determine which components can truly be Server Components and which ones should remain as “Client Components” (our old standard React components) with the client hydration.&lt;/p&gt;

&lt;p&gt;By default, when using a RSC-compatible version of React (currently only available in canary releases), all components are treated as server components. However, if we require client interactivity, we can declare a component as a client component by including the &lt;code&gt;use client&lt;/code&gt; directive at the top of the file.&lt;/p&gt;

&lt;p&gt;Server components will only render on the server, while client components will render on both the server and the client, during the hydration process. The code for server components is not included in the JavaScript bundle, as they will never be hydrated, re-rendered, or have any client interactivity.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi84mtxvoi63v05dnaec.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxi84mtxvoi63v05dnaec.gif" alt="Server components: hydration of client components only"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, we have two advantages that address the first two problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No client hydration work is required for server components.&lt;/li&gt;
&lt;li&gt;The JavaScript bundle size is significantly reduced.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What’s more, we can directly fetch data from APIs in server components. This fetch occurs before the components are rendered server-side. In this way we also solve the third issue we encountered with Server-Side Rendering.&lt;/p&gt;

&lt;p&gt;As of the time I am writing this, the recommended way to use Server Components is through the &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; framework with the &lt;a href="https://nextjs.org/docs" rel="noopener noreferrer"&gt;App Router&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you are searching for a headless CMS solution that supports React Server Components, consider exploring &lt;a href="https://reactbricks.com/" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;, co-founded by me, which recently released v4.2, fully supporting server components. It also provides two Next.js starter projects: one is a blank project, while the other one comes with Tailwind CSS, pre-made content blocks, and a blog.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this post we discussed the problems that React Server Components are addressing in modern web development. We also took a time-machine trip way back in the web development history, to better understand where we come from. I believe that sometimes it’s important to view things from a broader perspective (or maybe it’s because I am getting older? ;).&lt;/p&gt;

&lt;p&gt;Now we understand the benefits of React Server Components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;They eliminate the need for client hydration for non-interactive components that don't require re-rendering.&lt;/li&gt;
&lt;li&gt;They reduce the JavaScript bundle size, as the JavaScript for Server components is not sent to the browser.&lt;/li&gt;
&lt;li&gt;They enable data fetching on the server directly from a single component, rather than just at the route level.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We did not go into the details of how server components are used, the composition rules for server and client components, or the server-only components that use the &lt;code&gt;use server&lt;/code&gt; directive to trigger Server Actions. But that’s material for another article 😊.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>nextjs</category>
      <category>javascript</category>
    </item>
    <item>
      <title>React, where are you going?</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Tue, 16 Jan 2024 19:05:29 +0000</pubDate>
      <link>https://dev.to/matfrana/react-where-are-you-going-5284</link>
      <guid>https://dev.to/matfrana/react-where-are-you-going-5284</guid>
      <description>&lt;p&gt;I'm writing these random notes as an &lt;strong&gt;open letter to the people I deeply trust in the React&lt;/strong&gt; (and more generally, the open-source) &lt;strong&gt;community&lt;/strong&gt;. People like Tanner Linsley, Laurie Voss, Cassidy Williams, Michael Jackson, Mark Erikson, Kyle Mathews, Sophie Alpert and many others.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In the past few months I’ve been feeling conflicted about React&lt;/strong&gt;. It started with the days when server components were essentially announced at a framework conference, and the React documentation began suggesting the use of an external framework for React development. After reading &lt;a href="https://blog.cassidoo.co/post/annoyed-at-react/" rel="noopener noreferrer"&gt;Cassidy's post&lt;/a&gt; last night and sharing her vision, I felt the urge to express my concerns as well.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I fell in love with React in 2016&lt;/strong&gt; when Angular announced Angular 2 and we were worried about the breaking changes. I immediately fell in love with the React community, even though I never actively participated. &lt;/p&gt;

&lt;p&gt;I remember the tweets between Sophie Alpert and Dan Abramov. I also remember the first talk at ReactJsDay (Italy) by Michele Bertoli in 2016, which made my eyes sparkle. And I can't forget the 2018 edition of ReactJsDay when Michael Jackson recreated much of React Router live coding in front of us - those were great days!&lt;/p&gt;

&lt;p&gt;React has been a winning choice for us, both as a web development agency and now as a product company. I still get emotional when I think about the day (I believe it was January 2nd, 2020) when I showed the first MVP of React Bricks to Guillermo Rauch, who was the first to believe in the project and gave me the confidence to go on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;However, today I see two problems that make me enjoy React a little less&lt;/strong&gt; and make me worry that new developers might be intimidated by it: ownership and complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ownership
&lt;/h2&gt;

&lt;p&gt;As for ownership, I don’t particularly like that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;React &lt;a href="https://react.dev/learn/start-a-new-react-project" rel="noopener noreferrer"&gt;suggests using a framework&lt;/a&gt; to start a project, suggesting to use one of the three main open source frameworks, instead of just React.&lt;/li&gt;
&lt;li&gt;During a framework's conference, new React features such as React Server components are introduced to a large part of the community for the first time, as if it was just a framework achievement.&lt;/li&gt;
&lt;li&gt;The most popular framework, which has hired some people from the React core team (which is not a bad thing, but certainly provides them with privileged insight into development) uses canary releases, while the &lt;a href="https://github.com/facebook/react/releases" rel="noopener noreferrer"&gt;last release of React&lt;/a&gt; (18.2) is of June 2022. In this way canary features enter the codebase of many new React projects, becoming the “de facto” stable release, but just for the users of a framework that can feel safe leveraging canary features.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Furthermore, features like Server actions, which trigger metered serverless function calls when hosted on cloud platforms, may potentially increase hosting costs for frontend applications in the future. While this is not currently a problem since there is no monopoly and we have the freedom to choose, &lt;strong&gt;I would like&lt;/strong&gt; a way for the community &lt;strong&gt;to be guaranteed that tomorrow there will still be multiple choices&lt;/strong&gt; available. Please understand that I don't see anyone as being "evil" in this regard. Great things can come from the collaboration between a private company and the community. It's simply a matter of separating concerns and responsibilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complexity
&lt;/h2&gt;

&lt;p&gt;I started creating websites in 1996, when I was 17 years old. At that time, you created HTML files and uploaded them to an FTP server to a folder served by a web server. I managed my own physical server (a Pentium 120), housing it at a local Internet Provider. It ran on Windows NT4 IIS as webserver, BIND for DNS, and IPSwitch IMail server for email. Everything was simple and clear.&lt;/p&gt;

&lt;p&gt;Nowadays, web development has become more powerful, but also much more complex. We have lost touch with what's happening under the hood, with the introduction of transpilers, bundlers, and frameworks. However, React stands out with its clean one-way data flow. Things got a bit more complicated with hooks (which have some behind-the-scenes black magic :), but it was manageable and, in the end, a good choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With Server components, everything is much more complex to grasp&lt;/strong&gt;. And, the fact that they are the default choice in the most widely used React framework, somewhat forces newcomers to also learn this new paradigm. I understand the advantages of RSC, but now we have &lt;a href="https://overreacted.io/the-two-reacts/" rel="noopener noreferrer"&gt;two different ways&lt;/a&gt; of building things even within the same React framework. &lt;/p&gt;

&lt;p&gt;We have recently completed the task of making the &lt;a href="https://reactbricks.com" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt; library compatible with RSC. This required a month of work and thousands of lines of code. However, as a result, the final API for developers is not as clean as before. I am uncertain whether sacrificing simplicity for a slight performance boost will truly benefit our customers. Nevertheless, since it is both the "default" and the shiny new thing, we have to have it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Meanwhile, there are many interesting things happening outside of the React world, with the new frameworks&lt;/strong&gt;. I wouldn't like to be a new programmer trying to choose their first framework right now, as the decision is really tough. React is the most popular, Vue is easier to use, Svelte is a cool idea, Astro is really great, and then there are signals and SolidJS by the very smart and humble Ryan Carniato. Qwik is also very smart, I love the approach (it was created by competitors of React Bricks… but I hold them in high esteem :). So… the choice of a base framework is already so complicated!&lt;/p&gt;

&lt;h2&gt;
  
  
  A dream?
&lt;/h2&gt;

&lt;p&gt;In this complex scenario, &lt;strong&gt;it would be beneficial to have a "default, official" React framework that covers the basic needs of building a SEO-friendly website&lt;/strong&gt;, with routing, SSG, SSR, ISR (and all the permutations of these letters ;). I know the Remix team would not agree on the need for SSG, but I think it has valid use cases. And I would like it to always be self-hostable on a Linux box.&lt;/p&gt;

&lt;p&gt;I envision this default framework being developed by the React community, with a &lt;strong&gt;steering committee consisting of recognized contributors from the React ecosystem (through a voting process?)&lt;/strong&gt;. I know that usually open source doesn't work in this way, but... I dream of this "probi viri Fellowship of the Ring" making decisions.&lt;/p&gt;

&lt;p&gt;This default framework should &lt;strong&gt;not aim to include all the shiny new things&lt;/strong&gt; out there, found in other frameworks like Remix or Next.js, which I use and love. I believe it should serve as a solid starting point created by the community. And I think we have already some great stuff available today to start with (Tanner?). &lt;/p&gt;

&lt;p&gt;As for RSC, I think the concept of avoiding hydration is great, but we need a new kind of server-client integration to make them easy to use. If they remain complex, with the current constraints, trading simplicity for performance would not be beneficial for most websites. And probably RSC is losing in terms of performance compared to something like Qwik, anyway, because they are performing the same work twice, processing chunks from serialized JSON on the client. However, this is material for a separate discussion.&lt;/p&gt;

&lt;h2&gt;
  
  
  Open Questions
&lt;/h2&gt;

&lt;p&gt;So, after this long stream of consciousness, I would like to pose some questions to the community:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;What are your thoughts on the future of React?&lt;/li&gt;
&lt;li&gt;Do you believe it is feasible to have a community-driven framework without a sponsoring company, but with a sort of elected steering committee? How could this independent steering committee be financially supported by the community or corporate users, in order to maintain its independence?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Matteo Frana&lt;br&gt;
Jan 16, 2023&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Visual editing !== No code</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Mon, 29 Nov 2021 15:03:53 +0000</pubDate>
      <link>https://dev.to/matfrana/visual-editing-no-code-2ba9</link>
      <guid>https://dev.to/matfrana/visual-editing-no-code-2ba9</guid>
      <description>&lt;p&gt;&lt;strong&gt;Belief #1&lt;/strong&gt;: I believe that a corporate website should be created with code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Belief #2&lt;/strong&gt;: I believe that a CMS should offer the best experience to its everyday users: content creators. And the best user experience is visual editing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Are these beliefs in contrast?&lt;/strong&gt; Not at all! Follow me.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;h3&gt;
  
  
  If you are a web developer...
&lt;/h3&gt;

&lt;p&gt;...you know it: &lt;strong&gt;every corporate website is unique&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You need total control for pixel-perfect corporate image&lt;/li&gt;
&lt;li&gt;You must be sure nobody will break the design&lt;/li&gt;
&lt;li&gt;You may have ad-hoc interactive features which require a JavaScript framework&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  If you are a content creator...
&lt;/h3&gt;

&lt;p&gt;... you know it: &lt;strong&gt;creating content filling gray forms is boring&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You want to edit visually, like you do in Word or Pages&lt;/li&gt;
&lt;li&gt;You want the freedom to compose your page as you need&lt;/li&gt;
&lt;li&gt;You want to be sure you won't break things&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. No-code tools 🙁
&lt;/h3&gt;

&lt;p&gt;Tools like Wix or Webflow have a great user experience, but they have pitfalls that make them unusable for corporate websites. They are either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Not flexible&lt;/strong&gt;: the tools that are easier to use, usually force you to choose one of the proposed graphic templates. Great for a freelancer project, no-go for a corporate website.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Complex&lt;/strong&gt;: more advanced tools, like WebFlow, are very flexible, but they are more complex to use.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Too flexible&lt;/strong&gt;: what's more, it's not the content creator business to create the design and tweak CSS parameters. For a corporate website, the design system is created by designers and developers: content creators should not have the ability to alter the the design system. We don't want green text on red background, right?&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Headless CMSs 😐
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Headless CMS ⇒ gray forms&lt;/strong&gt; ⇒ not great for content creators.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. React Bricks 😍
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://reactbricks.com" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt; has the &lt;strong&gt;advantages of both&lt;/strong&gt; Headless CMSs and a No-code tools, &lt;strong&gt;without the problems&lt;/strong&gt; that Content creators have with headless CMSs and that Developers have with No-code tools.&lt;/p&gt;

&lt;h4&gt;
  
  
  For Developers
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Developers create content blocks with code&lt;/strong&gt; (they are just React components) using the React Bricks library. &lt;strong&gt;React Bricks adds the visual editing magic.&lt;/strong&gt; And it's really fun.&lt;br&gt;
React Bricks provides also the documentation for your design system.&lt;/p&gt;

&lt;h4&gt;
  
  
  For Content creators
&lt;/h4&gt;

&lt;p&gt;Content creators have a best-in-class visual interface:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;They can edit text and images directly&lt;/strong&gt; as you do in Word or Pages&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;They can change properties&lt;/strong&gt; like background color etc. using sidebar controls. They can change only the properties that the developers chose to be editable and with the values that are allowed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;They have all the freedom they want and no more than they need.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Code and Visual editing can go hand-in-hand: to create a corporate website that's easy and fun to edit in a visual way, you need code.&lt;br&gt;
And a bit of magic. &lt;strong&gt;React Bricks brings the magic.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactbricks.com" rel="noopener noreferrer"&gt;Learn more on the React Bricks website&lt;/a&gt;&lt;/p&gt;

</description>
      <category>cms</category>
      <category>react</category>
      <category>javascript</category>
      <category>nocode</category>
    </item>
    <item>
      <title>Code, No-code and Low-code for Content Management Systems</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Sat, 04 Sep 2021 09:21:02 +0000</pubDate>
      <link>https://dev.to/matfrana/code-no-code-and-low-code-for-content-management-systems-49am</link>
      <guid>https://dev.to/matfrana/code-no-code-and-low-code-for-content-management-systems-49am</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Low-code vs No-code: many articles explain the differences, benefits and drawbacks of the two approaches. In this article I'd like to narrow down the topic to that of content management systems (CMS). I will broaden the use of the term "CMS" to include visual site builders, which are starting to blend in with more traditional tools.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I will focus on how different types of CMS lead to code, no-code or low-code approaches in the front-end development of a website.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We'll start with monolithic CMSs, travel through developer-centric solutions like headless CMSs, look at no-code tools and eventually get a glimpse of the future in a recent new approach.&lt;/p&gt;

&lt;h2&gt;
  
  
  Monolithic CMSs 🗿
&lt;/h2&gt;

&lt;p&gt;A monolithic CMS such as Drupal or WordPress usually leads to a "low code" experience on the front-end, but, depending on how it is used, it can also be a completely "no-code" or full "code" experience.&lt;/p&gt;

&lt;p&gt;I will now use "WordPress" as a synonym for monolithic CMS, as it is easier to say. Keep in mind that WordPress is a great product and nowadays it can be used also as a headless CMS exposing REST or GraphQL APIs.&lt;/p&gt;

&lt;p&gt;For very simple projects, where you can just set up a website with a pre-made template and you are good to go, WordPress is a &lt;strong&gt;no-code&lt;/strong&gt; tool.&lt;/p&gt;

&lt;p&gt;As soon as you want to change something, WordPress can become a &lt;strong&gt;low-code&lt;/strong&gt; tool, because you can just change some HTML code in the PHP templates and change the CSS files.&lt;/p&gt;

&lt;p&gt;If you create templates from scratch, it is a full "&lt;strong&gt;code&lt;/strong&gt;" solution, because you have to write all of your template files in PHP, using the WordPress framework (the "loop"!).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Monolithic CMSs are flexible, as you can choose how much code to write, based on your needs and your skills.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Usually a developer would like to write code to limit what the content creators could do, to avoid having customers breaking the website, for example placing a table that breaks the responsive layout or creating red text over a green background (the designer says thank you). &lt;/p&gt;

&lt;p&gt;To do so developers create fixed fields that can be used on a page (for example using Advanced Custom Fields), so that content creators end up filling gray forms instead of writing content in a free way.&lt;/p&gt;

&lt;p&gt;Don't get me wrong, content creators don't want to have total freedom and to break the design. They just need to get the job done. And the best way to get the job done is to write content as you do in Pages or Word, which unfortunately is not appropriate for designers, unless you can guarantee that the corporate image remains safe.&lt;/p&gt;

&lt;p&gt;And the fact is that many front-end developers would laugh today reading what I said about developers that want to write code in WordPress. Modern front-end developers don't want to see PHP code at all: they want to leverage a modern stack solution, using a JavaScript framework like React, Vue or Angular.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Monolithic CMSs are still by far the most used kind of CMSs and offer a certain amount of flexibility, but, as we saw, they tend to be always a suboptimal solution for at least one of the involved actors (developers, content creators, designers), based on how they are used.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Luckily today there are tools that are more suitable for web agencies working with modern front-end stacks: read on!&lt;/p&gt;

&lt;h2&gt;
  
  
  Headless CMSs 🤯
&lt;/h2&gt;

&lt;p&gt;With headless CMSs you have the separation of concerns between the back-end (database, APIs, image processing) and the front-end (the website consuming the APIs and rendering the content). &lt;/p&gt;

&lt;p&gt;The backend is usually of no concern because it is provided as a service, so the front-end developers can focus on creating the website using a modern stack, for example using a React framework like Gatsby or Next.js.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Headless CMSs require coding&lt;/strong&gt;: a developer needs to write the code for the front-end website in order to fetch content from the APIs and present it, usually using a JavaScript framework.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Headless CMSs are great for developers&lt;/strong&gt;, because they have total freedom in choosing the framework they prefer without the hassle of creating the APIs and the Admin interface for content editing. And they offer better performance, scalability and security out of the box.&lt;/p&gt;

&lt;p&gt;The problem with headless CMSs is that a core actor in the adoption of the CMS, the Content creator, is not happy with this solution. Why? Because &lt;strong&gt;the content creator loses the visual editing experience&lt;/strong&gt; that he could have with a blank WordPress page (the infamous blank page that horrifies designers and frightens developers).&lt;/p&gt;

&lt;h2&gt;
  
  
  Visual site builders 🏗️
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Visual site builders like Wix or Webflow exhibit a simple point and click interface&lt;/strong&gt; in order to deliver a user experience that is very similar to that of a word processing software like Word or Pages.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Visual site builders are no-code tools and they are great for Content creators with no particular corporate image needs or no developers available.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In particular, tools like Wix address pure Content creators who don't need to change the graphics and are ok with the provided templates, while more advanced tools like Webflow allow the user to change every aspect of the page content. In one case you cannot express your exact corporate image, in the other one the content creator has too much power, like in the blank WordPress page case. &lt;/p&gt;

&lt;p&gt;Either way, content creators may be happy, while designers are not. And developers? They are not really involved in this case (so they are skeptical, I tell you by experience 😉).&lt;/p&gt;

&lt;h2&gt;
  
  
  The missing pieces 📡
&lt;/h2&gt;

&lt;p&gt;Developers usually prefer a "code" solution like a headless CMS while content creators usually prefer a "no-code" solution like Wix. But... &lt;strong&gt;the funny thing is the reason for the like/dislike is not the quantity of code&lt;/strong&gt;, but something else.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Developers prefer a headless CMS over a monolithic CMS &lt;strong&gt;not because they can write more code, but because they can write code in a better way&lt;/strong&gt;, using better tools, with a better architecture.&lt;/p&gt;

&lt;p&gt;Content creators prefer a visual site builder &lt;strong&gt;not because they don't have to code&lt;/strong&gt;: at a corporate level they have developers that can code on their behalf. They prefer a visual site builder &lt;strong&gt;because they can have a visual editing experience&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And designers? Well, they need to be able to express the exact corporate image (so no Wix, sorry) and be sure that nobody will break the corporate image (so no "unleashed" WordPress or WebFlow, sorry, sorry).&lt;/p&gt;

&lt;p&gt;We need something new. Will it be a no-code tool? A full code solution? Read on!&lt;/p&gt;

&lt;h2&gt;
  
  
  A new approach ✨
&lt;/h2&gt;

&lt;p&gt;From what we saw, it seems that full code means the ability to reproduce the exact design system and create constraints so that the editors cannot break the design, using a modern development stack.&lt;/p&gt;

&lt;p&gt;Is this in contrast with visual editing, the great UX that content creators are looking for?&lt;/p&gt;

&lt;p&gt;Well, in a way yes, because &lt;strong&gt;for a single developer or a small team, it is impossible to re-create a complex system like Wix for a corporate website&lt;/strong&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;So what we really need is a development framework that allows developers to create something great like Wix, but with our own corporate design system and constraints, in order to be sure that nobody will be able to (accidentally!) break it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And this framework should be great for modern front-end developers, keeping the advantages of headless CMSs. It should be a front-end library created with a JavaScript framework like React, Vue or Angular, with a decoupled API as a service.&lt;/p&gt;

&lt;p&gt;And what about the "&lt;strong&gt;design system&lt;/strong&gt;" thing? What is it? Let's simplify: &lt;strong&gt;it is a set of content blocks with a designer-designed design that can be used in your content&lt;/strong&gt;. Ok, so we need a way to create content blocks with React (or Vue, or Angular) with visual editing that save content on headless APIs as a service.&lt;/p&gt;

&lt;p&gt;Is it code? No-code? Low-code? Well, at the moment it could be a solution where you have to write code using this library, but the library takes care of many things for you, like calling APIs, wiring the visual editing to your content blocks, rendering on any framework like Next.js or Gatsby, etc. &lt;strong&gt;So we can say such a solution is a low-code one.&lt;/strong&gt; You just write the components, the library does the magic. And clearly the experience for the content creators is completely no-code, a no-code tailor-made for them: no useless power, but comfortable constraints.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it the future or... now? 🛸
&lt;/h2&gt;

&lt;p&gt;Well, it is just now. I know two CMSs that follow this philosophy, Tina and React Bricks, both working with React. Tina works with Next.js, React Bricks works with Next.js and Gatsby. They have a similar idea behind them, but different approaches. &lt;/p&gt;

&lt;p&gt;Tina has an experimental feature for visual editing ("inline editing") while React Bricks has been created from day one around the core concept of visual editing. React Bricks is born to be a one stop shop where content is persisted on APIs as a service and image processing is done by the same APIs, while Tina started as a Git-based CMS and it leverages an external service (Cloudinary) for image processing.&lt;/p&gt;

&lt;p&gt;And... I created React Bricks, with the help of my team.&lt;/p&gt;

&lt;p&gt;Ok ok, so I am biased. I am biased because I believe so strongly in what I say here that I founded a start-up based on this concept. I turned a profitable software house working for customers into a product-centric bootstrapped startup. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;I believe this is the way we can create great user experiences for everybody: content creators, developers and designers. I believe this is the way people will edit websites very soon. And they will have fun. Again.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;BTW, if you want to have a look at React Bricks... 😉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://reactbricks.com" rel="noopener noreferrer"&gt;https://reactbricks.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>nocode</category>
      <category>lowcode</category>
      <category>cms</category>
      <category>react</category>
    </item>
    <item>
      <title>React CMS: The missing link</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Tue, 29 Jun 2021 15:39:18 +0000</pubDate>
      <link>https://dev.to/matfrana/react-cms-the-missing-link-3iok</link>
      <guid>https://dev.to/matfrana/react-cms-the-missing-link-3iok</guid>
      <description>&lt;p&gt;&lt;strong&gt;You are a developer. You love your headless CMS.&lt;/strong&gt; &lt;br&gt;
Having an API with no hassles and a modern front-end feels great.&lt;/p&gt;

&lt;p&gt;Do you think your users are happy too? &lt;strong&gt;Think again.&lt;/strong&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  What content creators want
&lt;/h1&gt;

&lt;p&gt;Content creators want to have a solution that is &lt;strong&gt;easy and inspiring to use&lt;/strong&gt;, possibly with no instruction to read.&lt;br&gt;
Wix is such a tool, with its point and click interface.&lt;br&gt;
&lt;strong&gt;An headless CMS&lt;/strong&gt;, with its gray forms and complex interface, is &lt;strong&gt;neither easy nor inspiring&lt;/strong&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  What about designers?
&lt;/h1&gt;

&lt;p&gt;Designers want to be able to express the &lt;strong&gt;corporate design system&lt;/strong&gt; and be sure that &lt;strong&gt;nobody will ever break it&lt;/strong&gt;.&lt;br&gt;
This is why they don't like visual editing, as it often implies too much freedom. Designers want &lt;strong&gt;flexibility&lt;/strong&gt; (for themselves) and &lt;strong&gt;constraints&lt;/strong&gt; (for content creators).&lt;/p&gt;
&lt;h1&gt;
  
  
  Are you really happy?
&lt;/h1&gt;

&lt;p&gt;Do you like going back and forth between your headless CMS to define fields and your code to fetch these fields and use them in your React app?&lt;br&gt;
&lt;strong&gt;Wouldn't it be great if you could save time, stay in your editor&lt;/strong&gt; and define there your fields, as you do for the &lt;strong&gt;props of React components&lt;/strong&gt;?&lt;/p&gt;
&lt;h1&gt;
  
  
  The missing link
&lt;/h1&gt;

&lt;p&gt;The missing link is a framework that has decoupled APIs as a service, but lets you define your &lt;strong&gt;content blocks as components&lt;/strong&gt; (for example React or Vue components), providing some &lt;em&gt;magic&lt;/em&gt; to enable visual editing over the texts and images. &lt;strong&gt;The props of this components enforce constraints&lt;/strong&gt; so that designers can be sure that nobody will break the design. As a plus, it would be great if the schema of components could &lt;strong&gt;self-document&lt;/strong&gt; itself.&lt;/p&gt;
&lt;h1&gt;
  
  
  I didn't find the missing link...
&lt;/h1&gt;

&lt;p&gt;... so I created it ;P&lt;br&gt;
Its name is &lt;strong&gt;&lt;a href="https://reactbricks.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=missing_link" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  How does it work?
&lt;/h1&gt;
&lt;h2&gt;
  
  
  It’s just React
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Content blocks are React components&lt;/strong&gt;. No back and forth between the front-end and the headless CMS. Define the fields as props on your component, &lt;strong&gt;get visual editing for free&lt;/strong&gt; from React Bricks &lt;code&gt;&amp;lt;Text&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;RichText&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Image&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;Repeater&amp;gt;&lt;/code&gt; components.&lt;br&gt;
Props like background or anything you need can be changed via &lt;strong&gt;sidebar controls&lt;/strong&gt; (you can choose a standard control like text, number, select, color, etc. or provide a custom component).&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/Y0Odt3W6L48"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Great editing experience
&lt;/h2&gt;

&lt;p&gt;The editing interface is very &lt;strong&gt;easy and familiar&lt;/strong&gt; with Visual editing and a Sidebar to change props, with &lt;strong&gt;no way to break the design&lt;/strong&gt;.&lt;br&gt;
In the Playground you get the &lt;strong&gt;documentation&lt;/strong&gt; for all of your content blocks for free.&lt;/p&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/I8eL7HexnmQ"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it flexible enough?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;You can configure everything&lt;/strong&gt;: add custom fields on the page accessible via hooks, provide your own components for rich text rendering or for the sidebar controls, validate props, change ui like logo or responsive breakpoints, set user permissions...&lt;/p&gt;

&lt;h2&gt;
  
  
  Is it fast?
&lt;/h2&gt;

&lt;p&gt;You bet! The starter projects use the latest &lt;strong&gt;Next.js&lt;/strong&gt; versions with a &lt;strong&gt;blazing fast&lt;/strong&gt; statically generated website.&lt;br&gt;
&lt;strong&gt;Images are optimized&lt;/strong&gt; for responsive view and lazy load and served from a fast global &lt;strong&gt;CDN&lt;/strong&gt;.&lt;br&gt;
You can provide a &lt;strong&gt;build web hook&lt;/strong&gt; to let your editors trigger a rebuild on the server with the click of a button.&lt;/p&gt;
&lt;h2&gt;
  
  
  Developer experience
&lt;/h2&gt;

&lt;p&gt;React Bricks is written in &lt;strong&gt;TypeScript&lt;/strong&gt; and fully typed.&lt;br&gt;
&lt;strong&gt;Scaffold a project in seconds using the CLI.&lt;/strong&gt;&lt;br&gt;
The &lt;a href="https://docs.reactbricks.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=missing_link" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; is very complete.&lt;br&gt;
You may start from the &lt;a href="https://reactbricks.com/learn/welcome?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=missing_link" rel="noopener noreferrer"&gt;Step-by-step Tutorial&lt;/a&gt; where you gain points... with a final surprise!&lt;/p&gt;
&lt;h1&gt;
  
  
  Ok, but you are biased!
&lt;/h1&gt;

&lt;p&gt;Of course I am, but I am sincere when I tell you that I love creating "bricks" of content in React and seeing our customers happy while creating content. &lt;br&gt;
But don't take my word for it. We have big startups like &lt;a href="https://capbase.com" rel="noopener noreferrer"&gt;CapBase&lt;/a&gt; and &lt;a href="https://casavo.com" rel="noopener noreferrer"&gt;Casavo&lt;/a&gt; powering their websites (and empowering their marketing) with React Bricks. And &lt;a href="https://twitter.com/Swizec" rel="noopener noreferrer"&gt;Swizec Teller&lt;/a&gt; wrote a &lt;a href="https://swizec.com/blog/react-bricks-visual-blocks-editor-for-nextjs-codewithswiz-22/" rel="noopener noreferrer"&gt;great post about React Bricks&lt;/a&gt;.&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1237872398889701378-960" src="https://platform.twitter.com/embed/Tweet.html?id=1237872398889701378"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1237872398889701378-960');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1237872398889701378&amp;amp;theme=dark"
  }



&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1374480533955047424-2" src="https://platform.twitter.com/embed/Tweet.html?id=1374480533955047424"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1374480533955047424-2');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1374480533955047424&amp;amp;theme=dark"
  }



&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1374479894692818950-987" src="https://platform.twitter.com/embed/Tweet.html?id=1374479894692818950"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1374479894692818950-987');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1374479894692818950&amp;amp;theme=dark"
  }



&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1359186869402013699-66" src="https://platform.twitter.com/embed/Tweet.html?id=1359186869402013699"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1359186869402013699-66');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1359186869402013699&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;h1&gt;
  
  
  What do &lt;em&gt;you&lt;/em&gt; think about it?
&lt;/h1&gt;

&lt;p&gt;Please, let me know what do you think about &lt;a href="https://reactbricks.com?utm_source=devto&amp;amp;utm_medium=social&amp;amp;utm_campaign=missing_link" rel="noopener noreferrer"&gt;React Bricks&lt;/a&gt;.&lt;br&gt;
What do you like (or not) about it? What would you use it for? How may I help you start with a project?&lt;/p&gt;
&lt;h1&gt;
  
  
  Last thing: see me explain why React Bricks will change the way we edit websites
&lt;/h1&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/WVVX4PvrTp0"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

</description>
      <category>react</category>
      <category>nextjs</category>
      <category>cms</category>
      <category>visualediting</category>
    </item>
    <item>
      <title>Static Site generation impact on API Servers</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Tue, 07 Apr 2020 14:51:56 +0000</pubDate>
      <link>https://dev.to/matfrana/static-site-generation-impact-on-api-servers-5bc7</link>
      <guid>https://dev.to/matfrana/static-site-generation-impact-on-api-servers-5bc7</guid>
      <description>&lt;p&gt;Does the new trend of Static site generation have an impact on API server resources? Let’s see!&lt;/p&gt;

&lt;h1&gt;
  
  
  What is Static Site Generation?
&lt;/h1&gt;

&lt;p&gt;With Static Site Generation, a website dynamic content is generated via a &lt;strong&gt;build process&lt;/strong&gt;. &lt;/p&gt;

&lt;p&gt;The result of the build process is a static website: something like a &lt;strong&gt;1996 pure HTML website&lt;/strong&gt;, but often with very smart JavaScript tricks to preload content when it is likely to be needed, obtaining a &lt;strong&gt;perceived performance&lt;/strong&gt; which is the best you can have.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;All the calls&lt;/strong&gt; to external resources that are needed to gather content and generate the pages (for example a CMS API) are &lt;strong&gt;made during the build process&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Then, the resulting static website may be hosted on a &lt;strong&gt;CDN&lt;/strong&gt;, with no other call to the APIs.&lt;/p&gt;

&lt;p&gt;In this way the website is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Super fast&lt;/strong&gt; (static content + CDN + preload tricks)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Very secure&lt;/strong&gt;, as the attack surface of a static website is very limited&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less demanding on API / DB server&lt;/strong&gt; resources&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you like to see the differences between Server Side Rendering and Static Site Generation, &lt;a href="https://dev.to/matfrana/server-side-rendering-vs-static-site-generation-17nf"&gt;see this post&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Note
&lt;/h3&gt;

&lt;p&gt;Actually, the static website could need API calls at run time: if we think of an e-commerce, all the product pages may be statically generated, but the order management requires API calls to create an order. Anyway, these “POST” calls typically represent a small part of all the API calls to “GET” the content.&lt;/p&gt;

&lt;h1&gt;
  
  
  Impact on API and DB Server resources
&lt;/h1&gt;

&lt;p&gt;As we saw, with static site generation, most of the API calls are at build time, so they are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;From just 1 client machine&lt;/strong&gt; (the one where the build is launched)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Many at once&lt;/strong&gt; for each build (all the API calls to build all the pages)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interleaved&lt;/strong&gt; by a (more or less) &lt;strong&gt;long idle time&lt;/strong&gt; before the next build&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;As for the 2nd point, the API calls may be less if we can use an &lt;strong&gt;incremental build process&lt;/strong&gt;, so that just the new / changed / needing frequent updates pages are generated.&lt;br&gt;
For example &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt; recently created an &lt;a href="https://github.com/zeit/next.js/discussions/11552" rel="noopener noreferrer"&gt;RFC for incremental site generation&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;As for the 3rd point, if we think that on a server we may host the APIs / DB of more than one website, the high-CPU / idle cycles may be &lt;strong&gt;balanced&lt;/strong&gt; between the hosted websites. &lt;/p&gt;

&lt;p&gt;The same, we have requests in burst and from few clients.&lt;/p&gt;

&lt;p&gt;This will mean, on the API server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Less network usage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less DB usage&lt;/strong&gt; (only for builds, not for every request)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Less average CPU usage&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CPU/disk usage in bursts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A higher write / read ratio&lt;/strong&gt; on the disk (having much less read operations)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In general, the usage on the API server will be much less with SSG, especially with the adoption of incremental builds, which greatly flattens the usage bursts for websites with many pages.&lt;/p&gt;

&lt;p&gt;Of course, this is true unless you have a website with 100K pages, just 2 visitors per day and you rebuild it all every minute… 😊&lt;/p&gt;

&lt;h1&gt;
  
  
  Advantages of a serverless architecture
&lt;/h1&gt;

&lt;p&gt;I manage servers since 1997 (I still jealously guard the Windows NT 4.0 box) and we still manage our servers, so I am "old school", but with SSG, serverless services are great, because:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;You need bursts usage&lt;/strong&gt;, and with serverless architectures you just &lt;strong&gt;pay for what you use&lt;/strong&gt; (so you don't pay during the idle time between builds)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Absolute performance is not required&lt;/strong&gt;, as the build process is a batch process with no user perceiving the performance. So, even the cold startup time of a &lt;strong&gt;lambda function&lt;/strong&gt; is not a problem here.&lt;/li&gt;
&lt;/ol&gt;

&lt;h1&gt;
  
  
  Impact on reliability and brand image
&lt;/h1&gt;

&lt;p&gt;With a server side rendered website, if the API server goes down, the site goes down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With a static generated website, if the API server goes down, we have no immediate impact&lt;/strong&gt;. &lt;br&gt;
The website is served on the edge by the CDN and works independently of the API server.&lt;/p&gt;

&lt;p&gt;We still have an impact, because we cannot update the website content: the users don’t see errors, but &lt;strong&gt;stale content&lt;/strong&gt;, until the API server is restored. The API server in a way becomes &lt;strong&gt;less critical&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Even if we have an e-commerce website&lt;/strong&gt;, with API calls to manage orders, the impact of a failure is limited to the checkout phase, while the website is still visible. In this case, we surely have impact on the income, but &lt;strong&gt;less damage on the brand image&lt;/strong&gt; of the website.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;With Static Site Generation, in general, we need &lt;strong&gt;less resources on the API server&lt;/strong&gt; than using server-side rendering.&lt;br&gt;
What’s more, &lt;strong&gt;a server admin could sleep better at night&lt;/strong&gt;, as the impact of the API / DB server failure is less severe and less immediate.&lt;/p&gt;

&lt;p&gt;Let me know what you think about this post: I'd be super interested in receiving &lt;strong&gt;usage data stats&lt;/strong&gt; that confirms (or prove wrong) my educated guesses. Thank you.&lt;/p&gt;

&lt;h3&gt;
  
  
  React Bricks
&lt;/h3&gt;

&lt;p&gt;By the way, if you’d like to build a blazing fast &lt;strong&gt;static website using Gatsby or Next.js and keep the WYSIWYG&lt;/strong&gt; editing that is missing in headless CMSs, you may try our hybrid block-based CMS &lt;a href="https://www.reactbricks.com/" rel="noopener noreferrer"&gt;React-Bricks&lt;/a&gt;! It’s now in beta! 🚀&lt;/p&gt;

</description>
      <category>devops</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>react</category>
    </item>
    <item>
      <title>React Hook Form: the best form library?</title>
      <dc:creator>Matteo Frana</dc:creator>
      <pubDate>Thu, 02 Apr 2020 12:45:00 +0000</pubDate>
      <link>https://dev.to/matfrana/react-hook-form-the-best-form-library-1o1l</link>
      <guid>https://dev.to/matfrana/react-hook-form-the-best-form-library-1o1l</guid>
      <description>&lt;p&gt;This is a very short post on a library I recently discovered (to build the beta subscription of &lt;a href="https://www.reactbricks.com" rel="noopener noreferrer"&gt;React Bricks CMS&lt;/a&gt;) and which I love: &lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;React Hook Form&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I come from &lt;a href="https://redux-form.com/" rel="noopener noreferrer"&gt;Redux Form&lt;/a&gt; (which still haunts my old projects), then embraced the great &lt;a href="https://jaredpalmer.com/formik" rel="noopener noreferrer"&gt;Formik&lt;/a&gt; by &lt;a href="https://twitter.com/jaredpalmer" rel="noopener noreferrer"&gt;Jared Palmer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Today I use React Hook Form everywhere, replacing Formik.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;h1&gt;
  
  
  1. Less and cleaner code
&lt;/h1&gt;

&lt;p&gt;This is the main reason why I love React Hook Form: it has the smallest amount of code of any other library: &lt;strong&gt;you just execute a hook and add a &lt;code&gt;ref&lt;/code&gt; to your fields&lt;/strong&gt;. Done.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Validation is added in one second&lt;/strong&gt; too, using the provided &lt;code&gt;required&lt;/code&gt;, &lt;code&gt;min&lt;/code&gt;, &lt;code&gt;max&lt;/code&gt;, &lt;code&gt;minLength&lt;/code&gt;, &lt;code&gt;maxLength&lt;/code&gt;, &lt;code&gt;pattern&lt;/code&gt;, &lt;code&gt;validate&lt;/code&gt; rules. &lt;/p&gt;

&lt;p&gt;Out of the box it focuses on the first field with a validation error.&lt;br&gt;
If you prefer, you may use a centralized &lt;a href="https://github.com/jquense/yup" rel="noopener noreferrer"&gt;yup&lt;/a&gt; schema.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;And... I love Hooks&lt;/strong&gt;: you completely avoid the wrappers hell problem you typically have with Render Props (&lt;a href="https://www.youtube.com/watch?v=BEYg11nZev4" rel="noopener noreferrer"&gt;in this talk at ReactJsDay&lt;/a&gt; I explain why Hooks are superior to Higher Order Components and Render Props).&lt;/p&gt;

&lt;p&gt;Here's a simple example, complete with validation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;useForm&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react-hook-form&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Example&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;register&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useForm&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;onSubmit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;values&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;values&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt; &lt;span class="na"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;handleSubmit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;onSubmit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"fullName"&lt;/span&gt;
        &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fullName&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Enter your name&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;span&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;input&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;
        &lt;span class="na"&gt;ref&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;register&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
          &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;E-mail required&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;pattern&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;value&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z0-9._%+-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+@&lt;/span&gt;&lt;span class="se"&gt;[&lt;/span&gt;&lt;span class="sr"&gt;A-Z0-9.-&lt;/span&gt;&lt;span class="se"&gt;]&lt;/span&gt;&lt;span class="sr"&gt;+&lt;/span&gt;&lt;span class="se"&gt;\.[&lt;/span&gt;&lt;span class="sr"&gt;A-Z&lt;/span&gt;&lt;span class="se"&gt;]{2,4}&lt;/span&gt;&lt;span class="sr"&gt;$/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Enter a valid email address&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;errors&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;

      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;Submit&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;button&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;form&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Very easy, huh?&lt;/p&gt;

&lt;h1&gt;
  
  
  2. Documentation
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;The documentation is a pleasure to read.&lt;/strong&gt;&lt;br&gt;
It is very well done and also beautiful: to me this is very important.&lt;/p&gt;

&lt;h1&gt;
  
  
  3. Easy integration with UI libraries
&lt;/h1&gt;

&lt;p&gt;I integrated it very easily with &lt;strong&gt;react-select&lt;/strong&gt; and I wrapped my &lt;strong&gt;custom form components&lt;/strong&gt; in a snap. &lt;/p&gt;

&lt;p&gt;No friction here means &lt;strong&gt;you can start using it with no worries&lt;/strong&gt; about how well it would play with your existing components' stack: &lt;strong&gt;it plays well&lt;/strong&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  4. Super light and zero dependencies
&lt;/h1&gt;

&lt;p&gt;Absolutely no dependencies, which is very good from a tech debt perspective and... just 5 KB!&lt;/p&gt;

&lt;h1&gt;
  
  
  5. Performance
&lt;/h1&gt;

&lt;p&gt;I am not one of those evaluating a library based on a couple of milliseconds of difference, but, also from this point of view, React Hook Form beats them all: it &lt;strong&gt;reduces the number of re-renders&lt;/strong&gt; to the bare minimum and it mounts faster than Formik or Redux Form.&lt;/p&gt;

&lt;h1&gt;
  
  
  6. Batteries included
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Form Builder
&lt;/h3&gt;

&lt;p&gt;React Hook Form comes with a &lt;a href="https://react-hook-form.com/form-builder" rel="noopener noreferrer"&gt;Form Builder&lt;/a&gt; which comes in handy, especially for a quick form with simple validation rules.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dev Tools
&lt;/h3&gt;

&lt;p&gt;It has its own Dev Tools to debug the form status. &lt;br&gt;
I admit that I still haven't used it, but I think it's a nice-to-have plus.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Really, I couldn't ask for more. &lt;br&gt;
So... yes, in my opinion &lt;strong&gt;this is the best React form library today&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://react-hook-form.com/" rel="noopener noreferrer"&gt;Try it yourself&lt;/a&gt; and let me know your opinion!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
