diff --git a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/README.md b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/README.md
new file mode 100644
index 0000000000..bc2ed47bca
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/README.md
@@ -0,0 +1,5 @@
+# UFM Custom Component
+
+This example demonstrates how to write a custom Umbraco-Flavored Markdown (UFM) component.
+
+https://docs.umbraco.com/umbraco-cms/reference/umbraco-flavored-markdown#custom-ufm-components
diff --git a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts
new file mode 100644
index 0000000000..9f4486eb7a
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/custom-ufm-component.ts
@@ -0,0 +1,26 @@
+import { customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import { UmbUfmComponentBase } from '@umbraco-cms/backoffice/ufm';
+import type { UfmToken } from '@umbraco-cms/backoffice/ufm';
+
+export class UmbCustomUfmComponent extends UmbUfmComponentBase {
+ render(token: UfmToken) {
+ // You could do further regular expression/text processing,
+ // then output your custom HTML markup.
+ return ``;
+ }
+}
+
+// eslint-disable-next-line local-rules/enforce-umb-prefix-on-element-name
+@customElement('ufm-custom-component')
+export class UmbCustomUfmComponentElement extends UmbLitElement {
+ @property()
+ text?: string;
+
+ override render() {
+ return html``;
+ }
+}
+
+export { UmbCustomUfmComponent as api };
+export { UmbCustomUfmComponentElement as element };
diff --git a/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts
new file mode 100644
index 0000000000..2da0c936cc
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/examples/ufm-custom-component/index.ts
@@ -0,0 +1,13 @@
+import type { ManifestUfmComponent } from '@umbraco-cms/backoffice/extension-registry';
+
+export const manifests: Array = [
+ {
+ type: 'ufmComponent',
+ alias: 'Umb.CustomUfmComponent',
+ name: 'Custom UFM Component',
+ api: () => import('./custom-ufm-component.js'),
+ meta: {
+ marker: '%',
+ },
+ },
+];
diff --git a/src/Umbraco.Web.UI.Client/src/packages/ufm/index.ts b/src/Umbraco.Web.UI.Client/src/packages/ufm/index.ts
index 6bf7af213f..6ef5cd49bd 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/ufm/index.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/ufm/index.ts
@@ -1,2 +1,3 @@
export * from './components/ufm-render/index.js';
export * from './plugins/marked-ufm.plugin.js';
+export * from './ufm-components/ufm-component-base.js';