<?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: schukai </title>
    <description>The latest articles on DEV Community by schukai  (@schukai).</description>
    <link>https://dev.to/schukai</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%2Forganization%2Fprofile_image%2F4990%2Fc1df8abe-0eef-4285-850f-a41aa6b4edea.png</url>
      <title>DEV Community: schukai </title>
      <link>https://dev.to/schukai</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/schukai"/>
    <language>en</language>
    <item>
      <title>Workspaces: Building a Headless Company OS for API-first Processes and AI Agent Workflows</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Mon, 04 May 2026 00:42:46 +0000</pubDate>
      <link>https://dev.to/schukai/workspaces-building-a-headless-company-os-for-api-first-processes-and-ai-agent-workflows-18ld</link>
      <guid>https://dev.to/schukai/workspaces-building-a-headless-company-os-for-api-first-processes-and-ai-agent-workflows-18ld</guid>
      <description>&lt;h1&gt;
  
  
  Workspaces: Building a Headless Company OS for API-first Processes and AI Agent Workflows
&lt;/h1&gt;

&lt;p&gt;Many business systems were historically built around user interfaces.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRM? UI.
&lt;/li&gt;
&lt;li&gt;ERP? UI.
&lt;/li&gt;
&lt;li&gt;Document management? UI.
&lt;/li&gt;
&lt;li&gt;Commerce? UI.
&lt;/li&gt;
&lt;li&gt;Reporting? UI.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That works as long as humans manually execute every process step.&lt;/p&gt;

&lt;p&gt;But modern companies increasingly need something else: systems that can be automated, integrated, and controlled by other systems.&lt;/p&gt;

&lt;p&gt;This is one of the reasons we are building &lt;a href="https://nucleus.getshop.cloud/" rel="noopener noreferrer"&gt;&lt;strong&gt;Workspaces&lt;/strong&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Workspaces is our approach to a &lt;strong&gt;headless Company OS&lt;/strong&gt; with an ERP core, web administration, and API-based operation for business processes. The platform brings together CRM, commerce, PIM, documents, workflows, tasks, compliance, reporting, chat, newsletters, AI-adjacent features, and task streams in one shared multi-tenant system.&lt;/p&gt;

&lt;p&gt;But this article is not meant to sound like everything is already perfect.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are not perfect either. But we are working on it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And that is actually an important part of the story.&lt;/p&gt;

&lt;p&gt;Workspaces is not just a product name for us. It is a direction. A journey. A long-term attempt to make operational business software more programmable, more open, and more useful for automation.&lt;/p&gt;

&lt;p&gt;The goal is not simply to build another ERP with a nice web interface.&lt;/p&gt;

&lt;p&gt;The goal is to build a platform where humans, systems, integrations, and eventually AI agents can work with business processes through stable contracts.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why We Started Thinking About This
&lt;/h2&gt;

&lt;p&gt;If you have ever integrated business software, you probably know the problem.&lt;/p&gt;

&lt;p&gt;Many systems have an API, but the API often feels like an afterthought.&lt;/p&gt;

&lt;p&gt;The UI is the real product.&lt;br&gt;&lt;br&gt;
The API is something added later.&lt;br&gt;&lt;br&gt;
The documentation is incomplete.&lt;br&gt;&lt;br&gt;
The data model is hard to understand.&lt;br&gt;&lt;br&gt;
Permissions are unclear.&lt;br&gt;&lt;br&gt;
Workflows are hidden inside UI actions.&lt;br&gt;&lt;br&gt;
Automation requires too much custom glue code.&lt;/p&gt;

&lt;p&gt;For simple integrations, this might still work.&lt;/p&gt;

&lt;p&gt;For serious automation, it becomes painful.&lt;/p&gt;

&lt;p&gt;And when AI agents enter the picture, the problem becomes even more obvious.&lt;/p&gt;

&lt;p&gt;An AI agent does not need a beautiful dashboard. It needs reliable answers to very practical questions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Which actions are available?&lt;/li&gt;
&lt;li&gt;Which data may I access?&lt;/li&gt;
&lt;li&gt;Which parameters are required?&lt;/li&gt;
&lt;li&gt;Which workflow can I start?&lt;/li&gt;
&lt;li&gt;How do I check the current status?&lt;/li&gt;
&lt;li&gt;What happens if something fails?&lt;/li&gt;
&lt;li&gt;In which tenant and permission context am I operating?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A system that was designed only from a UI perspective usually cannot answer these questions cleanly.&lt;/p&gt;

&lt;p&gt;That is the gap we are trying to close with Workspaces.&lt;/p&gt;


&lt;h2&gt;
  
  
  The Basic Idea Behind Workspaces
&lt;/h2&gt;

&lt;p&gt;Workspaces is designed as a &lt;strong&gt;headless-capable business platform&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The web administration interface is still important. People need good tools. Teams need dashboards, forms, lists, reports, tasks, and workflows.&lt;/p&gt;

&lt;p&gt;But the UI should not be the only way to operate the system.&lt;/p&gt;

&lt;p&gt;Core functions should also be accessible through APIs. Processes should be controllable by external systems. Clients should be able to discover what is available. Authentication and permissions should be part of the platform contract.&lt;/p&gt;

&lt;p&gt;In simplified form, the idea looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;External systems
AI agents
Integrations
Automations
Internal web administration
        │
        ▼
     /api/v1
        │
        ▼
Workspaces Company OS
CRM · ERP · Commerce · PIM · Documents · Workflows · Tasks · Reporting · Compliance
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The important part is this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;API access is not supposed to be a side feature. It is supposed to be part of the foundation.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is something we are actively working toward.&lt;/p&gt;

&lt;p&gt;Some parts are already there. Some parts are still evolving. Some things will certainly change as we learn from real use cases.&lt;/p&gt;

&lt;p&gt;But the direction is clear: business software should become more programmable.&lt;/p&gt;




&lt;h2&gt;
  
  
  API-first Is More Than “We Have an API”
&lt;/h2&gt;

&lt;p&gt;A lot of software products say they are API-first.&lt;/p&gt;

&lt;p&gt;But in practice, “API-first” can mean very different things.&lt;/p&gt;

&lt;p&gt;For us, it means that the API should not merely expose database objects. It should represent useful business capabilities.&lt;/p&gt;

&lt;p&gt;Not only:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /contacts
PATCH /orders/123
GET /documents/456
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But also:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start a customer onboarding workflow.
Create a task in the correct business context.
Attach a document to an entity.
Check the status of an automation.
Expose available capabilities to a client.
Respect tenant and permission boundaries.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This distinction matters.&lt;/p&gt;

&lt;p&gt;Business software is not only about data. It is about processes.&lt;/p&gt;

&lt;p&gt;And processes need more than CRUD.&lt;/p&gt;




&lt;h2&gt;
  
  
  Discovery-first Instead of Hardcoded Assumptions
&lt;/h2&gt;

&lt;p&gt;One principle we care about is &lt;strong&gt;discovery&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Instead of forcing clients to hardcode every path, every feature, and every entry point, we want Workspaces to expose available capabilities at runtime.&lt;/p&gt;

&lt;p&gt;A simplified example could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;GET /api/v1/capabilities
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response could describe which capabilities are available in the current context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tenant"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"example-company"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"capabilities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"crm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/v1/crm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"read_contacts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"create_contact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"update_contact"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"documents"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/v1/documents"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"upload"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"classify"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"link_to_entity"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"workflows"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"entrypoint"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/api/v1/workflows"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"actions"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"inspect"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"cancel"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is useful for traditional clients.&lt;/p&gt;

&lt;p&gt;It is even more useful for dynamic clients and AI agent workflows.&lt;/p&gt;

&lt;p&gt;Instead of assuming:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I hope this endpoint exists.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A client can ask:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;What can I do here?
Which capabilities are available?
Which actions are allowed?
Where do I start?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is the kind of interaction model we want.&lt;/p&gt;

&lt;p&gt;We are not fully done with this vision. But we believe this is the right direction.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why OpenAPI-like Contracts Matter
&lt;/h2&gt;

&lt;p&gt;For developers, an API is only truly useful when it is documented, consistent, and machine-readable.&lt;/p&gt;

&lt;p&gt;That is why Workspaces moves toward OpenAPI-like contracts, structured metadata, and field-level descriptions.&lt;/p&gt;

&lt;p&gt;This matters for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SDK generation&lt;/li&gt;
&lt;li&gt;API clients&lt;/li&gt;
&lt;li&gt;validation&lt;/li&gt;
&lt;li&gt;tests&lt;/li&gt;
&lt;li&gt;external integrations&lt;/li&gt;
&lt;li&gt;AI agent tooling&lt;/li&gt;
&lt;li&gt;documentation&lt;/li&gt;
&lt;li&gt;field-level access control&lt;/li&gt;
&lt;li&gt;privacy-aware data handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In business software, a JSON response alone is not enough.&lt;/p&gt;

&lt;p&gt;A client should be able to understand which fields are readable, writable, required, sensitive, or restricted.&lt;/p&gt;

&lt;p&gt;A simplified example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"contact"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"fields"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"readOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"privacy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"personal_data"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"required"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"customerNumber"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"readOnly"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"internalNote"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"visibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"restricted"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For normal software clients, this is helpful.&lt;/p&gt;

&lt;p&gt;For AI agents, it becomes essential.&lt;/p&gt;

&lt;p&gt;An agent should not simply read, interpret, or modify everything it sees. It needs boundaries. It needs contracts. It needs to know what is allowed.&lt;/p&gt;

&lt;p&gt;This is one of the reasons we think API design, metadata, and privacy-aware field contracts are becoming more important, not less.&lt;/p&gt;




&lt;h2&gt;
  
  
  Headless Authentication and API Key Operation
&lt;/h2&gt;

&lt;p&gt;If business processes should be automated, a classic browser login is not enough.&lt;/p&gt;

&lt;p&gt;External systems, services, and agents need ways to authenticate without a human clicking through a web interface.&lt;/p&gt;

&lt;p&gt;That is why Workspaces supports and continues to evolve around headless login flows and API key operation.&lt;/p&gt;

&lt;p&gt;But authentication alone is not enough.&lt;/p&gt;

&lt;p&gt;Every API call exists in a business context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Who is calling?
For which tenant?
With which permissions?
For which capability?
For which purpose?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is especially important in a multi-tenant system.&lt;/p&gt;

&lt;p&gt;An AI agent that analyzes documents, creates tasks, or updates CRM data must not operate outside its allowed context.&lt;/p&gt;

&lt;p&gt;Permissions, tenant context, and authentication should not be bolted on later. They should be part of the platform contract from the beginning.&lt;/p&gt;

&lt;p&gt;This is a difficult area, and we are still learning.&lt;/p&gt;

&lt;p&gt;But it is also one of the most important areas.&lt;/p&gt;

&lt;p&gt;Because automation without clear boundaries is not progress. It is risk.&lt;/p&gt;




&lt;h2&gt;
  
  
  Workflows Instead of Isolated API Calls
&lt;/h2&gt;

&lt;p&gt;Many APIs are built around isolated operations.&lt;/p&gt;

&lt;p&gt;Create this.&lt;br&gt;
Update that.&lt;br&gt;
Delete something else.&lt;/p&gt;

&lt;p&gt;That is necessary, but it is not enough for real business processes.&lt;/p&gt;

&lt;p&gt;A typical process often looks more like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A new lead comes in.&lt;/li&gt;
&lt;li&gt;The company and contact data are checked.&lt;/li&gt;
&lt;li&gt;A CRM record is created or updated.&lt;/li&gt;
&lt;li&gt;A document is attached.&lt;/li&gt;
&lt;li&gt;A compliance rule is evaluated.&lt;/li&gt;
&lt;li&gt;A task is created.&lt;/li&gt;
&lt;li&gt;A person or team gets assigned.&lt;/li&gt;
&lt;li&gt;A reporting event is written.&lt;/li&gt;
&lt;li&gt;The process continues depending on the result.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If this logic lives only in external scripts, middleware, or cron jobs, the process becomes fragmented.&lt;/p&gt;

&lt;p&gt;The data is in one place.&lt;br&gt;
The workflow is somewhere else.&lt;br&gt;
The business rules are hidden in custom code.&lt;br&gt;
The status is hard to inspect.&lt;/p&gt;

&lt;p&gt;That is exactly what we want to improve.&lt;/p&gt;

&lt;p&gt;Workspaces is designed to support workflows and task streams so that integrations and agents can work with processes, not just records.&lt;/p&gt;

&lt;p&gt;A simplified workflow start could look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;POST /api/v1/workflows/start
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workflow"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"new_customer_onboarding"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"input"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"companyName"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example GmbH"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"email"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"info@example.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"website"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response could return the current process state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"workflowRunId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"wf_123456"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"status"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"running"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"next"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"task"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"assignedTo"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"sales"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"label"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Review customer data"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This turns the API into more than a data pipe.&lt;/p&gt;

&lt;p&gt;It becomes a process interface.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters for AI Agents
&lt;/h2&gt;

&lt;p&gt;AI agents are often described as chatbots.&lt;/p&gt;

&lt;p&gt;But for business software, the more interesting question is not whether an agent can chat.&lt;/p&gt;

&lt;p&gt;The interesting question is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Can an agent safely perform useful work inside real business processes?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;To do that, the agent needs access to tools, data, workflows, and status information.&lt;/p&gt;

&lt;p&gt;But that access must be controlled, traceable, and understandable.&lt;/p&gt;

&lt;p&gt;Workspaces is being built with this direction in mind.&lt;/p&gt;

&lt;p&gt;An agent should be able to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;discover available capabilities&lt;/li&gt;
&lt;li&gt;authenticate headlessly&lt;/li&gt;
&lt;li&gt;operate in a tenant context&lt;/li&gt;
&lt;li&gt;understand allowed actions&lt;/li&gt;
&lt;li&gt;call APIs with documented parameters&lt;/li&gt;
&lt;li&gt;start workflows&lt;/li&gt;
&lt;li&gt;create tasks&lt;/li&gt;
&lt;li&gt;check process state&lt;/li&gt;
&lt;li&gt;write results back into the business context&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This does not mean that every process should be fully autonomous.&lt;/p&gt;

&lt;p&gt;It also does not mean that an AI agent should replace human decision-making everywhere.&lt;/p&gt;

&lt;p&gt;In many cases, the best model is a hybrid one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent prepares.
System validates.
Human approves.
Workflow continues.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is a much more realistic and useful approach than pretending that everything should be automated immediately.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Possible Agent Scenario
&lt;/h2&gt;

&lt;p&gt;Imagine a company receives an inquiry through a web form:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"We are interested in product X and would like to receive an offer."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An AI-assisted workflow in Workspaces could look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Receive the inquiry.&lt;/li&gt;
&lt;li&gt;Check whether the company already exists.&lt;/li&gt;
&lt;li&gt;Create or update the CRM contact.&lt;/li&gt;
&lt;li&gt;Fetch product information from the PIM.&lt;/li&gt;
&lt;li&gt;Link relevant documents or price lists.&lt;/li&gt;
&lt;li&gt;Check compliance or internal rules.&lt;/li&gt;
&lt;li&gt;Create a task for the sales team.&lt;/li&gt;
&lt;li&gt;Write the current status into the task stream.&lt;/li&gt;
&lt;li&gt;Prepare a draft response.&lt;/li&gt;
&lt;li&gt;Let a human review and send it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The agent does not need to rebuild the CRM, ERP, PIM, document management, and task system.&lt;/p&gt;

&lt;p&gt;It uses Workspaces as the operational control center.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI agent
  │
  ├─ queries available capabilities
  ├─ authenticates headlessly
  ├─ reads permitted CRM and PIM data
  ├─ starts workflows
  ├─ creates tasks
  ├─ checks status
  └─ writes results into the process context
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the kind of architecture we believe will become increasingly important.&lt;/p&gt;

&lt;p&gt;Not because AI magically solves every business problem.&lt;/p&gt;

&lt;p&gt;But because AI becomes much more useful when it can operate through stable, well-defined, permission-aware interfaces.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Hard Part: Business Software Is Messy
&lt;/h2&gt;

&lt;p&gt;One thing we have learned again and again: business software is messy.&lt;/p&gt;

&lt;p&gt;Every company has different processes.&lt;br&gt;
Every team has exceptions.&lt;br&gt;
Every workflow has edge cases.&lt;br&gt;
Every integration reveals another detail.&lt;br&gt;
Every automation needs guardrails.&lt;/p&gt;

&lt;p&gt;That is why we do not want to present Workspaces as if everything is finished and flawless.&lt;/p&gt;

&lt;p&gt;It is not.&lt;/p&gt;

&lt;p&gt;We are building it step by step.&lt;/p&gt;

&lt;p&gt;We are improving the APIs.&lt;br&gt;
We are refining the capability model.&lt;br&gt;
We are working on better metadata.&lt;br&gt;
We are improving workflow handling.&lt;br&gt;
We are learning where automation helps and where humans must stay in control.&lt;/p&gt;

&lt;p&gt;And yes, sometimes we discover that something we built needs to be changed.&lt;/p&gt;

&lt;p&gt;That is part of the journey.&lt;/p&gt;

&lt;p&gt;The important thing is the direction:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We want to make operational business software programmable, discoverable, automatable, and ready for a future where humans, systems, and AI agents work together.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h2&gt;
  
  
  Why a Shared Data and Process Framework Matters
&lt;/h2&gt;

&lt;p&gt;Many companies use a separate tool for every area:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CRM for contacts&lt;/li&gt;
&lt;li&gt;shop system for commerce&lt;/li&gt;
&lt;li&gt;PIM for product data&lt;/li&gt;
&lt;li&gt;DMS for documents&lt;/li&gt;
&lt;li&gt;task tool for assignments&lt;/li&gt;
&lt;li&gt;newsletter tool for communication&lt;/li&gt;
&lt;li&gt;reporting system for analytics&lt;/li&gt;
&lt;li&gt;compliance tool for rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That can work.&lt;/p&gt;

&lt;p&gt;But it creates integration cost.&lt;/p&gt;

&lt;p&gt;Every automation has to connect multiple systems.&lt;br&gt;
Every agent needs several APIs.&lt;br&gt;
Every process must synchronize context across tools.&lt;br&gt;
Every exception creates another piece of glue code.&lt;/p&gt;

&lt;p&gt;Workspaces follows a different approach.&lt;/p&gt;

&lt;p&gt;Operational domains should exist in one shared multi-tenant system, or at least in a shared process and API framework.&lt;/p&gt;

&lt;p&gt;That does not mean every company has to treat everything as one monolith.&lt;/p&gt;

&lt;p&gt;But it does mean that processes can be modeled more consistently across domain boundaries.&lt;/p&gt;

&lt;p&gt;For developers, this is helpful because less logic disappears into middleware, cron jobs, and one-off scripts.&lt;/p&gt;


&lt;h2&gt;
  
  
  What Developers Might Find Interesting
&lt;/h2&gt;

&lt;p&gt;For developers, Workspaces becomes especially interesting when business software is not only used, but integrated, extended, automated, and programmed.&lt;/p&gt;

&lt;p&gt;Some of the technical ideas behind it are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API-first architecture&lt;/li&gt;
&lt;li&gt;headless operation&lt;/li&gt;
&lt;li&gt;discovery endpoints&lt;/li&gt;
&lt;li&gt;capability-based access&lt;/li&gt;
&lt;li&gt;OpenAPI-like contracts&lt;/li&gt;
&lt;li&gt;machine-readable metadata&lt;/li&gt;
&lt;li&gt;privacy-aware field contracts&lt;/li&gt;
&lt;li&gt;multi-tenancy&lt;/li&gt;
&lt;li&gt;permission and authentication context&lt;/li&gt;
&lt;li&gt;workflow start and status inspection&lt;/li&gt;
&lt;li&gt;task stream integration&lt;/li&gt;
&lt;li&gt;operational domains in one shared system&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is a different perspective on business software.&lt;/p&gt;

&lt;p&gt;Not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here is an ERP with a user interface.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Here is an operational backend that humans, systems, and agents can use through stable contracts.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is what we are working toward with Workspaces.&lt;/p&gt;




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

&lt;p&gt;Workspaces is our attempt to build an API-first, headless-capable business platform for operational processes.&lt;/p&gt;

&lt;p&gt;It combines an ERP core, CRM, commerce, PIM, documents, workflows, tasks, compliance, reporting, communication, and additional functions in one shared multi-tenant system.&lt;/p&gt;

&lt;p&gt;But more importantly, Workspaces is part of a broader journey:&lt;/p&gt;

&lt;p&gt;We want to make business processes programmable.&lt;/p&gt;

&lt;p&gt;We want APIs that are not just technical endpoints, but reliable business contracts.&lt;/p&gt;

&lt;p&gt;We want discovery, metadata, authentication, permissions, workflows, and task streams to work together.&lt;/p&gt;

&lt;p&gt;We want AI agents and external systems to interact with business software safely and meaningfully.&lt;/p&gt;

&lt;p&gt;And we know this is not easy.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;We are not perfect either. But we are working on it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For us, Workspaces is not a finished claim that all problems are solved.&lt;/p&gt;

&lt;p&gt;It is the direction we are building toward.&lt;/p&gt;

&lt;p&gt;A headless Company OS for businesses that want their processes to become more integrated, more automated, and more programmable.&lt;/p&gt;

</description>
      <category>api</category>
      <category>ai</category>
      <category>automation</category>
      <category>erp</category>
    </item>
    <item>
      <title>You Don’t Always Need React — Sometimes You Just Need Structure</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Mon, 13 Apr 2026 16:51:07 +0000</pubDate>
      <link>https://dev.to/schukai/you-dont-always-need-react-sometimes-you-just-need-structure-m9j</link>
      <guid>https://dev.to/schukai/you-dont-always-need-react-sometimes-you-just-need-structure-m9j</guid>
      <description>&lt;h1&gt;
  
  
  Structure in the browser without committing to a framework
&lt;/h1&gt;

&lt;p&gt;At some point, most frontend projects hit the same wall.&lt;/p&gt;

&lt;p&gt;You start simple: a bit of vanilla JavaScript, maybe some fetch calls, a few event listeners. It works. It’s fast. It feels clean.&lt;/p&gt;

&lt;p&gt;Then the UI grows.&lt;/p&gt;

&lt;p&gt;Forms get more complex. State starts leaking across components. Validation logic spreads. Tables need filtering, pagination, persistence. Suddenly, “just JavaScript” turns into a pile of implicit behavior.&lt;/p&gt;

&lt;p&gt;That’s usually the moment where teams reach for a framework like React or Vue.js.&lt;/p&gt;

&lt;p&gt;And to be fair—those solve a lot of problems. But they also come with their own cost: another abstraction layer, a different mental model, and often a growing distance from the platform itself.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;monsterjs&lt;/code&gt; takes a different approach.&lt;/p&gt;

&lt;h3&gt;
  
  
  Working &lt;em&gt;with&lt;/em&gt; the platform, not around it
&lt;/h3&gt;

&lt;p&gt;Instead of replacing the browser model, &lt;code&gt;monsterjs&lt;/code&gt; leans into it.&lt;/p&gt;

&lt;p&gt;It builds on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom Elements&lt;/li&gt;
&lt;li&gt;Shadow DOM&lt;/li&gt;
&lt;li&gt;ES Modules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No virtual DOM. No proprietary templating language. No “magic” rendering pipeline.&lt;/p&gt;

&lt;p&gt;You still write HTML, CSS, and JavaScript—but with a layer of structure that helps you scale beyond toy examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where it actually helps
&lt;/h3&gt;

&lt;p&gt;The goal isn’t to reinvent everything. It’s to make common application patterns easier and more consistent.&lt;/p&gt;

&lt;p&gt;Things like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;declarative DOM updates instead of manual wiring&lt;/li&gt;
&lt;li&gt;form-associated custom elements that behave like real inputs&lt;/li&gt;
&lt;li&gt;reactive data binding without a full framework runtime&lt;/li&gt;
&lt;li&gt;REST-backed forms and datatables that reflect real backend flows&lt;/li&gt;
&lt;li&gt;built-in i18n handling&lt;/li&gt;
&lt;li&gt;reusable UI building blocks you can compose&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  From simple pages to real application flows
&lt;/h3&gt;

&lt;p&gt;The interesting part is how far you can push this without leaving the platform.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;monster-register-wizard&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
A full multi-step registration flow: email availability checks, profile + address steps, consent handling, validation, API mapping.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;monster-file-manager&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Browse files in a tree, open them in tabs, attach editors by MIME type.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;monster-datatable&lt;/code&gt;&lt;/strong&gt;&lt;br&gt;
Pagination, filters (input, select, range, date-range), save/status handling—built for real CRUD interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Form controls&lt;/strong&gt; like&lt;br&gt;
&lt;code&gt;monster-credential-button&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;monster-tree-select&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;monster-variant-select&lt;/code&gt;,&lt;br&gt;
&lt;code&gt;monster-repeat-field-set&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren’t demo widgets. They’re meant for actual application complexity.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting started without friction
&lt;/h3&gt;

&lt;p&gt;One of the nice things: you don’t have to commit upfront.&lt;/p&gt;

&lt;p&gt;You can start with a minimal browser setup—no build step, no tooling overhead—and grow into a package-based setup later if needed.&lt;/p&gt;

&lt;p&gt;The documentation on &lt;strong&gt;monsterjs.org&lt;/strong&gt; reflects that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a dedicated getting-started section&lt;/li&gt;
&lt;li&gt;examples that go from simple to structured&lt;/li&gt;
&lt;li&gt;and even an &lt;code&gt;llms.txt&lt;/code&gt; file, making it easier to consume the project through AI tooling when you just want quick orientation instead of reading everything&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  When this approach makes sense
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;monsterjs&lt;/code&gt; fits best if you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;want to stay close to the DOM and browser APIs&lt;/li&gt;
&lt;li&gt;prefer composable building blocks over full frameworks&lt;/li&gt;
&lt;li&gt;need structure for complex forms, CRUD UIs, and flows&lt;/li&gt;
&lt;li&gt;don’t want to introduce a full rendering framework&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your project is already deeply tied to React, Vue.js, or a similar ecosystem, adding another model probably won’t help.&lt;/p&gt;

&lt;p&gt;But if you’re somewhere between “vanilla chaos” and “framework overhead,” this is an interesting middle ground.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>webcomponents</category>
    </item>
    <item>
      <title>Monster Select now supports paginated dropdowns – fully reactive, fully open source</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Wed, 24 Sep 2025 13:30:55 +0000</pubDate>
      <link>https://dev.to/schukai/monster-select-now-supports-paginated-dropdowns-fully-reactive-fully-open-source-330</link>
      <guid>https://dev.to/schukai/monster-select-now-supports-paginated-dropdowns-fully-reactive-fully-open-source-330</guid>
      <description>&lt;p&gt;&lt;strong&gt;We added pagination to our select component – and yes, it’s fully open source&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Sometimes it’s the small things that make a big difference.&lt;/p&gt;

&lt;p&gt;Our latest update to the &lt;code&gt;monster-select&lt;/code&gt; component adds something developers (and users) have been asking for: &lt;strong&gt;pagination.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No more infinite scrolling. No awkward workarounds. Just clean, native paging – fully integrated.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔧 What’s new?
&lt;/h3&gt;

&lt;p&gt;We’ve added a &lt;strong&gt;pagestepper&lt;/strong&gt; UI to the dropdown:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Paginated view of options&lt;/li&gt;
&lt;li&gt;Configurable number of items per page&lt;/li&gt;
&lt;li&gt;Fully reactive (updates with filters and async data)&lt;/li&gt;
&lt;li&gt;Works with keyboard navigation&lt;/li&gt;
&lt;li&gt;Handles edge cases gracefully (like filtering and empty pages)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here’s what it looks like:&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%2Fa32m7jezpbq1ic639gbo.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%2Fa32m7jezpbq1ic639gbo.png" alt="Pagestepper Screenshot" width="521" height="356"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h3&gt;
  
  
  🧪 Example: Remote Filter + Pagination
&lt;/h3&gt;

&lt;p&gt;Here’s how to configure the select for a real-world use case:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;monster-select&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-filter-mode=&lt;/span&gt;&lt;span class="s"&gt;"remote"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-filter-position=&lt;/span&gt;&lt;span class="s"&gt;"popper"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-url=&lt;/span&gt;&lt;span class="s"&gt;"/api/items?filter={filter}&amp;amp;page={page}"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-mapping-labeltemplate=&lt;/span&gt;&lt;span class="s"&gt;"${name}"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-mapping-selector=&lt;/span&gt;&lt;span class="s"&gt;"data.*"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-filter-defaultValue=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-mapping-valuetemplate=&lt;/span&gt;&lt;span class="s"&gt;"${id}"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-features-showremoteinfo=&lt;/span&gt;&lt;span class="s"&gt;"true"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-remoteinfo-url=&lt;/span&gt;&lt;span class="s"&gt;"/api/items?count=1"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-mapping-currentpage=&lt;/span&gt;&lt;span class="s"&gt;"meta.pagination.currentPage"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-mapping-objectsperpage=&lt;/span&gt;&lt;span class="s"&gt;"meta.pagination.perPage"&lt;/span&gt;
  &lt;span class="na"&gt;data-monster-option-mapping-total=&lt;/span&gt;&lt;span class="s"&gt;"meta.pagination.total"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&amp;lt;/monster-select&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This example assumes your backend API returns something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"data"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Item 4"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Item 5"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Item 6"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"meta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"pagination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"currentPage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"perPage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"total"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Want filtering?&lt;/strong&gt; It’s already baked in. Just hook up &lt;code&gt;filter={filter}&lt;/code&gt; and the component handles debounce, remote updates, and reactivity for you.&lt;/p&gt;




&lt;h3&gt;
  
  
  💡 Why we built it
&lt;/h3&gt;

&lt;p&gt;Select components can get complicated. Especially when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You're dealing with large datasets&lt;/li&gt;
&lt;li&gt;Filters need to be remote&lt;/li&gt;
&lt;li&gt;You want full keyboard and accessibility support&lt;/li&gt;
&lt;li&gt;Pagination and state should sync with backend logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We needed a modular, scalable solution that plays well in modern web apps. So we built it into &lt;strong&gt;MonsterJS&lt;/strong&gt; – and open-sourced the whole thing.&lt;/p&gt;




&lt;h3&gt;
  
  
  🔗 Explore more
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Git:&lt;/strong&gt; &lt;a href="https://gitlab.schukai.com/oss/libraries/javascript/monsterjs-org" rel="noopener noreferrer"&gt;gitlab.schukai.com/.../monsterjs-org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docs &amp;amp; Live Demos:&lt;/strong&gt; &lt;a href="https://monsterjs.org/" rel="noopener noreferrer"&gt;monsterjs.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;monster-select&lt;/code&gt; is just one part of the puzzle. The lib also includes reactive state management, routing, declarative rendering and more.&lt;/p&gt;

&lt;p&gt;We’re building MonsterJS for developers who want structure without the overhead – and components that &lt;em&gt;just work&lt;/em&gt;.&lt;/p&gt;




&lt;h3&gt;
  
  
  ✅ TL;DR
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Monster Select now supports full pagination&lt;/li&gt;
&lt;li&gt;Works with async data and remote filtering&lt;/li&gt;
&lt;li&gt;Open Source at &lt;a href="https://monsterjs.org" rel="noopener noreferrer"&gt;monsterjs.org&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it out. Fork it. Break it. Or build on top of it.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>ux</category>
    </item>
    <item>
      <title>MonsterJS v4 has landed – and it’s hungry.</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Sun, 11 May 2025 09:58:18 +0000</pubDate>
      <link>https://dev.to/schukai/monsterjs-v4-has-landed-and-its-hungry-2aej</link>
      <guid>https://dev.to/schukai/monsterjs-v4-has-landed-and-its-hungry-2aej</guid>
      <description>&lt;p&gt;We’ve released version 4 of our JavaScript component library, and yes, it’s packed with features that’ll make your inner frontend dev do a little dance (even if it’s in Vim).&lt;/p&gt;

&lt;p&gt;What’s new in the Monster’s lair?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🧮 &lt;strong&gt;Datatables&lt;/strong&gt; – Show off your data like it deserves, with sorting, paging, and built-in flexibility.&lt;/li&gt;
&lt;/ul&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%2Fcyl34a1y1gteri1ic3k5.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%2Fcyl34a1y1gteri1ic3k5.png" alt="datatable example" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔍 &lt;strong&gt;Select with remote filtering&lt;/strong&gt; – Hook it to your API, and let users type, search, and select without any awkward full-list dropdowns.&lt;/li&gt;
&lt;/ul&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%2Fp80t3vps80vrxo3wp2di.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%2Fp80t3vps80vrxo3wp2di.png" alt="Select / dropdown" width="558" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📅 &lt;strong&gt;Monthly calendar&lt;/strong&gt; – Clean, snappy, and ready to display all your timelines and events.&lt;/li&gt;
&lt;li&gt;🧱 &lt;strong&gt;Drag-and-drop grid&lt;/strong&gt; – For the moments when you want users to rearrange reality.&lt;/li&gt;
&lt;li&gt;✨ &lt;strong&gt;…and much more&lt;/strong&gt; – Yes, we mean it. This release refines performance, improves accessibility, and adds polish all over the place.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Give the Monster a chance. It doesn’t bite (unless your code has no semicolons).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm i @schukai/monster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Docs, demos, and more goodies live at: &lt;a href="https://monsterjs.org" rel="noopener noreferrer"&gt;https://monsterjs.org&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Shadow DOM Perfected: Experience the Power of Monster 3.100!</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Sun, 12 Jan 2025 19:48:54 +0000</pubDate>
      <link>https://dev.to/schukai/shadow-dom-perfected-experience-the-power-of-monster-3100-18ii</link>
      <guid>https://dev.to/schukai/shadow-dom-perfected-experience-the-power-of-monster-3100-18ii</guid>
      <description>&lt;p&gt;The Shadow DOM is, in our opinion, one of the most exciting new features in modern HTML engines. This concept enables a much better encapsulation and protection of implementation details than ever before, resulting in cleaner and more maintainable code.&lt;/p&gt;

&lt;p&gt;What is your opinion of the &lt;a href="https://dev.to/schukai/understanding-shadow-dom-and-shadow-roots-in-javascript-a-simple-guide-for-beginners-4479"&gt;shadowroot&lt;/a&gt;?&lt;/p&gt;

&lt;p&gt;Our JavaScript library is built on this principle and offers a comprehensive range of components—everything from sliders and tabs to select controls and data tables. The use of Shadow DOM ensures that our components are not only modular but also highly resilient against styling or scripting conflicts, making them ideal for large-scale applications.&lt;/p&gt;

&lt;p&gt;Beyond Shadow DOM, we leverage cutting-edge JavaScript, CSS, and HTML features to create a seamless developer experience. For example, our components take full advantage of JavaScript &lt;strong&gt;Proxy&lt;/strong&gt; objects to enable fine-grained control over state management, making debugging and data tracking more intuitive. CSS custom properties and container queries allow us to deliver responsive and highly customizable designs out of the box, while modern HTML APIs like the &lt;code&gt;IntersectionObserver&lt;/code&gt; ensure performance stays top-notch, even with complex UI elements.&lt;/p&gt;

&lt;p&gt;With the release of &lt;strong&gt;Monster&lt;/strong&gt; version 3.100, we’ve once again raised the bar with notable improvements:  &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%2Ffvya49tm266zy1v5p4nm.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%2Ffvya49tm266zy1v5p4nm.png" alt="the slider control" width="689" height="407"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The slider component now supports displaying multiple slides simultaneously, a much-requested feature that enhances usability and visual appeal.&lt;/li&gt;
&lt;/ul&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%2F5xupg5fe5zgv03c88ktr.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%2F5xupg5fe5zgv03c88ktr.png" alt="the select control" width="785" height="257"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The select control has been optimized to handle dynamic loading of values and options more efficiently, offering smoother performance in highly dynamic environments.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These updates, combined with our use of the latest web technologies, underscore our commitment to delivering flexible, robust, and feature-rich tools for modern web development. &lt;/p&gt;

&lt;p&gt;And the best thing is that it's all open source.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Introducing the New Version of Monster Components: Power Up Your Development Workflow</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Fri, 15 Nov 2024 14:31:15 +0000</pubDate>
      <link>https://dev.to/schukai/introducing-the-new-version-of-monster-components-power-up-your-development-workflow-4b3k</link>
      <guid>https://dev.to/schukai/introducing-the-new-version-of-monster-components-power-up-your-development-workflow-4b3k</guid>
      <description>&lt;p&gt;We’re excited to announce the latest version of our &lt;strong&gt;Monster&lt;/strong&gt; component library, packed with enhancements designed to make your developer life easier. Whether you’re building complex applications or refining a simple interface, Monster.js offers tools to save time and improve results.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Highlights from the New Release
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;strong&gt;Datatable: Structured Data Visualization Made Easy&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;Our &lt;strong&gt;Datatable&lt;/strong&gt; component is a game-changer for handling structured data. With its intuitive API and seamless integration, you can quickly transform raw data into interactive and visually appealing tables. Explore its features &lt;a href="https://monsterjs.org/components.datatable.datatable.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&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%2F0wtrakyhbnynxseol3sp.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%2F0wtrakyhbnynxseol3sp.png" alt="datatable screenshot" width="800" height="319"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;And &lt;strong&gt;battery included&lt;/strong&gt; is the dark mode, so you don’t have to worry about it.&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%2F7pkxqsuobn41n20sojf6.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%2F7pkxqsuobn41n20sojf6.png" alt="datatable with dark mode" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And of course, there’s built-in support for small screens as well.&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%2Fzl6w0n0eeu40kqp2bwt9.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%2Fzl6w0n0eeu40kqp2bwt9.png" alt="built-in support for small screens" width="734" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Monster?
&lt;/h3&gt;

&lt;p&gt;On &lt;strong&gt;&lt;a href="https://monsterjs.org" rel="noopener noreferrer"&gt;monsterjs.org&lt;/a&gt;&lt;/strong&gt;, you’ll find a rich collection of components and features tailored for developers. From layout tools to advanced UI controls, Monster.js is built to simplify your workflow while giving you the flexibility to create.  &lt;/p&gt;

&lt;p&gt;Start exploring today and take your projects to the next level!  &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>html</category>
      <category>dom</category>
    </item>
    <item>
      <title>Custom Function Integration in Element Updater with MonsterJS</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Fri, 01 Mar 2024 11:49:45 +0000</pubDate>
      <link>https://dev.to/schukai/custom-function-integration-in-element-updater-with-monsterjs-3blp</link>
      <guid>https://dev.to/schukai/custom-function-integration-in-element-updater-with-monsterjs-3blp</guid>
      <description>&lt;p&gt;MonsterJS introduces a flexible way to enhance the functionality of Element Updaters by allowing the attachment of custom functions. This feature provides developers with the ability to extend the standard behavior of Element Updaters, tailoring them to specific needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementing &lt;code&gt;updaterPipeCallbacks&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;To integrate custom functions with Element Updaters, a control must implement the &lt;code&gt;updaterPipeCallbacks&lt;/code&gt; method. This method should return an object containing key-value pairs, where the key is a unique name for the callback, and the value is the function itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  Example Implementation
&lt;/h3&gt;

&lt;p&gt;Here's an example of how you can define a custom function within a control using &lt;code&gt;onUpdaterPipeCallbacks&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;updaterPipeCallbacks&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;my-callback-doing&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="nx"&gt;value&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="k"&gt;switch &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="nl"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&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;In this example, the &lt;code&gt;my-callback-doing&lt;/code&gt; function checks the type of the input value and modifies it based on its type:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the value is a string, it appends an exclamation mark.&lt;/li&gt;
&lt;li&gt;If the value is a number, it increments the value by one.&lt;/li&gt;
&lt;li&gt;For other types, it returns the value unmodified.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Using Custom Functions in Templates
&lt;/h2&gt;

&lt;p&gt;Once you've defined your custom functions, you can invoke them in your control's template using the &lt;code&gt;call&lt;/code&gt; command within the data binding expression.&lt;/p&gt;

&lt;h3&gt;
  
  
  Template Integration Example
&lt;/h3&gt;

&lt;p&gt;Here's how you can incorporate the &lt;code&gt;my-callback-doing&lt;/code&gt; function into a control's template:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-monster-replace=&lt;/span&gt;&lt;span class="s"&gt;"path:options | index:label | call:my-callback-doing"&lt;/span&gt; &lt;span class="na"&gt;part=&lt;/span&gt;&lt;span class="s"&gt;"option-label"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this template snippet, the &lt;code&gt;data-monster-replace&lt;/code&gt; attribute is used to dynamically update the content of the &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt;. The &lt;code&gt;call:my-callback-doing&lt;/code&gt; part specifies that the &lt;code&gt;my-callback-doing&lt;/code&gt; function should be applied to the value obtained from &lt;code&gt;path:options | index:label&lt;/code&gt;.&lt;/p&gt;

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

&lt;p&gt;By leveraging the &lt;code&gt;updaterPipeCallbacks&lt;/code&gt; method, developers can create more dynamic and flexible web components with MonsterJS. Custom functions provide a powerful way to enhance the interactivity and responsiveness of your web applications, ensuring that you can cater to a wide array of use cases and scenarios.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>html</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Unleashing the Power of Dynamic Web Content with Monster Templating</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Sun, 25 Feb 2024 16:36:35 +0000</pubDate>
      <link>https://dev.to/schukai/unleashing-the-power-of-dynamic-web-content-with-monster-templating-22oa</link>
      <guid>https://dev.to/schukai/unleashing-the-power-of-dynamic-web-content-with-monster-templating-22oa</guid>
      <description>&lt;p&gt;In the ever-evolving landscape of web development, creating dynamic and interactive web applications is more crucial than ever. Enter Monster Templating, a modern and powerful DOM-based templating system that seamlessly integrates your data with the document object model (DOM). This guide delves into the heart of Monster Templating, unveiling how it can transform your HTML into a dynamic, data-driven powerhouse with minimal coding effort.&lt;/p&gt;

&lt;h2&gt;
  
  
  Embarking on the Monster Templating Journey
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The First Steps: Importing the Updater Class
&lt;/h3&gt;

&lt;p&gt;Our adventure begins with the integration of the Updater class from Monster's CDN, a simple yet pivotal step towards unlocking dynamic content creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Updater&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;https://cdn.skypack.dev/@schukai/monster@latest/source/dom/updater.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Setting the Stage: Preparing Your HTML Document
&lt;/h3&gt;

&lt;p&gt;Monster Templating thrives on flexibility, allowing you to inject data-binding attributes directly into your HTML or dynamically through JavaScript. This dual approach caters to diverse development styles and project requirements:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;body&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;querySelector&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;body&lt;/span&gt;&lt;span class="dl"&gt;'&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;headline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createElement&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;h1&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-monster-replace&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path:headline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;appendChild&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or, embed directly in your HTML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;data-monster-replace=&lt;/span&gt;&lt;span class="s"&gt;"path:headline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bringing Data to Life: Setting Up Data Binding
&lt;/h3&gt;

&lt;p&gt;With Monster, your data becomes the soul of your application, dynamically updating your HTML in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;obj&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headline&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Go!&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;updater&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Updater&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;obj&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;subject&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;updater&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getSubject&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// For real-time updates&lt;/span&gt;
&lt;span class="nx"&gt;updater&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Demonstrating the magic of dynamic updates, we see how effortlessly the content evolves:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;setTimeout&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="nx"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;headline&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Hello!&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="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Exploring the Enchanted Forest of Templating Features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  The Magic Wand: Content Replacement
&lt;/h3&gt;

&lt;p&gt;Monster's &lt;code&gt;data-monster-replace&lt;/code&gt; attribute stands as your magic wand, enabling you to replace content effortlessly, adding a sprinkle of transformational magic when needed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-monster-replace=&lt;/span&gt;&lt;span class="s"&gt;"static:HELLO | tolower"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Alchemist's Lab: Attribute Manipulation
&lt;/h3&gt;

&lt;p&gt;Transform and concoct new attributes with the &lt;code&gt;data-monster-attributes&lt;/code&gt; attribute, an alchemist's lab where new properties are forged:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-monster-attributes=&lt;/span&gt;&lt;span class="s"&gt;"id static:myid, class static:myclass"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;hello&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Vanishing Acts: Element Removal
&lt;/h3&gt;

&lt;p&gt;With &lt;code&gt;data-monster-remove&lt;/code&gt;, elements disappear from the DOM, a reminder of the impermanence of content in the dynamic web era:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;data-monster-remove&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Conjurer's Trick: Dynamic Element Insertion
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;data-monster-insert&lt;/code&gt; reveals the conjurer's trick, materializing elements from thin air (or data), showcasing the templating system's strongest feature:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;ol&lt;/span&gt; &lt;span class="na"&gt;data-monster-insert=&lt;/span&gt;&lt;span class="s"&gt;"myid path:a"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/ol&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Two-Way Mirror: Data Binding for Input Elements
&lt;/h3&gt;

&lt;p&gt;Monster introduces a two-way mirror with &lt;code&gt;data-monster-bind&lt;/code&gt;, where input fields and data models reflect and influence each other:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"text"&lt;/span&gt; &lt;span class="na"&gt;data-monster-bind=&lt;/span&gt;&lt;span class="s"&gt;"path:a.b"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Grand Library of Data Types
&lt;/h2&gt;

&lt;p&gt;As we delve deeper into the enchanted forest, we uncover a grand library of data types, each with its own unique charm and function. From casting numeric spells with &lt;code&gt;number&lt;/code&gt; to weaving complex structures with &lt;code&gt;object&lt;/code&gt;, Monster Templating accommodates a diverse array of data types, ensuring your web applications are as dynamic and versatile as the world they inhabit.&lt;/p&gt;

&lt;h2&gt;
  
  
  Epilogue
&lt;/h2&gt;

&lt;p&gt;Monster Templating doesn't reinvent web development, but it is a lightweight alternative. The real adventure lies in applying these principles to your projects to transform static HTML into living, breathing web applications that respond and evolve with your users' interactions.&lt;/p&gt;

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

</description>
      <category>javascript</category>
      <category>webdev</category>
      <category>html</category>
    </item>
    <item>
      <title>The awakening of the monster</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Sun, 05 Nov 2023 15:52:35 +0000</pubDate>
      <link>https://dev.to/schukai/the-awakening-of-the-monster-53jk</link>
      <guid>https://dev.to/schukai/the-awakening-of-the-monster-53jk</guid>
      <description>&lt;p&gt;We are pleased to announce the latest development in our JavaScript project: the release of the latest Monster library (3.52). &lt;/p&gt;

&lt;p&gt;This release marks an important milestone in the development of our web initiative by combining our previously separate components into a single, robust package.&lt;/p&gt;

&lt;h3&gt;
  
  
  A look at the past
&lt;/h3&gt;

&lt;p&gt;In the past, you had to manage multiple dependencies within the &lt;code&gt;@schukai&lt;/code&gt; ecosystem, such as &lt;code&gt;@schukai/component-form&lt;/code&gt; and other individual packages. &lt;/p&gt;

&lt;p&gt;While these modules served their purpose, they also introduced complexity when it came to version control, dependency management, and overall project coherence.&lt;/p&gt;

&lt;h3&gt;
  
  
  What's new in @schukai/monster?
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;@schukai/monster&lt;/code&gt; library simplifies the development workflow by bringing all the high quality components you rely on under one roof. &lt;/p&gt;

&lt;p&gt;What you can expect:&lt;/p&gt;

&lt;p&gt;Unified code base: A single NPM package is managed, resulting in smoother updates and integrations.&lt;/p&gt;

&lt;p&gt;Streamlined development: With everything in one place, you'll spend less time juggling packages and more time building great applications.&lt;/p&gt;

&lt;p&gt;Improved performance: We've optimized internal dependencies and ensured that the unified library meets or exceeds each package's performance benchmarks.&lt;/p&gt;

&lt;p&gt;Seamless integration: The transition to &lt;code&gt;@schukai/monster&lt;/code&gt;  has been made as seamless as possible, requiring minimal changes to existing projects.&lt;/p&gt;

&lt;p&gt;To make the transition easier for you, we have created a comprehensive migration guide. Here are the main steps to get you started:&lt;/p&gt;

&lt;p&gt;Refactor your import directives to reference @schukai/monster.&lt;/p&gt;

&lt;p&gt;Follow the detailed instructions for any specific components that require additional migration steps.&lt;/p&gt;

&lt;h3&gt;
  
  
  Looking to the future
&lt;/h3&gt;

&lt;p&gt;The release of &lt;code&gt;@schukai/monster&lt;/code&gt; is more than just an update - it's a commitment to the future of development in our ecosystem. We will continue to support the library with regular updates, new features and improvements based on your feedback.&lt;/p&gt;

&lt;p&gt;We invite you to use the power and simplicity of &lt;code&gt;@schukai/monster&lt;/code&gt; in your next project. Stay tuned for more updates, and happy coding!&lt;/p&gt;

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

</description>
      <category>webcomponents</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>html</category>
    </item>
    <item>
      <title>YAConfigLib - Dynamic Configurations in Go: Introducing Postprocessing Hooks</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Mon, 14 Aug 2023 15:40:14 +0000</pubDate>
      <link>https://dev.to/schukai/yaconfiglib-dynamic-configurations-in-go-introducing-postprocessing-hooks-mg8</link>
      <guid>https://dev.to/schukai/yaconfiglib-dynamic-configurations-in-go-introducing-postprocessing-hooks-mg8</guid>
      <description>&lt;p&gt;Hey Gophers! 🚀&lt;/p&gt;

&lt;p&gt;Do you struggle with configuration files in different formats like JSON, YAML or TOML in your Go applications? If yes, then you appreciate the value of a robust configuration management library. &lt;/p&gt;

&lt;p&gt;Today we released a brand new feature in our configuration library.&lt;/p&gt;

&lt;p&gt;We present: Postprocessing Hooks! 🌟&lt;/p&gt;

&lt;p&gt;Imagine, you can not only read configurations in different formats, but now you can also define hooks that are triggered directly when a configuration change is made. Previously, you could also solve this via ChangeHooks, but these ran in their own Go routine.&lt;/p&gt;

&lt;p&gt;The decisive advantage for tasks such as&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Changing paths based on new configurations.&lt;/li&gt;
&lt;li&gt;Building new structures after loading configurations.&lt;/li&gt;
&lt;li&gt;Integrating real-time responses to dynamic configurations into your application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why should you try the new feature of our configuration library?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Flexibility: read and manage configurations in YAML, TOML and JSON.&lt;/li&gt;
&lt;li&gt;Reactivity: Real-time actions based on dynamic configuration changes.&lt;/li&gt;
&lt;li&gt;Powerful: Efficient handling without the overhead of additional routines.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We are convinced that after your first experience with Postprocessing Hooks, you will wonder how you ever got along without it!&lt;/p&gt;

&lt;p&gt;Try it out, share your feedback and let's improve dynamic configurations in Go together!&lt;/p&gt;

&lt;p&gt;Stay tuned for more exciting updates. Have a great time programming! 🎉&lt;/p&gt;

&lt;p&gt;&lt;a href="https://gitlab.schukai.com/oss/libraries/go/application/configuration" rel="noopener noreferrer"&gt;https://gitlab.schukai.com/oss/libraries/go/application/configuration&lt;/a&gt;&lt;/p&gt;

</description>
      <category>go</category>
      <category>webdev</category>
      <category>config</category>
      <category>devops</category>
    </item>
    <item>
      <title>Remote Brew: The Secret Blend of Team Bonding and Communication</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Sun, 23 Apr 2023 15:41:54 +0000</pubDate>
      <link>https://dev.to/schukai/virtual-coffee-machine-chat-how-remote-teams-informally-come-together-and-communicate-194b</link>
      <guid>https://dev.to/schukai/virtual-coffee-machine-chat-how-remote-teams-informally-come-together-and-communicate-194b</guid>
      <description>&lt;p&gt;Imagine you are an entrepreneur, executive, or part of a team that has been working remotely since the start of the pandemic. In this new work environment, you and your colleagues are seeking ways to maintain informal exchanges and a sense of community despite the physical distance. This article explores how virtual coffee breaks and casual coworking can help achieve that.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenge
&lt;/h2&gt;

&lt;p&gt;Our company had already successfully transitioned to remote work before the pandemic, and we were fortunate to not have to learn it the hard way.&lt;/p&gt;

&lt;p&gt;However, over the past few years, we have also faced many challenges such as the lack of informal exchange moments that used to occur around the coffee machine or during lunch breaks. This has led to employees feeling more isolated and less connected to one another."&lt;/p&gt;

&lt;h2&gt;
  
  
  One, Two or Many Ideas
&lt;/h2&gt;

&lt;p&gt;We have devoted considerable thought to addressing and improving this challenge. We have explored many potential approaches and discarded them. One current idea involves creating a virtual space where the team can meet spontaneously and informally, much like a real coffee break.&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%2Fpdt27t3bs5grsd20xnn8.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%2Fpdt27t3bs5grsd20xnn8.png" alt=" " width="800" height="1132"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How can this be implemented technically and organizationally? We have experimented with various methods.&lt;/p&gt;

&lt;p&gt;To address the challenge of fostering casual exchanges between remote team members, we took a hopefully simple approach by creating a virtual "water cooler" or "coffee break room." This room is technically implemented as a zoom room. The ambience is designed to be appealing and inviting. It also integrates seamlessly with our favorite communication tools such as instant messaging platforms.&lt;/p&gt;

&lt;p&gt;We encourage all team members to seek out this space when they are taking a break, chatting with colleagues, or just looking for a moment to relax. We see this virtual space as a means to recreate the spontaneous interactions that used to take place in the office, fostering a sense of community and connection among team members.&lt;/p&gt;

&lt;p&gt;So far, we are enthusiastic about the potential of virtual coffee chats and plan to explore additional possibilities in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  And Now for Something Completely Different
&lt;/h2&gt;

&lt;p&gt;In addition to the virtual coffee machine, we are testing another concept.&lt;/p&gt;

&lt;p&gt;We also regularly schedule informal virtual events and team-building activities, such as virtual happy hours and game nights. These events are designed to be fun and help team members get to know each other better in a relaxed and informal setting. &lt;/p&gt;

&lt;p&gt;By combining the virtual water cooler with these regular virtual events, we seek to cultivate a sense of social cohesion and support to help mitigate the challenges of telecommuting and foster a positive work culture.&lt;/p&gt;

&lt;h2&gt;
  
  
  Casual coworking
&lt;/h2&gt;

&lt;p&gt;We work together casually by inviting two or three team members to at least one-hour sessions. After a brief greeting, the cameras are turned off. The microphone and speakers, however, remain on. Everyone starts working.&lt;/p&gt;

&lt;p&gt;If someone needs to discuss something, they can turn on their camera as needed. &lt;/p&gt;

&lt;p&gt;At the end of the session, there is a virtual goodbye, and we exchange information about work and personal matters.&lt;/p&gt;

&lt;p&gt;Unlike pair programming or collaboration, the focus here is not on working together on a project. People can even work on different tasks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The structure:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Casual coworking with scheduled one-hour sessions&lt;/li&gt;
&lt;li&gt;Focus on individual work with the option for brief interactions&lt;/li&gt;
&lt;li&gt;Virtual goodbye and exchange of information at the end of each session&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Our previous experiences indicate that virtual coffee breaks and casual coworking can be effective. However, it's crucial to ensure that the framework is appropriate and to continue refining the formats.&lt;/p&gt;

&lt;p&gt;In an era where distance and remote work define the daily routines of many people, it is more important than ever to find ways to maintain a sense of community and informal exchange. Virtual coffee breaks and casual coworking are two examples of how this can be achieved.&lt;/p&gt;




&lt;p&gt;Hey there! Have you had any experiences like this or maybe some cool, innovative ideas of your own? We'd love to hear about them in the comments below. Your positive feedback means a lot to us, so let's chat&lt;/p&gt;

</description>
      <category>management</category>
      <category>motivation</category>
      <category>startup</category>
    </item>
    <item>
      <title>Understanding Shadow DOM and Shadow Roots in JavaScript: A Simple Guide for Beginners</title>
      <dc:creator>Volker Schukai</dc:creator>
      <pubDate>Thu, 30 Mar 2023 21:30:05 +0000</pubDate>
      <link>https://dev.to/schukai/understanding-shadow-dom-and-shadow-roots-in-javascript-a-simple-guide-for-beginners-4479</link>
      <guid>https://dev.to/schukai/understanding-shadow-dom-and-shadow-roots-in-javascript-a-simple-guide-for-beginners-4479</guid>
      <description>&lt;p&gt;As part of development on the Monster open-source project, our developers often use the powerful Shadow DOM technology to create complex components. This article aims to provide a concise explanation of what Shadow DOM is all about and how knowledge of it can be beneficial when working with Monster components. We will also explore the basics of the Shadow Roots API in JavaScript, which is an essential part of the Web Components standard and allows the creation of encapsulated, reusable components. With the help of a simple example, beginners will find it easier to understand and apply these concepts in their projects.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Shadow DOM?
&lt;/h2&gt;

&lt;p&gt;Shadow DOM is a powerful web standard that lets you create encapsulated HTML, CSS, and JavaScript in your web components. It lets you create self-contained components whose internal structure, style, and behavior remain separate from the main DOM tree. This separation ensures that the styles and scripts within a component do not interfere with other elements on the page.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a Shadow Root?
&lt;/h2&gt;

&lt;p&gt;A Shadow Root is the root element of a Shadow DOM tree. It is attached to a host element, which is a regular DOM element. The Shadow Root acts as a boundary between the host element and the Shadow DOM, providing encapsulation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Creating a Shadow Root:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To create a Shadow Root, you can use the &lt;code&gt;attachShadow()&lt;/code&gt; method on a DOM element. This method takes an object with a single property, mode, which can be set to either 'open' or 'closed'. An open Shadow Root can be accessed using JavaScript, while a closed one cannot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;style&amp;gt;&lt;/span&gt;
    &lt;span class="nc"&gt;.container&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nl"&gt;border&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="no"&gt;black&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10px&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/style&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;class=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"container"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getElementById&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;container&lt;/span&gt;&lt;span class="dl"&gt;"&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;shadowRoot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;container&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;attachShadow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;open&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="nx"&gt;shadowRoot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;innerHTML&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`
      &amp;lt;style&amp;gt;
        p {
          color: red;
        }
      &amp;lt;/style&amp;gt;
      &amp;lt;p&amp;gt;Hello, Shadow DOM!&amp;lt;/p&amp;gt;
    `&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we create a Shadow Root attached to a &lt;code&gt;&amp;lt;div&amp;gt;&lt;/code&gt; element with the class "container". Inside the Shadow Root, we define a &lt;code&gt;&amp;lt;style&amp;gt;&lt;/code&gt; block with a rule for &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; elements and a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; element with the text "Hello, Shadow DOM!". The style defined inside the Shadow Root applies only to elements within the Shadow Root and does not affect the main DOM.&lt;/p&gt;

&lt;p&gt;Understanding Shadow DOM and Shadow Roots in JavaScript is essential for developers starting to work with Web Components. The encapsulation they provide helps create reusable, self-contained components that do not interfere with the main DOM tree. With this simple guide and example, you should now have a solid foundation for working with Shadow DOM and Shadow Roots in your projects.&lt;/p&gt;

&lt;p&gt;There is still a lot to say about this topic, as the world of Shadow DOM and Web Components continues to evolve. If you have any questions or need further clarification, please feel free to post them in the comments section. We'll be more than happy to help you on your journey to mastering Shadow DOM and creating incredible web components.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM" rel="noopener noreferrer"&gt;https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_shadow_DOM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://dev.to/schukai/get-to-know-the-monster-button-bar-5c7l"&gt;https://dev.to/schukai/get-to-know-the-monster-button-bar-5c7l&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>javascript</category>
      <category>dom</category>
      <category>html</category>
    </item>
  </channel>
</rss>
