<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Jamal</title>
    <description>The latest articles on Forem by Jamal (@jamalfox85).</description>
    <link>https://forem.com/jamalfox85</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1556151%2Fc562404d-5d42-4868-b0b1-1c569b0c8dde.png</url>
      <title>Forem: Jamal</title>
      <link>https://forem.com/jamalfox85</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/jamalfox85"/>
    <language>en</language>
    <item>
      <title>I Built a JSON-to-Vue Form Generator Using Naive UI — Here’s How It Works</title>
      <dc:creator>Jamal</dc:creator>
      <pubDate>Fri, 31 Oct 2025 03:48:00 +0000</pubDate>
      <link>https://forem.com/jamalfox85/i-built-a-json-to-vue-form-generator-using-naive-ui-heres-how-it-works-c62</link>
      <guid>https://forem.com/jamalfox85/i-built-a-json-to-vue-form-generator-using-naive-ui-heres-how-it-works-c62</guid>
      <description>&lt;h2&gt;
  
  
  🎯 The Problem
&lt;/h2&gt;

&lt;p&gt;If you’ve built Vue apps (especially with Naive-UI), you’ve probably written something like this dozens of times:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nf"&gt;data&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Then&lt;/span&gt; &lt;span class="nx"&gt;wrapped&lt;/span&gt; &lt;span class="nx"&gt;each&lt;/span&gt; &lt;span class="nx"&gt;property&lt;/span&gt; &lt;span class="kd"&gt;with&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;input&amp;gt;`&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="s2"&gt;`&amp;lt;n-form-item&amp;gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;added&lt;/span&gt; &lt;span class="nx"&gt;labels&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;accessibility&lt;/span&gt; &lt;span class="nx"&gt;attributes&lt;/span&gt; &lt;span class="nx"&gt;manually&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;  

&lt;span class="nx"&gt;It&lt;/span&gt;&lt;span class="err"&gt;’&lt;/span&gt;&lt;span class="nx"&gt;s&lt;/span&gt; &lt;span class="nx"&gt;repetitive&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;prone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;breaks&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;flow&lt;/span&gt; &lt;span class="nx"&gt;when&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;just&lt;/span&gt; &lt;span class="nx"&gt;want&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;prototype&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;form&lt;/span&gt; &lt;span class="nx"&gt;quickly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="o"&gt;---&lt;/span&gt;

&lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="err"&gt;⚡&lt;/span&gt; &lt;span class="nx"&gt;The&lt;/span&gt; &lt;span class="nx"&gt;Solution&lt;/span&gt;

&lt;span class="nx"&gt;With&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;paste&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;target&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="err"&gt;—&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;example&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
json&lt;br&gt;
{&lt;br&gt;
  "first_name": "John",&lt;br&gt;
  "last_name": "Doe",&lt;br&gt;
  "email": "&lt;a href="mailto:john.doe@example.com"&gt;john.doe@example.com&lt;/a&gt;",&lt;br&gt;
  "password": "password123",&lt;br&gt;
  "confirm_password": "password123"&lt;br&gt;
}&lt;/p&gt;

&lt;p&gt;And instantly generate a complete, accessible Vue form using Naive UI components:&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
html
&amp;lt;template&amp;gt;
    &amp;lt;n-form ref="formRef" @submit.prevent="handleSubmit" :model="formData" :rules="rules"&amp;gt;
        &amp;lt;n-form-item path="first_name"&amp;gt;
            &amp;lt;template #label&amp;gt;
                &amp;lt;label for="first_name"&amp;gt;First Name&amp;lt;/label&amp;gt;
            &amp;lt;/template&amp;gt;
            &amp;lt;n-input id="first_name" v-model:value="formData.first_name" type="password" aria-required="true" /&amp;gt;
        &amp;lt;/n-form-item&amp;gt;
        &amp;lt;n-form-item path="last_name"&amp;gt;
            &amp;lt;template #label&amp;gt;
                &amp;lt;label for="last_name"&amp;gt;Last Name&amp;lt;/label&amp;gt;
            &amp;lt;/template&amp;gt;
            &amp;lt;n-input id="last_name" v-model:value="formData.last_name"  /&amp;gt;
        &amp;lt;/n-form-item&amp;gt;
        &amp;lt;n-form-item path="email"&amp;gt;
            &amp;lt;template #label&amp;gt;
                &amp;lt;label for="email"&amp;gt;Email&amp;lt;/label&amp;gt;
            &amp;lt;/template&amp;gt;
            &amp;lt;n-input id="email" v-model:value="formData.email" type="email" autocomplete="email"  /&amp;gt;
        &amp;lt;/n-form-item&amp;gt;
        &amp;lt;n-form-item path="password"&amp;gt;
            &amp;lt;template #label&amp;gt;
                &amp;lt;label for="password"&amp;gt;Password&amp;lt;/label&amp;gt;
            &amp;lt;/template&amp;gt;
            &amp;lt;n-input id="password" v-model:value="formData.password" type="password"  /&amp;gt;
        &amp;lt;/n-form-item&amp;gt;
        &amp;lt;n-form-item path="confirm_password"&amp;gt;
            &amp;lt;template #label&amp;gt;
                &amp;lt;label for="confirm_password"&amp;gt;Confirm Password&amp;lt;/label&amp;gt;
            &amp;lt;/template&amp;gt;
            &amp;lt;n-input id="confirm_password" v-model:value="formData.confirm_password" type="password"  /&amp;gt;
        &amp;lt;/n-form-item&amp;gt;
        &amp;lt;n-form-item&amp;gt;
            &amp;lt;n-button attr-type="submit" type="primary"&amp;gt;Submit&amp;lt;/n-button&amp;gt;
        &amp;lt;/n-form-item&amp;gt;
    &amp;lt;/n-form&amp;gt;
&amp;lt;/template&amp;gt;


✅ Generated instantly.
✅ Copy-paste ready.
✅ Fully accessible and Naive UI–compatible.

## 🧩 Under the Hood

Here’s the high-level idea:

Parse the JSON structure.

Infer input types (e.g., detect emails, passwords, booleans).

Generate the &amp;lt;template&amp;gt; and &amp;lt;script&amp;gt; sections dynamically.

Apply accessibility features (aria-required, autocomplete, etc.).

Support rule generation for form validation.


## 🛠️ Key Features

⚙️ Generate Vue form components directly from JSON

🧠 Smart field type detection (email, password, text, etc.)

🧑‍🦽 Accessibility built-in

🎨 Built entirely with Naive UI

💾 Copy to clipboard (and soon download as .vue file)

🧰 Fine-tune each input via a settings panel

## 💬 Community Feedback

I shared an early version of this app on Reddit and got around 375 users on day one.
The feedback was awesome — people loved the idea but pointed out bugs and accessibility gaps.

After addressing those, I’m now focused on expanding support and getting more feedback from the Vue community.

## 🚀 Try It Yourself

🔗 Live App: https://jsontovue.com/

You can generate your first Vue + Naive UI form in under 30 seconds.

If you run into any issues or have suggestions, I’d love your feedback — you can leave a comment here

## 🧭 What’s Next

I’m currently exploring:

Supporting other frameworks like Nuxt and Shadcn

Auto-generating validation rules

Exporting to React and Svelte

If that sounds interesting, follow me for updates or drop a comment below with your ideas.

Thanks for reading! ❤️
If you think this tool could help other Vue developers, please share it or give this post a 🦄
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>opensource</category>
      <category>frontend</category>
    </item>
  </channel>
</rss>
