Skip to content

Micro Block

This document specifies the Micro-Block extension framework, a universal UI extension solution that enables custom rendering and interaction capabilities. The Micro-Block extension provides a lightweight, single-file UI extension approach that supports React component rendering while maintaining reusability across different environments.

The Micro-Block extension addresses the need for extensible UI capabilities within the Eidos ecosystem while preserving generality for code reuse in other projects. This specification defines a lightweight, single-file UI extension approach that can serve as both a development playground and a production component library.

Micro-Block functions as pure UI components, with Eidos SDK integration available when interaction with Eidos logic is required. Without the Eidos SDK, Micro-Block components behave identically to standard React components.

The framework adopts a single-file component approach to facilitate code reuse across projects. Complex components should be developed using conventional methods, published to npm, and imported as third-party components to maintain separation of concerns and reduce maintenance overhead.

The system provides a build-free (zero-config build) development experience where users can preview changes immediately upon saving, similar to Deno’s development workflow. The framework automatically transforms imports to the latest external package versions, leveraging the npm ecosystem while reducing version management complexity.

The framework uses standard Node.js import syntax while automatically resolving to external packages:

// Standard import syntax
import { Excalidraw } from "@excalidraw/excalidraw"
// Automatically resolved to: https://esm.sh/@excalidraw/excalidraw

Manual version specification is only required when issues arise.

The framework provides seamless integration with Shadcn/ui components, enabling consistent UI styling with the Eidos interface. Components share theme configurations with the main application while supporting independent theme customization.

import { Button } from "@/components/ui/button"

Shadcn/ui’s LLM-friendly architecture facilitates AI-assisted development, enabling code generation for simple scenarios without manual coding.

Micro-Block components execute in browser environments similar to standard React components. In Eidos Desktop, each Micro-Block runs in an isolated domain:

<extid>.ext.<spaceId>.eidos.localhost:13127

Table view extensions provide custom visualization options beyond the default grid, gallery, and kanban views.

interface TableViewMeta {
type: "tableView"
componentName: string
tableView: {
title: string
description: string
}
}
export const meta = {
type: "tableView",
componentName: "MyListView",
tableView: {
title: "List View",
description: "This is a list view",
},
}
interface ITableViewContext {
tableId: string
viewId: string
}
const getRows = async (ctx: ITableViewContext) => {
const rows = await eidos.currentSpace.table(ctx.tableId).rows.query(
{},
{
viewId: ctx.viewId,
}
)
return rows
}
export function MyListView({ ctx }: { ctx: ITableViewContext }) {
const [rows, setRows] = useState<any[]>([])
useEffect(() => {
getRows(ctx).then((rows) => {
setRows(rows)
})
}, [ctx])
return (
<div>
{rows.map((row) => (
<div key={row.id}>{row.title}</div>
))}
</div>
)
}

Extension nodes provide custom node types beyond the default document and table nodes, with consistent directory tree behavior but custom rendering logic.

When rendering as an extNode, the block will default to accessing the following URL structure:

<extid>.ext.<spaceId>.eidos.localhost:13127/<nodeid>

This URL pattern enables isolated execution of extension nodes within the Eidos Desktop environment while maintaining proper scoping to the specific space and node.

interface ExtNodeMeta {
type: "extNode"
componentName: string
extNode: {
title: string
description: string
extHandler: string[]
}
}

For local-only extension nodes:

export const meta = {
type: "extNode",
componentName: "MyExcalidraw",
extNode: {
title: "Excalidraw",
description: "This is a excalidraw node",
extHandler: ["excalidraw"],
},
}
interface IExtNodeContext {
nodeId: string
type: string
}
export function MyExcalidraw({ ctx }: { ctx: IExtNodeContext }) {
const [initialData, setInitialData] = useState("")
useEffect(() => {
eidos.currentSpace.extNode.getText(ctx.nodeId).then((text) => {
setInitialData(JSON.parse(text))
})
}, [ctx])
return <Excalidraw initialData={initialData} />
}

For publishable extension nodes:

export const loader = async () => {
const nodeid = request.url.split("/").pop()
const text = await eidos.currentSpace.extNode.getText(nodeid)
return {
props: {
text,
},
}
}
export function MyExtNode({
ctx,
text,
}: {
ctx: IExtNodeContext
text: string
}) {
return <div>{text}</div>
}

The framework supports overriding default components, such as replacing the default Lexical-based document editor with alternative implementations.

import Editor from "@monaco-editor/react"
export const meta = {
type: "document",
componentName: "MyDocument",
}
export function MyDocument({ ctx }: { ctx: IExtNodeContext }) {
if (ctx.type !== "document") {
return <div>Not a document</div>
}
return <Editor />
}

Extension execution should be properly sandboxed to prevent unauthorized system access. Implementations must validate component props and enforce appropriate isolation between extensions and the host application.

  • Micro-Block extensions SHOULD export a meta object conforming to the specified interface when specific extension functionality is required
  • When no meta object is exported, the component will run as a regular React component without injected specific props
  • If a meta object is exported, component names in meta.componentName MUST match the actual exported component
  • Extensions SHOULD implement proper error boundaries and loading states
  • Data fetching MUST be performed through the Eidos SDK when interacting with application data

This specification may be extended to support additional extension types such as:

  • Custom field renderers