npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@json-to-jsx/engine

v0.1.0

Published

JSON-to-JSX no-code engine built on Mantine UI

Readme

@repo/schema-engine

License: MIT

Також доступно: English 🇬🇧

JSON-to-JSX рушій без коду на базі Mantine UI. Опишіть UI як JSON-схему → рендеринг у реальному часі → експорт готового .tsx файлу.

Запит користувача  ──▶  AI (Gemini / OpenAI / Anthropic)  ──▶  JSON Schema
                                  ▲                                   │
                           База знань                                 ▼
                        (правила категорій         SchemaRenderer (live preview)
                           + приклади)                                │
                                                                      ▼
                                                               generateTsx()
                                                                      │
                                                                      ▼
                                                            Завантажити .tsx файл

Зміст


Встановлення

# pnpm
pnpm add @repo/schema-engine @mantine/core @mantine/hooks

# npm
npm install @repo/schema-engine @mantine/core @mantine/hooks

Peer dependencies: react >= 18, @mantine/core >= 7

Обгорніть застосунок у MantineProvider та підключіть стилі Mantine:

import "@mantine/core/styles.css";
import { MantineProvider } from "@mantine/core";

export default function App({ children }) {
  return <MantineProvider>{children}</MantineProvider>;
}

Швидкий старт

import { SchemaRenderer, SchemaEngineProvider } from "@repo/schema-engine";
import type { Schema } from "@repo/schema-engine";

const schema: Schema = {
  version: "1.0",
  meta: { title: "Форма входу", locale: "uk" },
  root: {
    type: "Stack",
    props: { gap: "md", maw: 400, mx: "auto" },
    children: [
      { type: "Title", props: { order: 2 }, children: "Увійти" },
      { type: "TextInput", props: { label: "Email", required: true } },
      { type: "PasswordInput", props: { label: "Пароль", required: true } },
      {
        type: "Button",
        props: { fullWidth: true, onClick: "handleSubmit" },
        children: "Увійти",
      },
    ],
  },
};

export function App() {
  return (
    <SchemaEngineProvider>
      <SchemaRenderer
        schema={schema}
        locale="uk"
        callbacks={{ handleSubmit: () => console.log("відправлено") }}
      />
    </SchemaEngineProvider>
  );
}

Специфікація схеми

Коренева схема

interface Schema {
  version: "1.0";       // обов'язково, має бути рівно "1.0"
  root: SchemaNode;     // кореневий вузол дерева компонентів
  meta?: {
    title?: string;         // використовується як ім'я компонента при кодогенерації
    description?: string;
    locale?: string;        // локаль за замовчуванням для $i18n (напр. "uk")
    theme?: SchemaTheme;    // переопределення теми Mantine
  };
}

Структура вузла

interface SchemaNode {
  type: string;                                     // назва компонента з реєстру
  props?: Record<string, unknown>;                  // пропси Mantine компонента
  children?: TextValue | SchemaNode | SchemaNode[]; // вкладений контент
  style?: React.CSSProperties;                      // інлайн стилі
  visible?: boolean;                                // false = не рендерити (за замовч.: true)
  key?: string;                                     // React key
}

TextValue

Будь-який пропс або children з текстом може бути TextValue:

| Формат | Приклад | Коли використовувати | |--------|---------|----------------------| | Рядок | "Привіт" | Статичний контент | | { "$t": "ключ" } | { "$t": "nav.home" } | Зовнішня i18n (next-intl, i18next…) | | { "$i18n": { "en": "…", "uk": "…" } } | — | Вбудовані переклади прямо в схемі |

Застосовується до: children, label, placeholder, description, error, title, cite.

{
  "type": "TextInput",
  "props": {
    "label": { "$i18n": { "en": "Email address", "uk": "Електронна пошта" } },
    "placeholder": { "$t": "form.email_placeholder" }
  }
}

EventHandler

Події (onClick, onChange, onSubmit, onClose, onOpen, onFocus, onBlur, onStepClick) підтримують два формати:

{ "onClick": "handleSubmit" }
{ "onClick": { "$action": "submitForm", "payload": { "formId": "login" } } }

Рядок-ключ шукається в об'єкті callbacks переданому до <SchemaRenderer>. Формат $action викликає callbacks[action](payload).

Доступні типи компонентів

Розмітка (Layout)

Stack · Group · Grid · GridCol · Container · Center · Flex · SimpleGrid · Space · Divider · Box · Paper · ScrollArea · AspectRatio

Форми (Forms)

TextInput · PasswordInput · NumberInput · Textarea · Select · MultiSelect · Checkbox · CheckboxGroup · RadioGroup · Radio · Switch · Slider · RangeSlider · FileInput · ColorInput · ColorPicker · PinInput · Rating · SegmentedControl · Chip · ChipGroup

Контент (Content)

Text · Title · Image · Anchor · List · ListItem · Blockquote · Code · Highlight · Mark · Badge · Alert · Notification · ThemeIcon · Kbd · Spoiler

Інтерактивні (Interactive)

Button · ActionIcon · CloseButton · UnstyledButton · Modal · Drawer · Tabs · TabsList · TabsTab · TabsPanel · Accordion · AccordionItem · AccordionControl · AccordionPanel · Menu · MenuTarget · MenuDropdown · MenuItem · Tooltip · Popover · PopoverTarget · PopoverDropdown · HoverCard · HoverCardTarget · HoverCardDropdown · Dialog · LoadingOverlay · Overlay · Collapse

Відображення даних (Data Display)

Table · TableThead · TableTbody · TableTr · TableTh · TableTd · Card · CardSection · Timeline · TimelineItem · Stepper · StepperStep · Avatar · AvatarGroup · Indicator · Progress · ProgressSection · RingProgress · BackgroundImage · ColorSwatch · Skeleton · NumberFormatter

Навігація (Navigation)

NavLink · Breadcrumbs · Pagination · Burger

Примітка щодо складових компонентів: в схемі використовуйте плоскі імена (GridCol, TabsList, TableTr). Рендерер та генератор коду автоматично конвертують їх у крапкову нотацію Mantine (Grid.Col, Tabs.List, Table.Tr).

Правила ієрархії

| Правило | Деталі | |---------|--------| | GridCol | Має бути прямим дочірнім елементом Grid | | TabsList, TabsTab, TabsPanel | Мають бути всередині Tabs; TabsTab/TabsPanel вимагають проп value; Tabs вимагає defaultValue | | AccordionItem | Має бути всередині Accordion; вимагає проп value | | AccordionControl, AccordionPanel | Мають бути всередині AccordionItem | | MenuTarget, MenuDropdown | Мають бути всередині Menu | | PopoverTarget, PopoverDropdown | Мають бути всередині Popover | | Modal, Drawer | Вимагають булевий проп opened та обробник onClose | | StepperStep | Має бути всередині Stepper | | TableTr | Має бути всередині TableThead або TableTbody |


API Reference

SchemaRenderer

import { SchemaRenderer } from "@repo/schema-engine";

<SchemaRenderer
  schema={schema}             // Schema | SchemaNode — обов'язково
  registry={registry}         // ComponentRegistry — за замовч. createDefaultRegistry()
  locale="uk"                 // активна локаль для $i18n
  fallbackLocale="en"         // запасна локаль якщо переклад відсутній (за замовч. "en")
  t={(key) => i18n.t(key)}    // зовнішня i18n функція для $t ключів
  callbacks={{                // карта обробників подій
    handleSubmit: () => {},
    handleCancel: () => {},
  }}
  onError={(error, node) => ( // кастомний рендерер помилок per-node
    <Alert color="red">{error.message}</Alert>
  )}
/>

| Проп | Тип | Обов'язк. | Опис | |------|-----|-----------|------| | schema | Schema \| SchemaNode | ✓ | Схема або вузол для рендерингу | | registry | ComponentRegistry | — | Реєстр компонентів | | locale | string | — | Активна локаль (напр. "uk", "en") | | fallbackLocale | string | — | Запасна локаль (за замовч. "en") | | t | (key: string) => string | — | Функція для { $t } значень | | callbacks | Record<string, Function> | — | Іменовані обробники подій | | onError | (error, node) => ReactNode | — | Кастомна межа помилок per-node |

SchemaEngineProvider

Обгортає MantineProvider та застосовує опціональні токени теми зі схеми.

import { SchemaEngineProvider } from "@repo/schema-engine";

<SchemaEngineProvider theme={{ primaryColor: "violet", defaultRadius: "md" }}>
  <SchemaRenderer schema={schema} />
</SchemaEngineProvider>

Якщо у вашому застосунку вже є MantineProvider, можна використовувати SchemaRenderer напряму без SchemaEngineProvider.

validateSchema

import { validateSchema } from "@repo/schema-engine";

const result = validateSchema(unknownJson);

if (result.success) {
  const schema: Schema = result.data;
} else {
  console.error(result.errors.format()); // ZodError
}

У режимі розробки (NODE_ENV !== "production") SchemaRenderer автоматично валідує та виводить попередження в консоль.

ComponentRegistry

import { createRegistry, createDefaultRegistry } from "@repo/schema-engine";

const registry = createDefaultRegistry(); // всі 60+ Mantine компонентів

registry.register("MyCard", MyCardComponent);
registry.unregister("Burger");
registry.get("MyCard");    // ComponentType | undefined
registry.has("MyCard");    // boolean
registry.getAll();         // Map<string, ComponentType>

Генератор коду

Перетворює Schema у готовий .tsx файл з коректними Mantine імпортами.

generateTsx

import { generateTsx } from "@repo/schema-engine/codegen";

const code = generateTsx(schema, {
  componentName: "LoginForm",  // за замовч.: береться з schema.meta.title
  exportType: "named",         // "named" | "default"  (за замовч.: "named")
});

Результат генерації:

"use client";

import { Button, Paper, PasswordInput, Stack, TextInput, Title } from "@mantine/core";

export function LoginForm() {
  return (
    <Stack gap="md" maw={400} mx="auto">
      <Title order={2} ta="center">Sign In</Title>
      <Paper withBorder shadow="md" p="xl" radius="md">
        <Stack gap="sm">
          <TextInput label="Email" placeholder="[email protected]" required />
          <PasswordInput label="Password" placeholder="Your password" required />
          <Button fullWidth mt="md" type="submit" onClick={() => { /* handleSubmit */ }}>Sign in</Button>
        </Stack>
      </Paper>
    </Stack>
  );
}

| Опція | Тип | За замовч. | Опис | |-------|-----|------------|------| | componentName | string | З meta.title | Ім'я React функції | | exportType | "named" \| "default" | "named" | Тип експорту |

collectImports

Рекурсивно збирає всі Mantine імпорти для дерева вузлів:

import { collectImports, buildImportStatements } from "@repo/schema-engine/codegen";

const imports = collectImports(schema.root);
// Map { "@mantine/core" => Set { "Button", "Stack", "TextInput" } }

const statement = buildImportStatements(imports);
// 'import { Button, Stack, TextInput } from "@mantine/core";'

serializeNode

Конвертує SchemaNode у JSX рядок:

import { serializeNode } from "@repo/schema-engine/codegen";

serializeNode({ type: "TextInput", props: { label: "Email", required: true } }, 4);
// '    <TextInput label="Email" required />'

serializeNode({ type: "GridCol", props: { span: 6 } }, 4);
// '    <Grid.Col span={6} />'

Власні компоненти

import { createDefaultRegistry, SchemaRenderer } from "@repo/schema-engine";

const registry = createDefaultRegistry();

function KpiCard({ title, value }: { title: string; value: string }) {
  return <div><span>{title}</span><strong>{value}</strong></div>;
}

registry.register("KpiCard", KpiCard as React.ComponentType<Record<string, unknown>>);

const schema = {
  version: "1.0",
  root: { type: "KpiCard", props: { title: "Виручка", value: "$84,220" } },
};

<SchemaRenderer schema={schema} registry={registry} />

Інтернаціоналізація

Рушій не залежить від конкретної i18n бібліотеки і підтримує три підходи.

1. Зовнішня i18n ($t)

import { useTranslations } from "next-intl";
import { SchemaRenderer } from "@repo/schema-engine";

function Page({ schema }) {
  const t = useTranslations();
  return <SchemaRenderer schema={schema} t={t} locale="uk" />;
}
{
  "type": "TextInput",
  "props": {
    "label": { "$t": "form.email_label" }
  }
}

2. Вбудовані переклади ($i18n)

Самодостатньо — жодна зовнішня бібліотека не потрібна:

{
  "version": "1.0",
  "meta": { "locale": "uk" },
  "root": {
    "type": "Button",
    "children": { "$i18n": { "en": "Submit", "uk": "Надіслати", "de": "Absenden" } }
  }
}
<SchemaRenderer schema={schema} locale={currentLocale} />

3. Прості рядки

Для статичного контенту — просто використовуйте звичайні рядки. Ніяких налаштувань не потрібно.


AI Інтеграція

Вбудовані провайдери

Три AI провайдери вже вбудовані. Всі реалізують один інтерфейс AIProvider:

import { GeminiProvider, OpenAIProvider, AnthropicProvider } from "@repo/schema-engine/ai";
import type { AIProvider } from "@repo/schema-engine/ai";

const provider: AIProvider = new GeminiProvider({
  apiKey: process.env.GEMINI_API_KEY!,
  // model: "gemini-2.5-flash",  // за замовч.
  // temperature: 0.3,
  // maxTokens: 4096,
});

const raw = await provider.generate(systemPrompt, userPrompt);

| Провайдер | Модель за замовч. | Змінна середовища | |-----------|-------------------|-------------------| | GeminiProvider | gemini-2.5-flash | GEMINI_API_KEY | | OpenAIProvider | gpt-4o-mini | OPENAI_API_KEY | | AnthropicProvider | claude-opus-4-6 | ANTHROPIC_API_KEY |

Інтерфейс AIProvider:

interface AIProvider {
  name: string;
  generate(systemPrompt: string, userPrompt: string): Promise<string>;
}

База знань

База знань надає категорійно-специфічні правила та приклади схем, що вводяться в системний промпт AI залежно від ключових слів запиту користувача.

9 категорій: auth, form, dashboard, data-display, navigation, ecommerce, content, feedback, layout

import { matchKnowledge, buildContextFromKnowledge } from "@repo/schema-engine/knowledge";

const entries = matchKnowledge("форма входу з email і паролем");
// [{ category: "auth", rules: [...], componentHints: [...], examples: [...] }]

const context = buildContextFromKnowledge(entries);
// Форматований рядок для додавання в системний промпт AI

matchKnowledge(prompt, topN?) — оцінює кожну категорію за збігом ключових слів, повертає top N (за замовч.: 3). Повертає layout якщо жодного збігу немає.

buildEnhancedPrompt

Поєднує базовий системний промпт + контекст бази знань + підказку локалі в готову пару промптів:

import { buildEnhancedPrompt, parseAIResponse } from "@repo/schema-engine/ai";

const { systemPrompt, userMessage } = buildEnhancedPrompt(
  "Сторінка налаштувань з вкладками профілю і сповіщень",
  { locale: "uk" }
);

// Використовуємо з будь-яким провайдером:
const raw = await provider.generate(systemPrompt, userMessage);
const schema = parseAIResponse(raw); // Schema | null

parseAIResponse

Витягує та валідує Schema з відповіді AI (обробляє JSON у блоках markdown):

import { parseAIResponse } from "@repo/schema-engine/ai";

const schema = parseAIResponse(aiText); // Schema | null

Повний приклад AI генерації

import { GeminiProvider, buildEnhancedPrompt, parseAIResponse } from "@repo/schema-engine/ai";
import { generateTsx } from "@repo/schema-engine/codegen";

const provider = new GeminiProvider({ apiKey: process.env.GEMINI_API_KEY! });

async function promptToTsx(userPrompt: string): Promise<string | null> {
  const { systemPrompt, userMessage } = buildEnhancedPrompt(userPrompt, { locale: "uk" });
  const raw = await provider.generate(systemPrompt, userMessage);
  const schema = parseAIResponse(raw);
  if (!schema) return null;
  return generateTsx(schema);
}

const tsx = await promptToTsx("Форма реєстрації з ім'ям, email, паролем і вибором країни");
// → готовий вміст .tsx файлу

Кастомізація теми

{
  "version": "1.0",
  "meta": {
    "theme": {
      "primaryColor": "violet",
      "defaultRadius": "md",
      "fontFamily": "Inter, sans-serif"
    }
  },
  "root": { "type": "Stack", "children": [] }
}
interface SchemaTheme {
  colorScheme?: "light" | "dark" | "auto";
  primaryColor?: string;
  colors?: Record<string, string[]>;
  fontFamily?: string;
  headings?: { fontFamily?: string };
  defaultRadius?: string;
  spacing?: Record<string, string>;
  other?: Record<string, unknown>;
}

Playground

Інтерактивний playground за адресою apps/web/app/playground надає:

  • JSON Editor — пишіть або вставляйте схему, бачте живий Mantine preview
  • AI Prompt — описуйте UI природною мовою → Gemini/OpenAI/Anthropic генерує схему
  • Code вкладка — синтаксично підсвічений .tsx вивід, копіювання в буфер або завантаження файлу
  • Вибір провайдера — перемикайтесь між Gemini, OpenAI, Anthropic у тулбарі

Запуск локально:

# 1. Задайте API ключ
echo "GEMINI_API_KEY=ваш_ключ" >> apps/web/.env.local

# 2. Запустіть dev сервер
pnpm dev

Відкрийте http://localhost:3000/playground.


Карта експортів

| Шлях імпорту | Що отримуєте | |--------------|--------------| | @repo/schema-engine | SchemaRenderer, SchemaEngineProvider, validateSchema, createDefaultRegistry, всі типи | | @repo/schema-engine/schema | validateSchema, schemaNodeSchema, типи схеми | | @repo/schema-engine/registry | ComponentRegistry, createRegistry, createDefaultRegistry, registerAll | | @repo/schema-engine/ai | buildEnhancedPrompt, parseAIResponse, getSystemPrompt, GeminiProvider, OpenAIProvider, AnthropicProvider, тип AIProvider | | @repo/schema-engine/codegen | generateTsx, collectImports, buildImportStatements, serializeNode, COMPONENT_TO_IMPORT | | @repo/schema-engine/knowledge | matchKnowledge, buildContextFromKnowledge, KNOWLEDGE_BASE |


Приклади

Playground містить 7 готових схем:

| Приклад | Опис | |---------|------| | Login Form | Email + пароль + кнопка входу | | Registration Form | Повна форма реєстрації з усіма типами полів | | Dashboard Layout | SimpleGrid картки статистики + Table з бейджами | | Settings Page | Tabs → панелі Профіль / Безпека / Сповіщення | | Product Card | Card із зображенням, ціною, бейджем і CTA | | i18n Example | Вбудований $i18n з перемикачем локалі | | Nested Layout | Глибоке вкладення GridStackPaperStack |


Ліцензія

MIT © 2026