<?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: Vu xfi</title>
    <description>The latest articles on DEV Community by Vu xfi (@vuxfi).</description>
    <link>https://dev.to/vuxfi</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%2F1271340%2Ff170a9fc-d112-42a4-8082-2d3e46f96a9a.png</url>
      <title>DEV Community: Vu xfi</title>
      <link>https://dev.to/vuxfi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vuxfi"/>
    <language>en</language>
    <item>
      <title>RestoApp v2.4 is here</title>
      <dc:creator>Vu xfi</dc:creator>
      <pubDate>Fri, 22 May 2026 04:57:53 +0000</pubDate>
      <link>https://dev.to/vuxfi/restoapp-v24-is-here-7ld</link>
      <guid>https://dev.to/vuxfi/restoapp-v24-is-here-7ld</guid>
      <description>&lt;p&gt;This release is heavily focused on one thing: rebuilding the admin experience.&lt;/p&gt;

&lt;p&gt;Over the past months, most of our work went into creating a cleaner, faster, and much more flexible admin panel. We wanted the system to feel modern, responsive, and enjoyable to work with every day — especially for teams handling large amounts of orders, products, and operational tasks.&lt;/p&gt;

&lt;p&gt;A huge part of this became possible thanks to — the open-source admin framework we actively participate in and contribute feedback to during real production usage. WebResto is not just using &lt;a href="https://dev.to/adminizer"&gt;Adminizer&lt;/a&gt;; we help shape its direction through practical experience from restaurant and delivery projects.&lt;/p&gt;

&lt;p&gt;We are also currently developing a dynamic admin module system that will allow expanding the panel on the fly — adding new functionality, workflows, and integrations without rebuilding the entire system. The goal is to turn the admin panel into a customizable operational workspace with a completely new experience for both developers and operators.&lt;/p&gt;

&lt;h2&gt;
  
  
  ✨ New Admin Panel
&lt;/h2&gt;

&lt;p&gt;The admin interface has been fully redesigned:&lt;/p&gt;

&lt;p&gt;• Modern and cleaner UI&lt;br&gt;
• New dashboard with customizable widgets&lt;br&gt;
• Reworked catalog management interface&lt;br&gt;
• Full compatibility with the current core and modules preserved&lt;/p&gt;

&lt;h2&gt;
  
  
  📦 Stock Manager &amp;amp; Inventory Control
&lt;/h2&gt;

&lt;p&gt;New tools for managing stock and availability:&lt;/p&gt;

&lt;p&gt;• Stock and stop-list editor&lt;br&gt;
• Dish and category availability management&lt;br&gt;
• Bulk actions and improved navigation&lt;/p&gt;

&lt;h2&gt;
  
  
  🧩 Experimental Order Kanban
&lt;/h2&gt;

&lt;p&gt;Order management has been significantly improved:&lt;/p&gt;

&lt;p&gt;• Visual Kanban board for orders&lt;br&gt;
• Order Stack support&lt;br&gt;
• Better filtering and statuses&lt;br&gt;
• Improved order processing workflow&lt;/p&gt;

&lt;h2&gt;
  
  
  📜 Order Logs &amp;amp; Transparency
&lt;/h2&gt;

&lt;p&gt;Every order action is now traceable:&lt;/p&gt;

&lt;p&gt;• Full order history&lt;br&gt;
• Error logging&lt;br&gt;
• Notification delivery logs&lt;br&gt;
• Transparent processing chain from start to finish&lt;/p&gt;

&lt;h2&gt;
  
  
  ⚡ Simplified Installer
&lt;/h2&gt;

&lt;p&gt;Deployment is now much easier:&lt;/p&gt;

&lt;p&gt;• Installation reduced from ~12 steps to just 3&lt;br&gt;
• More user-friendly setup process&lt;br&gt;
• Docker support fully preserved&lt;/p&gt;

&lt;h2&gt;
  
  
  📱 Mobile App Support
&lt;/h2&gt;

&lt;p&gt;Basic mobile application support has been added:&lt;/p&gt;

&lt;p&gt;• iOS and Android apps tested and working&lt;br&gt;
• Foundation prepared for deeper admin integration in v2.5&lt;/p&gt;

&lt;p&gt;WebResto continues evolving as an open platform for restaurant websites, delivery systems, and mobile applications.&lt;/p&gt;

</description>
      <category>news</category>
      <category>opensource</category>
      <category>showdev</category>
      <category>ui</category>
    </item>
    <item>
      <title>Adminizer 4.6</title>
      <dc:creator>Vu xfi</dc:creator>
      <pubDate>Fri, 22 May 2026 04:39:31 +0000</pubDate>
      <link>https://dev.to/adminizer/adminizer-46-4b3o</link>
      <guid>https://dev.to/adminizer/adminizer-46-4b3o</guid>
      <description>&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjryv7xhhw1n6ujlw2p6x.png" 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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjryv7xhhw1n6ujlw2p6x.png" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/adminization/adminizer" rel="noopener noreferrer"&gt;https://github.com/adminization/adminizer&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/adminizer/v/4.6.0" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/adminizer/v/4.6.0&lt;/a&gt;&lt;br&gt;
&lt;a href="https://t.me/talks_adminizer" rel="noopener noreferrer"&gt;https://t.me/talks_adminizer&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Five months of work. The release is about observability and automation — knowing what happens to your data, reacting to it, and plugging AI into the routine.&lt;/p&gt;




&lt;h2&gt;
  
  
  🕓 Change history (audit trail)
&lt;/h2&gt;

&lt;p&gt;The headline feature. Every model now keeps a full log: who, when, what changed, from which value to which.&lt;/p&gt;

&lt;p&gt;Under the hood — a pluggable history adapter: you can swap the storage to whatever fits (separate DB, S3, an external audit service).&lt;/p&gt;

&lt;h3&gt;
  
  
  How to use it
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Incident investigation&lt;/strong&gt;&lt;br&gt;
“Why did order #4821 change status yesterday at 18:40?” — open the record's history, instantly see the user, timestamp, and field diff. No more grepping app logs by timestamp.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Manual rollback&lt;/strong&gt;&lt;br&gt;
Previous value of every field is right there — restore state without a DB backup and without downtime.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Team oversight&lt;/strong&gt;&lt;br&gt;
A unified change list across all models, filterable by user — a manager opens it and sees exactly what a specific operator did today.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Compliance&lt;/strong&gt;&lt;br&gt;
For healthcare, finance, government contracts — covers the baseline requirement that all data edits must be traceable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Integration debugging&lt;/strong&gt;&lt;br&gt;
See what an incoming webhook actually changed, instead of “something changed somewhere”.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Included
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pagination&lt;/li&gt;
&lt;li&gt;Sort by date&lt;/li&gt;
&lt;li&gt;Filter by user&lt;/li&gt;
&lt;li&gt;Filter by association fields&lt;/li&gt;
&lt;li&gt;Separate permission for viewing history&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HistoryDialogStack&lt;/code&gt; UI component&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;getModelFieldsHistory&lt;/code&gt; export for custom views&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;History opens right inside the record card — no navigation away.&lt;/p&gt;




&lt;h2&gt;
  
  
  🔔 Notifications (foundation)
&lt;/h2&gt;

&lt;p&gt;The codebase now ships a base notifications model and the infrastructure around it.&lt;/p&gt;

&lt;p&gt;System notifications are off by default (so production doesn’t get spammed), but everything needed for your own alerts is already there.&lt;/p&gt;

&lt;h3&gt;
  
  
  What you can do today
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Business events&lt;/strong&gt;&lt;br&gt;
“New order from a VIP customer”, “SKU stock dropped below threshold”, “1★ review needs a response” — write a handler, drop a record into the notifications model, the operator sees it in the admin panel.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Tech alerts for the team&lt;/strong&gt;&lt;br&gt;
“Payment integration token expired”, “nightly cron didn’t run”, “import queue exceeded the limit” — without wiring up an external alerting tool.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Workflow reminders&lt;/strong&gt;&lt;br&gt;
“Order has been in packing status for over 24h” — a notification automatically lands with the responsible manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pair it with history&lt;/strong&gt;&lt;br&gt;
Important edit → automatic notification to the owner.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is the foundation for a full notification system in upcoming releases — for now it’s a clean primitive for your own alerting logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  🤖 AI agent (base layer)
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;AbstractAiModelService&lt;/code&gt; is now exported — a provider-neutral abstraction for any LLM.&lt;/p&gt;

&lt;p&gt;The OpenAI integration was polished, switched to &lt;code&gt;gpt-5-nano&lt;/code&gt; (faster and cheaper), and execution debug logs were expanded.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use cases
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Your own provider&lt;/strong&gt;&lt;br&gt;
Anthropic, a local LLM, a corporate AI gateway — implement the abstract service, register it, everything else works transparently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Field autofill&lt;/strong&gt;&lt;br&gt;
From a short product description the agent generates SEO title, meta description, and tags.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Summarization&lt;/strong&gt;&lt;br&gt;
A long customer message → one-sentence summary in the card + suggested ticket category.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Classification &amp;amp; routing&lt;/strong&gt;&lt;br&gt;
Incoming lead → segment detection → automatic assignment to a manager.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Auditable actions&lt;/strong&gt;&lt;br&gt;
Debug logs show exactly what the agent sees and what decision it makes — critical when an agent operates on production data.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;gpt-5-nano&lt;/code&gt; as the default makes typical agent runs several times cheaper than larger models — this is no longer “AI for the demo”, it’s viable for everyday work.&lt;/p&gt;




&lt;h2&gt;
  
  
  Everything else, in brief
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Configurable dashboard widgets (&lt;code&gt;defaultWidgets&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Info widget now supports links&lt;/li&gt;
&lt;li&gt;Password visibility toggle on login&lt;/li&gt;
&lt;li&gt;Redirect back to the original URL after sign-in&lt;/li&gt;
&lt;li&gt;Dock improvements&lt;/li&gt;
&lt;li&gt;&lt;code&gt;versionText&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;GitHub link&lt;/li&gt;
&lt;li&gt;Main-site link&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;displayName&lt;/code&gt; in model config&lt;/li&gt;
&lt;li&gt;Smart redirect for single-record catalogs&lt;/li&gt;
&lt;li&gt;Stabilization of Media Manager, Handsontable, JSONEditor&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;adminizer-jwt&lt;/code&gt; fixes&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;createdAt&lt;/code&gt; / &lt;code&gt;updatedAt&lt;/code&gt; typing&lt;/li&gt;
&lt;li&gt;CI: single npm publish workflow with branch-specific versioning&lt;/li&gt;
&lt;li&gt;Translation updates&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>news</category>
      <category>webdev</category>
      <category>opensource</category>
      <category>changelog</category>
    </item>
    <item>
      <title>RestoApp: Why We Built an Open-Source Food Delivery Platform</title>
      <dc:creator>Vu xfi</dc:creator>
      <pubDate>Sat, 09 Aug 2025 08:35:30 +0000</pubDate>
      <link>https://dev.to/restoapp/restoapp-why-we-built-an-open-source-food-delivery-platform-2nb8</link>
      <guid>https://dev.to/restoapp/restoapp-why-we-built-an-open-source-food-delivery-platform-2nb8</guid>
      <description>&lt;h2&gt;
  
  
  From WordPress to Node.js
&lt;/h2&gt;

&lt;p&gt;When we first started building food delivery websites, we relied on tried-and-true tools — &lt;strong&gt;WordPress&lt;/strong&gt; and &lt;strong&gt;WooCommerce&lt;/strong&gt;.&lt;br&gt;
For one of our clients, we launched a fully functional delivery site on this stack, and at first glance, it worked. But under the hood, it was almost entirely rewritten: too many modifications, a messy structure, and major maintenance headaches.&lt;/p&gt;

&lt;p&gt;Technologies like &lt;strong&gt;PHP&lt;/strong&gt; were no longer inspiring — we wanted something modern, modular, and flexible. That’s when we decided to switch to &lt;strong&gt;Node.js&lt;/strong&gt; to create solutions that meet today’s web development standards.&lt;/p&gt;

&lt;p&gt;At the time, we chose &lt;strong&gt;Sails.js&lt;/strong&gt; as the framework — it was simple and easy to understand, allowing us to quickly build an MVP. Yes, it’s aging now and we’re considering migrating to a newer stack, but back then it was the optimal choice.&lt;/p&gt;


&lt;h2&gt;
  
  
  Why Food Delivery is Not Just E-commerce
&lt;/h2&gt;

&lt;p&gt;Food delivery is not just an “online store with a cart.” It works differently:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The website often serves as an &lt;strong&gt;external storefront&lt;/strong&gt;, while business processes and logistics live inside &lt;strong&gt;ERP systems&lt;/strong&gt; (iiko, r-Keeper, Poster, Loyverse, or any other).&lt;/li&gt;
&lt;li&gt;For an enterprise-grade solution, &lt;strong&gt;synchronization&lt;/strong&gt; with these systems is critical — but the site must also work &lt;strong&gt;autonomously&lt;/strong&gt;, without external dependencies.&lt;/li&gt;
&lt;li&gt;Unlike retail, speed is critical: real-time order processing, live menu updates, delivery zones, and instant delivery cost calculation.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Our goal was to create a &lt;strong&gt;standalone, enterprise-level delivery site&lt;/strong&gt; that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Works equally well for a small café or a nationwide chain.&lt;/li&gt;
&lt;li&gt;Can easily integrate with &lt;strong&gt;any ERP&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Functions as a fully autonomous system, processing orders without third-party services.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Why We Chose Open Source
&lt;/h2&gt;

&lt;p&gt;Today, our clients range from single restaurants to large chains and franchises. We’ve learned that traditional subscription or “percentage of sales” models often don’t work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For large companies, they create unpredictable costs and vendor lock-in.&lt;/li&gt;
&lt;li&gt;Medium-sized businesses often seek &lt;strong&gt;lifetime licenses&lt;/strong&gt; for closed products.&lt;/li&gt;
&lt;li&gt;For long-term flexibility, &lt;strong&gt;Open Source&lt;/strong&gt; is increasingly the preferred choice.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We went fully &lt;strong&gt;open-source&lt;/strong&gt; for several reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Transparency&lt;/strong&gt; — anyone can review the code, check the architecture, and ensure its reliability.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Flexibility&lt;/strong&gt; — integrate with any service or make custom changes without waiting for vendor updates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Community&lt;/strong&gt; — build a network of developers and business owners around the platform.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scalability&lt;/strong&gt; — use RestoApp not only for delivery websites but also to create aggregator-level platforms.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For us, Open Source is not just a philosophy. It’s a strategic decision that gives businesses &lt;strong&gt;control and independence&lt;/strong&gt;, while letting us grow the platform together with the community.&lt;/p&gt;


&lt;h2&gt;
  
  
  Technology Stack
&lt;/h2&gt;

&lt;p&gt;RestoApp is built on modern, high-performance tools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Node.js&lt;/strong&gt; — fast, scalable server-side runtime.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sails.js&lt;/strong&gt; — straightforward, easy-to-learn framework for APIs and business logic.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PostgreSQL&lt;/strong&gt; — reliable relational database.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt; — deploy in minutes anywhere: locally, on a server, or in the cloud.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;
  
  
  Installing RestoApp
&lt;/h2&gt;

&lt;p&gt;We’ve made installation as simple as possible.&lt;/p&gt;
&lt;h3&gt;
  
  
  Quick Start
&lt;/h3&gt;

&lt;p&gt;Run RestoApp in Docker with one command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;--name&lt;/span&gt; restoapp &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 webresto/restoapp:latest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the container starts, open your browser and go to:&lt;br&gt;
&lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  What’s Next
&lt;/h2&gt;

&lt;p&gt;RestoApp is already ready to use as a complete food delivery solution, but we’re moving forward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Integration support for &lt;strong&gt;any ERP&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Extended modules for loyalty programs and promotions&lt;/li&gt;
&lt;li&gt;Capability to run delivery aggregators on top of the platform&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the next article, we’ll show you how to connect a restaurant management system and automate menu updates.&lt;/p&gt;




&lt;h2&gt;
  
  
  RestoApp Links
&lt;/h2&gt;

&lt;p&gt;🌐 &lt;a href="https://restoapp.org" rel="noopener noreferrer"&gt;RestoApp.org&lt;/a&gt;&lt;br&gt;
🐦 &lt;a href="https://twitter.com/restoapp_info" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; | 💬 &lt;a href="https://t.me/restoapp_community" rel="noopener noreferrer"&gt;Telegram&lt;/a&gt; | 🇷🇺 &lt;a href="https://vk.com/wall-229576548" rel="noopener noreferrer"&gt;VKontakte&lt;/a&gt; | 🎮 &lt;a href="https://discord.gg/mbT4AeBJZ6" rel="noopener noreferrer"&gt;Discord&lt;/a&gt; | ▶ &lt;a href="https://www.youtube.com/@restoapp_org" rel="noopener noreferrer"&gt;YouTube&lt;/a&gt;&lt;br&gt;
📘 &lt;a href="https://www.facebook.com/554037384466444" rel="noopener noreferrer"&gt;Facebook&lt;/a&gt; | 📷 &lt;a href="https://www.instagram.com/restoapp_org" rel="noopener noreferrer"&gt;Instagram&lt;/a&gt; | 🧵 &lt;a href="https://www.threads.net/@restoapp_org" rel="noopener noreferrer"&gt;Threads&lt;/a&gt; | 🌐 &lt;a href="https://bsky.app/profile/restoapp.bsky.social" rel="noopener noreferrer"&gt;BlueSky&lt;/a&gt; | 🎵 &lt;a href="https://www.tiktok.com/@restoapp_org" rel="noopener noreferrer"&gt;TikTok&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to Build a Realtime-Extensible Node.js SPA adminpanel</title>
      <dc:creator>Vu xfi</dc:creator>
      <pubDate>Thu, 19 Jun 2025 11:32:46 +0000</pubDate>
      <link>https://dev.to/adminizer/how-to-build-a-realtime-extensible-nodejs-spa-adminpanel-4c2b</link>
      <guid>https://dev.to/adminizer/how-to-build-a-realtime-extensible-nodejs-spa-adminpanel-4c2b</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;A quick look at our journey from classic templating engines to a dynamically extensible UI with Inertia.js.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the past five years, we’ve been searching for a convenient way to build the interface for our admin panel—something easy to update, expand, and scale. We started with &lt;strong&gt;Jade&lt;/strong&gt;, then moved to &lt;strong&gt;EJS&lt;/strong&gt;. Everything seemed fine. Later, we began removing &lt;strong&gt;jQuery&lt;/strong&gt; from the project and switched to &lt;strong&gt;Vue&lt;/strong&gt;. Vue had many strengths, but it turned out to be suboptimal for extensibility and scalability: each new component had to be bundled, and support for third-party libraries was often lacking.&lt;/p&gt;

&lt;p&gt;For our admin framework (&lt;a href="https://github.com/adminization/adminizer" rel="noopener noreferrer"&gt;Adminizer&lt;/a&gt;), one key requirement is extensibility &lt;strong&gt;without restarting the Node.js process&lt;/strong&gt;—in other words, &lt;strong&gt;realtime extensibility&lt;/strong&gt;. We need to allow developers to create custom controls for model fields via an internal API. Although Adminizer provides all the essential UI controls out of the box, sometimes more is needed.&lt;/p&gt;

&lt;p&gt;For example, in earlier versions of the admin panel, you could inject any component (e.g., &lt;code&gt;JsonEditor&lt;/code&gt;) using a &lt;code&gt;&amp;lt;head&amp;gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag and mount it via EJS to any database field requiring it. But how can we replicate this behavior in a &lt;strong&gt;SPA&lt;/strong&gt;—&lt;strong&gt;without rebuilding or restarting&lt;/strong&gt;?&lt;/p&gt;

&lt;h2&gt;
  
  
  How We Came to the Idea of Dynamic Bundling
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Why we abandoned full rebundling and turned to dynamic component loading.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;One of our developers raised a fundamental question: why bundle everything upfront? A SPA doesn’t need everything in one file, and modern tooling allows for dynamic component loading. So why not load the components we need—on demand, as independent modules?&lt;/p&gt;

&lt;p&gt;That idea clicked. We envisioned an admin panel where each module is a separate UI component that gets injected into the system on the fly, without any recompilation—just via HTTP requests.&lt;/p&gt;

&lt;p&gt;This led us to the concept of a &lt;em&gt;modular SPA&lt;/em&gt;, and the technology that enabled it was &lt;strong&gt;Inertia.js&lt;/strong&gt;. While this approach is widely used in Laravel/PHP, we had to make some adjustments for it to work well with our Node.js-based framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Inertia.js Was the Perfect Fit
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Explaining how Inertia.js stands out from other frameworks.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Inertia is designed to work with components. When it needs to render a page, it gets the component name from the server response and uses a &lt;strong&gt;manifest&lt;/strong&gt; to locate the appropriate file. All we had to do was write a wrapper component that dynamically imports the path passed through props.&lt;/p&gt;

&lt;p&gt;Inertia acts as a &lt;strong&gt;bridge&lt;/strong&gt; between the server and the SPA: on the backend, we specify which component to render, and Inertia takes care of loading and displaying it. The best part? That component doesn’t even need to exist at boot time—it can be created later and used immediately, without any need to rebuild the frontend.&lt;/p&gt;

&lt;p&gt;The result? We can display anything we want on the page. Since React is globally available via the window context, the entire admin system becomes controllable as a live SPA. In theory, it could even be wrapped in Cordova to deliver a mobile app version (though we haven’t tested this yet—that’s for another article).&lt;/p&gt;

&lt;h2&gt;
  
  
  How the New Admin Architecture Works
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Describing the practical implementation of dynamic extensibility.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Our new admin panel behaves like a modular SPA framework. &lt;code&gt;Vite&lt;/code&gt; loads &lt;code&gt;React&lt;/code&gt; globally via &lt;code&gt;window&lt;/code&gt;. When initializing a controller, we specify which component to load and from where—and if it exists, it gets rendered immediately. Most components live in individual modules, often inside &lt;code&gt;node_modules&lt;/code&gt;, and they require no rebundling.&lt;/p&gt;

&lt;p&gt;Inertia handles routing and delivery. It “understands” what needs to be rendered, even for routes we didn’t explicitly configure. It parses HTML and embedded JSON metadata, loads only what’s necessary, and even keeps a request log for caching and rollback.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters: Real-World Use Cases
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Why we needed this flexibility—and what it enables.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Modules can now not only extend the UI but also inject custom fields, interactive controls, or even entire standalone pages. For example, if a module needs a special editing interface, it simply defines it—and it just works. All of this happens &lt;strong&gt;without touching the main admin codebase&lt;/strong&gt; and &lt;strong&gt;without triggering a rebuild&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;We believe this architecture is close to ideal for an admin panel, where modularity and flexibility are critical.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion: Where We Are Now
&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;What’s done and what comes next.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;We now have a fully working &lt;strong&gt;version 4&lt;/strong&gt; of our admin panel, built with this modular Inertia.js approach. It’s already running in production. We’re currently polishing the last parts and preparing documentation to share this solution with the community.&lt;/p&gt;

&lt;p&gt;Hopefully, it’ll help others looking to build a flexible, scalable, and truly extensible admin panel—&lt;strong&gt;without the pain of constant rebuilds or server restarts&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Source code: &lt;a href="https://github.com/adminization/adminizer" rel="noopener noreferrer"&gt;https://github.com/adminization/adminizer&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>inertia</category>
      <category>adminpanel</category>
      <category>programming</category>
    </item>
  </channel>
</rss>
