INTRODUCING @MEONODE/UI

Type-Safe React

Without JSX

A production-ready library that replaces JSX with function-based composition — direct CSS-in-props, context-based theming, node-level memoization, and React Server Components support on Next.js.

View on GitHub
1// The MeoNode Way
2Div({
3  padding: '24px',
4  background: 'theme.primary',
5  borderRadius: '12px',
6  children: H1('Hello World', {
7    fontSize: '2rem'
8  })
9})

Type-safe API

RSC Ready

Theme-driven

Standard React

THE PHILOSOPHY

One Language. One Mental Model.

No context switching between XML and JavaScript. No angle brackets. Just pure functions and full TypeScript inference.

Function-Based Composition

Node(Component, { ... }) is a normal function call. TypeScript validates props directly against the component's signature — no JSX factory overhead, no ambient type declarations.

Zero Context Switching

Stay in expression position throughout. No bouncing between JSX grammar and JavaScript logic. No IIFEs, no extracted variables — just functions calling functions.

Surgical Memoization

Memoize any node with a dependency array. Empty array [] makes a node static — render once, never update. RSC compatible. Standard React, optimized.

SEE IT IN ACTION

Function Calls, Not Syntax Sugar

Every component is a function. Props are type-checked at the call site. Children pass naturally. Layout composes like Lego.

TodoApp.ts

1import {
2  Column, Row, H1, Text, Button,
3  Input, ThemeProvider, Component
4} from '@meonode/ui'
5import { useState } from 'react'
6
7// Type-safe reusable component
8interface TodoItemProps {
9  text: string
10  completed: boolean
11  onToggle: () => void
12}
13
14const TodoItem = Component<TodoItemProps>(({ text, completed, onToggle }) =>
15  Row({
16    gap: 12,
17    alignItems: 'center',
18    padding: '12px 16px',
19    backgroundColor: completed ? 'theme.accent' : 'theme.base.medium',
20    borderRadius: 8,
21    children: [
22      Button(completed ? 'Y' : 'O', {
23        onClick: onToggle,
24        backgroundColor: completed ? 'theme.secondary' : 'theme.base.deep',
25        color: completed ? 'theme.secondary.content' : 'theme.text.tertiary',
26        borderRadius: '50%',
27        width: 28,
28        height: 28,
29        padding: 0,
30      }),
31      Text(text, {
32        textDecoration: completed ? 'line-through' : 'none',
33        color: completed ? 'theme.text.tertiary' : 'theme.text.primary',
34        flex: 1,
35      }),
36    ],
37  })
38)
39
40// Main app with theme
41export const TodoApp = () => {
42  const [todos, setTodos] = useState([
43    { id: 1, text: 'Learn MeoNode', completed: true },
44    { id: 2, text: 'Build something amazing', completed: false },
45  ])
46
47  return ThemeProvider({
48    theme: {
49      mode: 'dark',
50      system: {
51        primary: { default: '#FF6B6B', content: '#4A0000' },
52        secondary: { default: '#6BCB77', content: '#0A3B0F' },
53        accent: { default: '#4ECDC4', content: '#1A4A47' },
54        base: { default: '#1A1A24', content: '#F0F0F5', medium: '#2A2A38', deep: '#12121A' },
55        text: { primary: '#F0F0F5', tertiary: '#9DA3B0' },
56      },
57    },
58    children: Column({
59      gap: 16,
60      padding: 24,
61      maxWidth: 480,
62      children: [
63        H1('My Todos', { fontSize: '1.75rem' }),
64        ...todos.map(todo =>
65          TodoItem({
66            key: todo.id,
67            text: todo.text,
68            completed: todo.completed,
69            onToggle: () => setTodos(prev =>
70              prev.map(t => t.id === todo.id
71                ? { ...t, completed: !t.completed }
72                : t
73              )
74            ),
75          })
76        ),
77      ],
78    }),
79  }).render()
80}
COMPONENTS

Every HTML Element as a Function

From layout primitives to form inputs. Every HTML element exposed as a type-safe function. Children-first for content. Props-first for containers.

Layout & Containers

Div, Column, Row, Grid, Center, Fixed, Relative, Absolute, Sticky, Root

Typography

H1-H6, Text, Span, P, Label, Code, Pre, Blockquote

Forms & Inputs

Input, Button, Textarea, Select, Option, Label, Form, Fieldset

Lists & Tables

Ul, Ol, Li, Table, Thead, Tbody, Tr, Td, Th

Media & Embeds

Img, Video, Audio, Iframe, Canvas, Svg, Source

Interactive

A, Button, Details, Summary, Dialog, Menu

Document Structure

Header, Footer, Main, Nav, Section, Article, Aside

Theme & Portal

ThemeProvider, StyleRegistry, PortalProvider, PortalHost

THEMING

Context-Based Theming with Automatic Value Resolution

Define your theme object once. Wrap your app with ThemeProvider. Reference tokens anywhere using string paths — 'theme.primary', 'theme.base.content'. No prop drilling. No context consumers. The styling engine resolves values automatically.

Light / Dark / Custom modes

CSS properties as direct props — no style={{ }} wrapper

Pseudo-classes & media queries via css prop

Numbers auto-converted to px

Theme Tokens

primary.default

#FF6B6B

primary.content

#4A0000

secondary.default

#6BCB77

secondary.content

#0A3B0F

accent.default

#4ECDC4

accent.content

#1A4A47

warning.default

#FFE66D

warning.content

#665A00

base.default

#1A1A24

base.content

#F0F0F5

FRAMEWORKS

Works Where React Works

Drop MeoNode into any React project — Next.js, Vite, or plain React. JSX components and MeoNode nodes compose seamlessly in both directions.

Next.js

Next.js

Vite

Vite

React

React

TS

TypeScript

Page.ts

1import { Root, Center } from '@meonode/ui'
2
3export default function Page() {
4  return Root({
5    minWidth: '100dvw',
6    minHeight: '100dvh',
7    children: Center({
8      flex: 1,
9      children: Span('Welcome to MeoNode UI!')
10    })
11  }).render()
12}

Ready to Ditch the Angle Brackets?

Install @meonode/ui today and experience the most natural way to build type-safe React applications.

npm install @meonode/ui react react-dom