When developing custom applications in ERPNext, managing frontend assets efficiently is crucial. Traditionally, ERPNext uses Jinja templates to build web pages, while modern frontend frameworks like Vite.js with React.js offer a more dynamic approach. In this blog post, I'll explore how Jinja and Vite.js handle builds, where to place the build files, and how to integrate them into an ERPNext custom app.
Jinja is a Python-based templating engine used in ERPNext for rendering HTML pages with dynamic data. It is tightly integrated into Frappe’s framework and is responsible for rendering both Desk and Web pages.
-
Template Location: Jinja templates are usually stored in:
your_app/your_app/templates/pages/your_app/your_app/templates/includes/
-
Rendering Process:
- When a page is requested, Frappe fetches the corresponding Jinja template.
- The template is processed on the server-side, injecting data from Python controllers (
your_app/your_app/www/). - The final HTML is sent to the client.
-
Static Assets (CSS, JS, Images):
- Placed inside
your_app/public/ - Served via
/assets/your_app/URL
- Placed inside
-
Build Output Location:
- Jinja itself doesn’t have a “build” process like modern frontend frameworks. Instead, it relies on server-side rendering with static files placed in
public/. However, ERPNext does generate bundled assets (JS, CSS) during thebench buildprocess, which are stored in thepublic/dist/folder.
- Jinja itself doesn’t have a “build” process like modern frontend frameworks. Instead, it relies on server-side rendering with static files placed in
your_app/
├── public/
│ ├── js/
│ │ ├── custom.js
│ ├── css/
│ │ ├── style.css
│ ├── images/
│ │ ├── logo.png
│
├── templates/
│ ├── pages/
│ │ ├── dashboard.html
│ ├── includes/
│ │ ├── navbar.html✅ Server-side rendering makes it SEO-friendly.
✅ Integrated directly into ERPNext.
❌ Less interactive and requires full page reloads.
❌ Harder to develop modern, component-based UIs.
Vite.js is a modern frontend tooling system that significantly improves performance by enabling faster builds and hot module replacement. It is commonly used for React.js applications in ERPNext.
-
Source Files:
- React.js components are written in
src/. - CSS, JS, and images are managed inside
src/assets/.
- React.js components are written in
-
Development Mode:
- Uses a local development server with hot reloading.
- No need to manually refresh the page.
-
Production Build:
- Running
vite buildgenerates optimized assets in thedist/folder (under Doppio configuration). - These assets must be served inside ERPNext’s
public/directory.
- Running
-
Where to Place Build Files?
- Move
dist/files toyour_app/public/frontend/. - Serve JavaScript inside Desk Pages using:
frappe.pages['custom-page'].on_page_load = function(wrapper) { let $page = $(wrapper); $page.html('<div id="react-app"></div>'); let script = document.createElement("script"); script.src = "/assets/your_app/frontend/assets/index.js"; script.type = "module"; document.body.appendChild(script); };
- Doppio take care all of above
- Move
your_app/
├── frontend/
│ ├── src/
│ │ ├── App.jsx
│ │ ├── components/
│ ├── assets/
│ ├── index.html
│
├── public/
│ ├── frontend/
│ │ ├── assets/
│ │ │ ├── index.js
│ │ │ ├── styles.css✅ Faster frontend performance with optimized builds.
✅ Component-based UI for modular development.
✅ Uses Doppio for easy integration into ERPNext.
❌ Requires a build step (doppio build).
❌ Extra setup needed to integrate with ERPNext’s Desk Pages.
| Feature | Jinja (ERPNext) | Vite.js (React.js) with Doppio |
|---|---|---|
| Rendering | Server-side | Client-side (SPA) |
| Interactivity | Low | High (dynamic UI) |
| SEO | Good | Requires SSR |
| Build Process | None (templating) | Needs doppio build |
| Where to Place Assets | public/ |
public/frontend/ |
| Usage | Simple pages, static content | Interactive dashboards, SPAs |
cd your_bench
bench get-app https://github.com/NagariaHussain/doppiobench add-spaBy leveraging Vite.js with Doppio, you can build modern React.js interfaces inside ERPNext, improving user experience while maintaining flexibility. This setup allows for faster development, component-based UIs, and better performance compared to Jinja templates!
With Doppio, you get a streamlined way to integrate Vite.js into ERPNext, making your frontend workflows more efficient and scalable.

ERPNext_Custom_App_Boilerplate.jpg