Agent skill

Create Custom Widget

by mendixlabs in mendixlabs/mxcli

Build a Mendix pluggable widget from scratch with React and TypeScript and package it as an .mpk.

Apache-2.0Auto-check passedFrontend & Design

Install Create Custom Widget

skills CLI
$ npx skills add mendixlabs/mxcli --skill create-custom-widget -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install mendixlabs/mxcli create-custom-widget --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/mendixlabs/mxcli.git skills-src && mkdir -p .claude/skills && cp -r skills-src/.claude/skills/mendix/create-custom-widget .claude/skills/create-custom-widget && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
create-custom-widget
GitHub stars
128
Token cost
~3.3k tokens
SKILL.md length
597 words
Files
1
Skills in repo
72
Repo updated
First seen
Licence
Apache-2.0

At a glance

Build a Mendix pluggable widget from scratch with React and TypeScript and package it as an .mpk.

  • Works in 8 steps: Scaffold the Project → Define Widget Properties (widget.xml) → Write the Entry Component → …
  • Built-in widget covers what is needed and a custom React component has to be written
  • SKILL.md covers Prerequisites, Step 1: Scaffold the Project, Step 2: Define Widget… and Step 3: Write the Entry…, plus 6 more sections
  • Calls npm; reaches mendix.com and w3.org

What it does

Create Custom Widget is an agent skill from mendixlabs/mxcli. Build a Mendix pluggable widget from scratch with React and TypeScript and package it as an .mpk. Use when no marketplace or built-in widget covers what is needed and a custom React component has to be written.

Its SKILL.md is about 3.3k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.

It sits in Frontend & Design, covering React components. It works with TypeScript, React and npm. The repository describes itself as: Mendix cli tool, a headless way to work with Mendix projects. Enables Mendix projects for use with 3rd party agentic coding tools like Claude Code and Copilot. Includes a… The licence is Apache-2.0.

When your agent uses it

  • Built-in widget covers what is needed and a custom React component has to be written
  • Tasks that involve React components

Example prompts

  • “/create-custom-widget”

Requirements

  • Node.js

Workflow steps

8 steps, taken from the step headings in SKILL.md.

  1. Scaffold the Project
  2. Define Widget Properties (widget.xml)
  3. Write the Entry Component
  4. Write the React Component
  5. Editor Config (optional but recommended)
  6. CSS Styles
  7. Build
  8. Install to Mendix Project

What it can do on your machine

Read from SKILL.md and the folder at commit 20a6c89. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Shell commands in SKILL.md call:

    • npm

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    Hosts in commands or code, which the agent is likely to contact:

    • mendix.com
    • w3.org

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names no API keys, tokens, secrets or passwords.

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Create Custom Widget loads about 3.3k tokens when it runs. Until then it costs about 58 tokens; SKILL.md has 597 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~58
When it runs · the whole SKILL.md, loaded when a task matches
~3.3k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.

SKILL.md

The full file from mendixlabs/mxcli at commit 20a6c89, republished under its Apache-2.0 licence (© mendixlabs). 597 words, ~3,322 tokens.

Download SKILL.mdSave it as .claude/skills/create-custom-widget/SKILL.md (or your agent's skills folder).
name
create-custom-widget
description
Build a Mendix pluggable widget from scratch with React and TypeScript and package it as an .mpk. Use when no marketplace or built-in widget covers what is needed and a custom React component has to be written.

Create Custom Pluggable Widget

Build a Mendix pluggable widget from scratch using React + TypeScript. Produces a .mpk file ready for Studio Pro.

Prerequisites

  • Node.js >= 16
  • npm

Step 1: Scaffold the Project

Create a directory and generate all source files. Use PascalCase for the widget name.

bash
mkdir -p <WidgetName>/src/components <WidgetName>/src/ui
package.json
json
{
  "name": "<widget-name>",
  "widgetName": "<WidgetName>",
  "version": "1.0.0",
  "description": "<description>",
  "license": "Apache-2.0",
  "config": {
    "projectPath": "./tests/testProject",
    "mendixHost": "http://localhost:8080",
    "developmentPort": 3000
  },
  "packagePath": "com.example.widgets",
  "scripts": {
    "dev": "pluggable-widgets-tools start:web",
    "build": "pluggable-widgets-tools build:web",
    "lint": "pluggable-widgets-tools lint",
    "lint:fix": "pluggable-widgets-tools lint:fix"
  },
  "devDependencies": {
    "@mendix/pluggable-widgets-tools": "^11.6.0",
    "@types/big.js": "^6.0.2"
  },
  "dependencies": {
    "classnames": "^2.2.6"
  },
  "resolutions": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0"
  },
  "overrides": {
    "react": "^19.0.0",
    "react-dom": "^19.0.0",
    "@types/react": "^19.0.0",
    "@types/react-dom": "^19.0.0"
  }
}

Naming rules:

  • name: kebab-case (npm package name)
  • widgetName: PascalCase (matches .xml and .tsx filename)
  • packagePath: reverse domain, dot-separated (e.g. com.example.widgets)
tsconfig.json
json
{
  "extends": "./node_modules/@mendix/pluggable-widgets-tools/configs/tsconfig.base.json"
}
src/package.xml
xml
<?xml version="1.0" encoding="utf-8" ?>
<package xmlns="http://www.mendix.com/package/1.0/">
    <clientModule name="<WidgetName>" version="1.0.0" xmlns="http://www.mendix.com/clientModule/1.0/">
        <widgetFiles>
            <widgetFile path="<WidgetName>.xml"/>
        </widgetFiles>
        <files>
            <file path="com/example/widgets/<widgetname>"/>
        </files>
    </clientModule>
</package>

The <file path> must match packagePath + lowercase widget name, with dots replaced by /. For example, for HelloWorld with packagePath=com.example.widgets, the path is com/example/widgets/helloworld.

Step 2: Define Widget Properties (widget.xml)

src/<WidgetName>.xml
xml
<?xml version="1.0" encoding="utf-8"?>
<widget id="com.example.widgets.<widgetname>.<WidgetName>"
        pluginWidget="true"
        needsEntityContext="true"
        offlineCapable="true"
        supportedPlatform="Web"
        xmlns="http://www.mendix.com/widget/1.0/"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.mendix.com/widget/1.0/ ../node_modules/mendix/custom_widget.xsd">
    <name><widget Name></name>
    <description><description></description>
    <icon/>
    <properties>
        <propertyGroup caption="General">
            <!-- Add properties here -->
        </propertyGroup>
    </properties>
</widget>

The id attribute must be <packagePath>.<widgetname>.<WidgetName> — the second-to-last segment is the lowercase widget name, which becomes the JS subdirectory. This must match the <file path> in package.xml.

Set needsEntityContext="true" when the widget needs entity data. Set to "false" for standalone widgets.

Property Type Reference
XML TypeMendix TypeUse CaseExample
stringStatic textLabels, titles<property key="title" type="string"><caption>title</caption></property>
booleanToggleShow/hide, enable<property key="showHeader" type="boolean" defaultValue="true"><caption>show header</caption></property>
integerNumberCounts, sizes<property key="columns" type="integer" defaultValue="3"><caption>columns</caption></property>
decimalDecimalMeasurements<property key="opacity" type="decimal" defaultValue="1.0"><caption>Opacity</caption></property>
enumerationEnum choiceMode selectionSee below
expressionDynamic valueComputed text<property key="label" type="expression" defaultValue=""><caption>label</caption><returnType type="string"/></property>
textTemplateTemplate textFormatted text with paramsSee below
attributeEntity attributeData bindingSee below
datasourceList data sourceLists, grids<property key="datasource" type="datasource" isList="true"><caption>data source</caption></property>
widgetsChild widgetsContent slots<property key="content" type="widgets" required="false"><caption>content</caption></property>
actionOn-click actionButtons, links<property key="onclick" type="action"><caption>on click</caption></property>
iconIconDecorative<property key="icon" type="icon" required="false"><caption>icon</caption></property>
imageImageAvatar, logo<property key="image" type="image" required="false"><caption>image</caption></property>
objectCompoundComplex configSee below
Enumeration Example
xml
<property key="alignment" type="enumeration" defaultValue="center">
    <caption>Alignment</caption>
    <description/>
    <enumerationValues>
        <enumerationValue key="left">left</enumerationValue>
        <enumerationValue key="center">Center</enumerationValue>
        <enumerationValue key="right">right</enumerationValue>
    </enumerationValues>
</property>
Attribute Binding Example
xml
<property key="value" type="attribute">
    <caption>value</caption>
    <description>The attribute to display</description>
    <attributeTypes>
        <attributeType name="string"/>
        <attributeType name="integer"/>
        <attributeType name="decimal"/>
    </attributeTypes>
</property>
TextTemplate Example
xml
<property key="displayText" type="textTemplate">
    <caption>display text</caption>
    <description/>
    <translations>
        <translation lang="en_US">default text</translation>
    </translations>
</property>
Object (Compound) Example — e.g. column definitions
xml
<property key="columns" type="object" isList="true">
    <caption>columns</caption>
    <description/>
    <properties>
        <propertyGroup caption="column">
            <property key="header" type="textTemplate">
                <caption>header</caption>
                <translations><translation lang="en_US">column</translation></translations>
            </property>
            <property key="attribute" type="attribute" datasource="datasource">
                <caption>attribute</caption>
                <attributeTypes>
                    <attributeType name="string"/>
                    <attributeType name="integer"/>
                </attributeTypes>
            </property>
            <property key="width" type="integer" defaultValue="100">
                <caption>width (px)</caption>
            </property>
        </propertyGroup>
    </properties>
</property>

Note: datasource="datasource" links the attribute picker to the datasource property.

Property Groups

Use nested <propertyGroup> for Studio Pro tab organization:

xml
<properties>
    <propertyGroup caption="General">
        <!-- main properties -->
    </propertyGroup>
    <propertyGroup caption="Appearance">
        <!-- style properties -->
    </propertyGroup>
    <propertyGroup caption="events">
        <!-- action properties -->
    </propertyGroup>
</properties>

Step 3: Write the Entry Component

src/<WidgetName>.tsx
tsx
import { ReactElement } from "react";
import { <WidgetName>ContainerProps } from "../typings/<WidgetName>Props";
import { MyComponent } from "./components/MyComponent";
import "./ui/<WidgetName>.css";

export function <WidgetName>(props: <WidgetName>ContainerProps): ReactElement {
    // map Mendix props to React component props
    return <MyComponent {...relevantProps} />;
}

The typings/<WidgetName>Props.d.ts file is auto-generated by the build tool from the .xml definition. Do NOT create it manually.

Key Mendix Prop Patterns
tsx
// string property
props.title  // string

// boolean property
props.showHeader  // boolean

// expression property
props.label?.value  // string | undefined (use .value to get resolved text)

// attribute property (read)
props.value?.displayValue  // string
props.value?.value  // actual typed value

// attribute property (write)
props.value?.setValue(newValue)

// TextTemplate property
props.displayText?.value  // string (resolved template)

// action property
props.onClick?.canExecute  // boolean
props.onClick?.execute()   // trigger the action

// datasource property
props.dataSource?.items  // ObjectItem[] | undefined
props.dataSource?.status  // "available" | "loading"

// widgets property (content slot)
props.content  // ReactNode

// icon property
import { icon } from "mendix/components/web/icon";
<icon icon={props.icon} />

// object list property (e.g. columns)
props.columns  // Array<{ header, attribute, width }>
// access attribute value for a specific item:
props.columns[0].attribute?.get(item)?.displayValue

Step 4: Write the React Component

src/components/MyComponent.tsx

Keep the component pure React — no Mendix API dependencies. This makes it testable and reusable.

tsx
import { ReactElement } from "react";
import classNames from "classnames";

export interface MyComponentProps {
    title: string;
    value?: string;
    className?: string;
}

export function MyComponent({ title, value, className }: MyComponentProps): ReactElement {
    return (
        <div className={classNames("widget-my-component", className)}>
            <h3>{title}</h3>
            {value && <p>{value}</p>}
        </div>
    );
}
Show full SKILL.md (242 more words)Show less
src/<WidgetName>.editorConfig.ts

Controls how the widget appears in Studio Pro's design mode:

ts
import { <WidgetName>PreviewProps } from "../typings/<WidgetName>Props";

export type properties = PropertyGroup[];
type PropertyGroup = {
    caption: string;
    propertyGroups?: PropertyGroup[];
    properties?: Property[];
};
type Property = {
    key: string;
    caption: string;
    description?: string;
};

export function getProperties(
    _values: <WidgetName>PreviewProps,
    defaultProperties: properties
): properties {
    return defaultProperties;
}

Step 6: CSS Styles

src/ui/<WidgetName>.css
css
.widget-<widget-name> {
    /* widget styles */
}

Use a .widget-<widget-name> prefix to avoid CSS collisions.

Step 7: Build

bash
cd <widget-dir>
npm install
npm run build

Output: dist/<version>/com.example.widgets.<WidgetName>.mpk

Step 8: Install to Mendix Project

bash
cp dist/*/*.mpk /path/to/mendix-project/widgets/

Then open/reload the project in Studio Pro.

Common Widget Patterns

KPI Card

Properties: title (string), value (expression/string), icon (icon), trend (enumeration: up/down/neutral), onclick (action)

Chart Wrapper

Properties: datasource (datasource), valueAttr (attribute/decimal), labelAttr (attribute/string), chartType (enumeration), height (integer)

Wrap a charting library (Chart.js, Recharts) inside the component.

Custom Input

Properties: value (attribute/string, writable), placeholder (string), onchange (action), validation (expression/string)

Set needsEntityContext="true". Use props.value.setValue() for two-way binding.

Layout Component

Properties: content (widgets), columns (integer), gap (integer)

Set needsEntityContext="false". Render children via {props.content}.

Checklist Before Build

  • id in .xml matches packagePath.WidgetName
  • <name> in package.xml matches .xml filename (without extension)
  • <file path> in package.xml matches packagePath with / separators
  • Entry .tsx exports a function with the exact widget name
  • CSS file imported in entry .tsx
  • needsEntityContext matches whether entity data is needed
  • No manual Props.d.ts file (auto-generated by build tool)
  • All expression properties have <returnType>
  • All attribute properties list valid <attributeType> entries
  • object properties with attributes set datasource reference

Troubleshooting

ErrorCauseFix
Cannot find module '../typings/...'Haven't built yetRun npm run build first, types are generated
widget not showing in Studio ProWrong id in XMLEnsure id="packagePath.WidgetName"
CE0463 widget definition changedProperty mismatchEnsure XML and component props match
pluginWidget must be trueMissing attributeAdd pluginWidget="true" to <widget>

© mendixlabs, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

Just SKILL.md in .claude/skills/mendix/create-custom-widget of mendixlabs/mxcli.

Open the folder on GitHubat commit 20a6c89

Compare with similar skills

Create Custom Widget next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Create Custom Widget compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Create Custom Widget this skillmendixlabs/mxcli128—~3.3kAutomated safety check: PassApache-2.0
Spotpatchhuanglvjing/spotpatch134—~998Automated safety check: PassMIT
Frontendstreamband/hydra-srt146—~582Automated safety check: PassApache-2.0
React Emailviclafouch/meme-studio1102 repos~3.6kAutomated safety check: PassMIT
Web Artifacts Builderanthropics/skills180k41 repos~769Automated safety check: PassApache-2.0
GSAP for Reactgreensock/gsap-skills16k4 repos~1.6kAutomated safety check: PassMIT

Similar skills

  • Spotpatch

    huanglvjing/spotpatch

    为 React 项目建立从浏览器页面元素到精确 JSX/TSX 源码、结构化上下文与可审阅修改的 SpotPatch 工作流。用户提到 SpotPatch、截图沟通前端修改、页面元素定位源码、Vite 或 Next.js 接入、组件数据链路、结构化 Prompt、AI 补丁审阅、安装检查或故障排查时使用此技能。

    134 GitHub stars~998 tokensUpdated 10 days ago
    Frontend & DesignAuto-check passed
  • Frontend

    streamband/hydra-srt

    A skill your agent uses for frontend work in webapp (React/TypeScript, UI implementation, tests, and refactors).

    146 GitHub stars~582 tokensUpdated 22 days ago
    Frontend & DesignAuto-check passed
  • React Email

    viclafouch/meme-studio

    A skill your agent uses when creating HTML email templates with React components - welcome emails, password resets, notifications, order confirmations, newsletters, or transactional emails.

    110 GitHub starsUsed in 2 repos~3.6k tokens
    Backend & APIsAuto-check passed
  • Web Artifacts Builder

    anthropics/skills

    Official

    Builds multi-component claude.ai HTML artifacts as a small React, TypeScript and Tailwind project, then bundles it into one shareable HTML file.

    180k GitHub starsUsed in 41 repos~769 tokens
    Frontend & DesignAuto-check passed
  • GSAP for React

    greensock/gsap-skills

    Shows how to run GSAP animations in React and Next.js with the useGSAP hook, refs, scoped selectors and automatic cleanup on unmount.

    16k GitHub starsUsed in 4 repos~1.6k tokens
    Frontend & DesignAuto-check passed
  • Use when implementing or refactoring React/TypeScript components and the task requires decisions about component ownership, feature boundaries, state, data…

    158k GitHub stars~626 tokensUpdated today
    Frontend & DesignAuto-check passed

More from mendixlabs/mxcli

All 72 skills in this repo
  • Mendix Odata Pushdown

    mendixlabs/mxcli

    Push OData query options into the SQL of a Mendix resource served by a read microflow, so $filter, $orderby, $top, $skip, $count and the key lookup reach the database instead of being silently…

    128 GitHub stars~2.5k tokensUpdated today
    Auto-check passed
  • Mendix Vega Charts

    mendixlabs/mxcli

    Chart a Mendix app with Vega-Lite through a pluggable widget that takes the specification and the data as separate properties, so the model emits rows and never assembles a chart payload.

    128 GitHub stars~3k tokensUpdated today
    Auto-check passed
  • Agents

    mendixlabs/mxcli

    Author Mendix AI agent documents in MDL — Model, Knowledge Base, Consumed MCP Service and Agent, with variables, tools and multi-line prompts.

    128 GitHub starsUsed in 1 repo~2.2k tokens
    Auto-check passed
  • Mendix Bulk Oql Dml

    mendixlabs/mxcli

    Run set-based INSERT, UPDATE and DELETE against Mendix entities through OQL statements, which the runtime supports and Studio Pro cannot author.

    128 GitHub stars~1.4k tokensUpdated today
    Auto-check passed
  • Business Events

    mendixlabs/mxcli

    Define event-driven APIs over Kafka with Mendix business event services — publish and subscribe contracts, CREATE/DROP/DESCRIBE.

    128 GitHub starsUsed in 1 repo~1.3k tokens
    Auto-check passed
  • Catalog Search

    mendixlabs/mxcli

    Search the Mendix Catalog platform service registry (catalog.mendix.com) from the CLI to find services published across an organisation.

    128 GitHub starsUsed in 1 repo~1.4k tokens
    Auto-check passed

Questions about Create Custom Widget

What does Create Custom Widget do?

Build a Mendix pluggable widget from scratch with React and TypeScript and package it as an .mpk. Create Custom Widget is an agent skill from mendixlabs/mxcli.mpk.

When should I use Create Custom Widget?

Create Custom Widget fits situations like: built-in widget covers what is needed and a custom React component has to be written; tasks that involve React components.

How do I install Create Custom Widget in Claude Code?

Run `npx skills add mendixlabs/mxcli --skill create-custom-widget -a claude-code`. Or copy the skill folder (.claude/skills/mendix/create-custom-widget in mendixlabs/mxcli) into .claude/skills/create-custom-widget in your project. Claude Code loads it when a task matches its description.

How do I install Create Custom Widget in Codex?

Run `npx skills add mendixlabs/mxcli --skill create-custom-widget -a codex`. Or copy the skill folder (.claude/skills/mendix/create-custom-widget in mendixlabs/mxcli) into .agents/skills/create-custom-widget in your project. Codex loads it when a task matches its description.

Can I use Create Custom Widget in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add mendixlabs/mxcli --skill create-custom-widget -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/create-custom-widget, .gemini/skills/create-custom-widget, .github/skills/create-custom-widget and .opencode/skills/create-custom-widget in your project.

What does Create Custom Widget need to run?

Going by SKILL.md and its folder, Create Custom Widget needs the command-line tools its instructions call (npm). Our summary lists: Node.js.

Does Create Custom Widget access the network?

SKILL.md names 2 domains. In commands or code: mendix.com and w3.org; the agent is likely to contact these when it follows the instructions. This is read from the text; nothing was executed.

Is Create Custom Widget safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.

What licence does Create Custom Widget use?

Create Custom Widget is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Create Custom Widget use?

About 3.3k tokens (SKILL.md is roughly 13k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.

What are the alternatives to Create Custom Widget?

Skills that share tags, products or a category with Create Custom Widget: Spotpatch (huanglvjing/spotpatch, 134 stars), Frontend (streamband/hydra-srt, 146 stars), React Email (viclafouch/meme-studio, 110 stars) and Web Artifacts Builder (anthropics/skills, 180k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Create Custom Widget?

mendixlabs (a GitHub organization) maintains it in mendixlabs/mxcli, which has 128 GitHub stars. The repository holds 72 skills in this directory. The repository was last updated on October 7, 2026.

Source: mendixlabs/mxcli on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.