<?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>DEV Community: Jafran Jemal</title>
    <description>The latest articles on DEV Community by Jafran Jemal (@jafranjemal).</description>
    <link>https://dev.to/jafranjemal</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%2F3423299%2F78797cee-9a13-4db3-a636-2ec692b2fd07.jpeg</url>
      <title>DEV Community: Jafran Jemal</title>
      <link>https://dev.to/jafranjemal</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/jafranjemal"/>
    <language>en</language>
    <item>
      <title>Stop Building Invoices. Give Your Users a React Design Studio Instead.</title>
      <dc:creator>Jafran Jemal</dc:creator>
      <pubDate>Tue, 12 Aug 2025 10:42:39 +0000</pubDate>
      <link>https://dev.to/aavanamkit/stop-building-invoices-give-your-users-a-react-design-studio-instead-260h</link>
      <guid>https://dev.to/aavanamkit/stop-building-invoices-give-your-users-a-react-design-studio-instead-260h</guid>
      <description>

&lt;p&gt;If you're a &lt;strong&gt;React developer&lt;/strong&gt;, you’ve probably gotten &lt;em&gt;that&lt;/em&gt; email.&lt;br&gt;&lt;br&gt;
It usually arrives right after you’ve shipped a shiny new feature, and it begins:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Hey, quick change: can we move the customer address below the invoice number, make the total amount bigger, and add a 'Discount' column to the items table?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suddenly your sprint is derailed. Instead of building &lt;strong&gt;the next big feature&lt;/strong&gt;, you’re back in the weeds — tweaking CSS, shuffling components, redeploying for what feels like a minor layout change.&lt;/p&gt;

&lt;p&gt;It’s not just frustrating. It’s a &lt;strong&gt;repeatable waste of dev time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;I thought: &lt;em&gt;There has to be a better way to handle user-facing documents in React.&lt;/em&gt;&lt;/p&gt;



&lt;p&gt;
  &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdpkxck2uh%2Fimage%2Fupload%2Fv1754988806%2Fmsedge_gnOKzkDB1T_cfqagj.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fres.cloudinary.com%2Fdpkxck2uh%2Fimage%2Fupload%2Fv1754988806%2Fmsedge_gnOKzkDB1T_cfqagj.gif" alt="AavanamKit Live Demo" width="720" height="359"&gt;&lt;/a&gt;
&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Introducing &lt;code&gt;@aavanamkit/designer&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@aavanamkit/designer&lt;/code&gt; is an &lt;strong&gt;open-source React component&lt;/strong&gt; that works as a &lt;strong&gt;full drag-and-drop template designer&lt;/strong&gt; — right inside your app.&lt;/p&gt;

&lt;p&gt;It’s built for &lt;strong&gt;invoices, quotes, reports, certificates&lt;/strong&gt;, or any printable document your app generates.&lt;/p&gt;

&lt;p&gt;💡 &lt;strong&gt;Core idea:&lt;/strong&gt; Stop being the bottleneck. Let &lt;strong&gt;your users&lt;/strong&gt; create and edit their own templates with a familiar, intuitive interface.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;No more redeploys&lt;/strong&gt; for layout tweaks
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No more CSS churn&lt;/strong&gt; for “just one more change”
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero config&lt;/strong&gt; to get started
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Teams using &lt;code&gt;@aavanamkit/designer&lt;/code&gt; have cut document change requests from &lt;strong&gt;hours to seconds&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🚀 Live Demo — Try It Now
&lt;/h2&gt;

&lt;p&gt;Big button, no distractions. Click it. Play. Done.&lt;/p&gt;

&lt;p&gt;🚀 &lt;a href="https://aavanamkit-demo.vercel.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;TRY THE LIVE DEMO →&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠 How It Works — For React Devs
&lt;/h2&gt;

&lt;p&gt;The integration is intentionally &lt;strong&gt;three simple steps&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  1️⃣ Install the Package
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @aavanamkit/designer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2️⃣ Define Your Data Schema
&lt;/h3&gt;

&lt;p&gt;This tells the designer what dynamic fields users can insert.&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="c1"&gt;// Your application's data structure&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myAppSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;invoiceNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3️⃣ Render the Component
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;react&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AavanamKit&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aavanamkit/designer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Prebuilt CSS — no Tailwind setup needed&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aavanamkit/designer/dist/AavanamKit.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;TemplateEditor&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;handleSave&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;templateJson&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Saving template to database:&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;templateJson&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// await saveTemplateToApi(templateJson);&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;div&lt;/span&gt; &lt;span class="nx"&gt;style&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{{&lt;/span&gt; &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100vh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;100%&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;}}&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AavanamKit&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;myAppSchema&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;handleSave&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;    &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/div&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When your user clicks &lt;strong&gt;Save&lt;/strong&gt;, you get a clean JSON object representing their design — ready to store or render.&lt;/p&gt;




&lt;h2&gt;
  
  
  🆚 Why Not Just Use Figma, Canva, or PDF Generators?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Figma / Canva&lt;/strong&gt; → Great for designers, but your users need something &lt;em&gt;inside your app&lt;/em&gt;, tied to their real data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Static PDF generators&lt;/strong&gt; → You’re still hardcoding layouts, and changes mean more code.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;@aavanamkit/designer&lt;/strong&gt; → Live, in-app, React-native, and powered by your own schema.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📦 Features at a Glance
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Drag-and-drop&lt;/strong&gt; WYSIWYG editor&lt;/li&gt;
&lt;li&gt;✅ Works with &lt;strong&gt;Next.js, Vite, CRA&lt;/strong&gt; out of the box&lt;/li&gt;
&lt;li&gt;✅ &lt;strong&gt;MIT Licensed&lt;/strong&gt; — no lock-in&lt;/li&gt;
&lt;li&gt;✅ Save designs as JSON — render anywhere&lt;/li&gt;
&lt;li&gt;✅ Easy theming &amp;amp; custom components&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  📢 Get Involved
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@aavanamkit/designer&lt;/code&gt; is &lt;strong&gt;MIT licensed&lt;/strong&gt; and fully open source.&lt;br&gt;&lt;br&gt;
It was born from real-world developer pain, and I believe it can save &lt;strong&gt;hundreds of hours&lt;/strong&gt; for teams everywhere.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Here’s how you can help:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;⭐ &lt;strong&gt;Star the GitHub repo:&lt;/strong&gt; &lt;a href="https://github.com/jafranjemal/aavanamkit" rel="noopener noreferrer"&gt;https://github.com/jafranjemal/aavanamkit&lt;/a&gt;&lt;br&gt;&lt;br&gt;
📖 &lt;strong&gt;Read the Docs:&lt;/strong&gt; &lt;a href="https://aavanamkit-docs.vercel.app/" rel="noopener noreferrer"&gt;https://aavanamkit-docs.vercel.app/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
🚀 &lt;strong&gt;Try the Live Demo:&lt;/strong&gt; &lt;a href="https://aavanamkit-demo.vercel.app/" rel="noopener noreferrer"&gt;https://aavanamkit-demo.vercel.app/&lt;/a&gt;&lt;br&gt;&lt;br&gt;
❤️ &lt;strong&gt;Sponsor the Project:&lt;/strong&gt; &lt;a href="https://github.com/sponsors/jafranjemal" rel="noopener noreferrer"&gt;https://github.com/sponsors/jafranjemal&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;💬 Got feedback? &lt;a href="https://github.com/jafranjemal/aavanamkit/discussions" rel="noopener noreferrer"&gt;Open a GitHub Discussion&lt;/a&gt; or DM me on Twitter.&lt;/p&gt;




&lt;h2&gt;
  
  
  🏆 Community Challenge
&lt;/h2&gt;

&lt;p&gt;Fork the repo, build a creative template, and post it in Discussions.&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Best design each month gets a GitHub Sponsor shoutout&lt;/strong&gt; 🎉&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;Every hour you spend tweaking invoice layouts is an hour not spent building your app’s &lt;em&gt;real&lt;/em&gt; features.&lt;br&gt;&lt;br&gt;
Give your users control, and give yourself back the time you deserve.&lt;/p&gt;

&lt;p&gt;🚀 &lt;a href="https://aavanamkit-demo.vercel.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;Install @aavanamkit/designer Today&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Was Tired of Building Invoices, So I Built a Full-Stack React Document Designer</title>
      <dc:creator>Jafran Jemal</dc:creator>
      <pubDate>Sat, 09 Aug 2025 09:45:13 +0000</pubDate>
      <link>https://dev.to/jafranjemal/i-was-tired-of-building-invoices-so-i-built-a-full-stack-react-document-designer-5c84</link>
      <guid>https://dev.to/jafranjemal/i-was-tired-of-building-invoices-so-i-built-a-full-stack-react-document-designer-5c84</guid>
      <description>&lt;p&gt;If you’ve been a web developer for any length of time, you know the email. It arrives a week after you’ve successfully launched a big project. It starts with &lt;em&gt;"Quick change..."&lt;/em&gt; and it’s about the PDF invoice generator you spent way too long building.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;"Hey, this is great! Quick change: can we move the logo to the right, make the 'Total' bold, and add our new company slogan to the footer?"&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Suddenly, your sprint is derailed. You’re not building the next big feature; you’re digging through old code, fighting with a clunky PDF library or tweaking &lt;code&gt;print.css&lt;/code&gt;, all to shift a logo a few pixels. You’ve become a report designer, and it’s a frustrating, unprofitable loop.&lt;/p&gt;

&lt;p&gt;This is a huge gap in our industry. We build these incredible, dynamic applications, but the moment we need to create a physical document, we revert to rigid, hardcoded templates that make &lt;strong&gt;us&lt;/strong&gt; the bottleneck for every tiny business change.&lt;/p&gt;

&lt;p&gt;I decided there had to be a better way.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✨ Introducing AavanamKit: A Design Studio for Your Users
&lt;/h2&gt;

&lt;p&gt;What if, instead of building the invoice, you could build the &lt;strong&gt;&lt;em&gt;invoice designer&lt;/em&gt;&lt;/strong&gt;?&lt;/p&gt;

&lt;p&gt;That’s the core idea behind &lt;strong&gt;AavanamKit&lt;/strong&gt;, the open-source project I've been building. It’s a complete, full-stack ecosystem for document generation, and it’s designed to do one thing: &lt;strong&gt;give the design power back to your users.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AavanamKit is made of two distinct but perfectly synchronized packages:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;🎨 &lt;code&gt;@aavanamkit/designer&lt;/code&gt;&lt;/strong&gt;: A powerful, embeddable &lt;strong&gt;React component&lt;/strong&gt; that provides a full WYSIWYG "design studio" for your users.&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;⚙️ &lt;code&gt;@aavanamkit/engine&lt;/code&gt;&lt;/strong&gt;: A pure, &lt;strong&gt;headless Node.js library&lt;/strong&gt; that takes the templates your users create and generates pixel-perfect documents on your server.&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  🚀 Show, Don't Just Tell: The Live Demo
&lt;/h2&gt;

&lt;p&gt;The best way to understand it is to see it. I've built a full live demo where you can play with the designer right now, no installation required.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aavanamkit-demo.vercel.app/" rel="noopener noreferrer"&gt;&lt;strong&gt;» Try the Live Demo Now!&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Here is a GIF of the designer in action.)&lt;/em&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  🛠️ How It Works: The 3-Step Workflow
&lt;/h2&gt;

&lt;p&gt;The entire system is designed to be simple and intuitive.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. You Define the Schema
&lt;/h3&gt;

&lt;p&gt;In your application, you define the shape of your data. This is the "dictionary" the designer will use.&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="c1"&gt;// Your application's data structure&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;myAppSchema&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;customer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;invoiceNumber&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;items&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;number&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="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;Users&lt;/span&gt; &lt;span class="nx"&gt;Design&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;Template&lt;/span&gt;
&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;embed&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AavanamKit&lt;/span&gt; &lt;span class="o"&gt;/&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;component&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;admin&lt;/span&gt; &lt;span class="nx"&gt;panel&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;pass&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Your&lt;/span&gt; &lt;span class="nx"&gt;users&lt;/span&gt; &lt;span class="nx"&gt;can&lt;/span&gt; &lt;span class="nx"&gt;then&lt;/span&gt; &lt;span class="nx"&gt;drag&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;drop&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;bind&lt;/span&gt; &lt;span class="nx"&gt;elements&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="nx"&gt;fields&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;When&lt;/span&gt; &lt;span class="nx"&gt;they&lt;/span&gt; &lt;span class="nx"&gt;hit&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Save,&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="kd"&gt;get&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;clean&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt; &lt;span class="nx"&gt;object&lt;/span&gt; &lt;span class="nx"&gt;representing&lt;/span&gt; &lt;span class="nx"&gt;their&lt;/span&gt; &lt;span class="nx"&gt;design&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;

&lt;span class="c1"&gt;// Your user-facing template editor page&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;AavanamKit&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aavanamkit/designer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aavanamkit/designer/dist/style.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;TemplateEditor&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;onSave&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="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;AavanamKit&lt;/span&gt;
      &lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;schema&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;onSave&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Your function to save the template JSON to your DB&lt;/span&gt;
    &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;  &lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="mi"&gt;3&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;Generate&lt;/span&gt; &lt;span class="nx"&gt;Documents&lt;/span&gt; &lt;span class="nx"&gt;on&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;Backend&lt;/span&gt;
&lt;span class="nx"&gt;When&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;user&lt;/span&gt; &lt;span class="nx"&gt;needs&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="nx"&gt;real&lt;/span&gt; &lt;span class="nx"&gt;invoice&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;use&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;aavanamkit&lt;/span&gt;&lt;span class="sr"&gt;/engine on your server. You feed it the saved template and the live data&lt;/span&gt;&lt;span class="err"&gt;.
&lt;/span&gt;
&lt;span class="c1"&gt;// Your backend API route&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;generate&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aavanamkit/engine&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/api/invoices/:id/download&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templates&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;(...);&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;liveData&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;invoices&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;findOne&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;params&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pdfBuffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;template&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;template&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;templateData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;liveData&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;outputType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;});&lt;/span&gt;

  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setHeader&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;application/pdf&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;pdfBuffer&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;An Open Invitation&lt;br&gt;
AavanamKit is a fully open-source project under the MIT license. It was born from a real-world developer frustration, and I believe it can save countless hours for others in our community.&lt;/p&gt;

&lt;p&gt;If this idea resonates with you, I'd be thrilled if you checked it out.&lt;/p&gt;

&lt;p&gt;⭐ Star the project on GitHub: &lt;a href="https://github.com/jafranjemal/aavanamkit" rel="noopener noreferrer"&gt;https://github.com/jafranjemal/aavanamkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;📖 Read the Docs: &lt;a href="https://aavanamkit-docs.vercel.app" rel="noopener noreferrer"&gt;https://aavanamkit-docs.vercel.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
