We stand in solidarity with Palestine against the ongoing genocide and the brutal occupation.
Vite is a modern frontend build tool that offers a very fast development experience and bundles your code for production. This plugin sets up Vite for use with a Django backend.
Install the Django app with pip and then install the Vite plugin via npm:
# Install the Django package
pip install django_vite_plugin
# Install the Vite plugin
npm install django-vite-plugin- Simple and elegant
- Static file lookup
- Auto reload
- JavaScript import helpers
- JS import autocompletions
- Production testing
Add django_vite_plugin to the INSTALLED_APPS list in your project's settings.py file:
INSTALLED_APPS = [
# Other apps
'django_vite_plugin',
# More apps
]Use the following code in your Django templates to load assets:
{% vite '<app_name>/<path>/<to>/<css>/styles.css' %}To output additional attributes in the HTML, do this:
{% vite '---.css' '--.js' crossorigin='anonymus' integrity='some-sha' %}This produces:
<link rel="stylesheet" type="text/css" crossorigin="anonymus" integrity="some-sha" href="---.css"/>
<script src="---.js" type="module" crossorigin="anonymus" integrity="some-sha"></script>Notice that the <script> tag automatically includes type="module". You may change this behavior from the settings.
Assume your home app has two files arranged as follows:
└── home
└── static
└── home
├── css
│ └── styles.css
└── js
└── main.jsYour template should look like this:
{% load vite %}
<!DOCTYPE html>
<html lang="en">
<head>
<!-- Other head elements -->
<!-- Vite dev client for hot module reload (only used in development) -->
{% vite %}
{% vite 'home/css/styles.css' 'home/js/main.js' %}
</head>
<body>
<!-- Page content -->
</body>
</html>Notice that instead of using home/static/home/*/*, we simply use home/*/*. By default the plugin adds static/<app_name> after the first segment of the path. This behavior can be adjusted via settings.
To use React, add this in your template file:
<head>
<!-- Other head elements -->
{% vite 'react' %}
{% vite 'home/css/styles.css' 'home/js/main.js' %}
</head>Or combine them in a single statement:
<head>
<!-- Other head elements -->
{% vite 'react' 'home/css/styles.css' 'home/js/main.js' %}
</head>In your vite.config.js, include the django-vite-plugin:
// vite.config.js
import { defineConfig } from 'vite'
import { djangoVitePlugin } from 'django-vite-plugin'
export default defineConfig({
plugins: [
djangoVitePlugin([
'home/js/app.js',
'home/css/style.css',
])
],
});The argument may be a string or an array of strings passed to build.rollupOptions.input.
Note: The automatic addition of
static/<app_name>applies here too.
All entry points used with{% vite '...' %}must be included here.
Run these commands in separate terminals:
# Start the Django development server
python manage.py runserver
# Start the Vite development server
npm run devFor production builds, run:
npm run buildMake sure you run all commands that are related to
django-vite-pluginfrom the same python environment as your django project.
django_vite_plugin requires no extra configuration for development or building your project. Customizations are done in your settings.py file.
The default configuration is as follows:
DJANGO_VITE_PLUGIN = {
'WS_CLIENT': '@vite/client',
'DEV_MODE': getattr(settings, 'DEBUG', True),
'BUILD_DIR': getattr(settings, 'STATIC_ROOT') or 'static',
'MANIFEST': '<BUILD_DIR>/.vite/manifest.json',
'BUILD_URL_PREFIX': getattr(settings, 'STATIC_URL'),
'JS_ATTRS': {
'type': 'module'
},
'CSS_ATTRS': {
'rel': 'stylesheet',
'type': 'text/css'
},
'STATIC_LOOKUP': True
}- WS_CLIENT: The Vite client script relative to the dev server URL. In most cases you do not need to change this.
- DEV_MODE: When
True, the Vite dev server links assets; otherwise build files are used. - BUILD_DIR: The directory where Vite outputs build assets. If you serve assets from another server (for example a CDN), keep the same structure.
- MANIFEST: The path to the
manifest.jsonfile. The default is<BUILD_DIR>/.vite/manifest.jsonas per Vite v5. The manifest must remain in this location even if assets are served from another server. - BUILD_URL_PREFIX: The URL prefix used in production. If
DEV_MODEisFalsethen all assets listed in<BUILD_DIR>/manifest.jsonreceive this prefix. Use this to specify a different server address if needed. - STATIC_LOOKUP: If enabled, the plugin inserts
static/<app_name>after the first segment of the asset path. For example,<app_name>/filebecomes<app_name>/static/<app_name>/file. Set this toFalseto disable the behavior. - JS_ATTRS: Attributes added by default to all
<script>tags. - JS_ATTRS_BUILD: Customize JavaScript attributes for production files (for instance, adding
deferor changing the type). - CSS_ATTRS: Attributes added by default to all
<link rel="stylesheet">tags.
The JavaScript configuration options include:
{
input: string | string[],
root?: string,
addAliases?: boolean,
pyPath?: string,
pyArgs?: string[],
reloader?: boolean | (file: string) => boolean,
watch?: string[],
delay?: number,
}- input: The entry points for JavaScript/CSS. Every file used with
{% vite '...' %}should be listed here. - root: The relative path from your
vite.config.jsto your project root. If they are the same, you can omit this. - addAliases: Determines whether to add the aliases
@s:<app>and@t:<app>injsconfig.json. If set totrue, the file is created if it does not exist. The default is to add aliases only ifjsconfig.jsonalready exists. - pyPath: The path to your Python executable (default is
python). - pyArgs: Additional arguments for
manage.pycommands. - reloader: Enables browser reload when HTML or Python files change. You may supply a function to check file changes. The default behavior checks for
.htmland.pyfiles. - watch: A list of extra files to monitor for browser reload. By default, the plugin detects changes in Python files within your apps.
- delay: The delay in milliseconds before reloading after a file change.
Suppose your vite.config.js is inside a frontend directory and your project structure is:
|-- home
| └-- static
| └-- home
| ├── css
| │ └── styles.css
| └── js
| └── main.js
└-- frontend
└-- vite.config.jsYour vite.config.js would then be:
// vite.config.js
import { defineConfig } from 'vite'
import { djangoVitePlugin } from 'django-vite-plugin'
export default defineConfig({
plugins: [
djangoVitePlugin({
input: [
// Your entry points
],
root: '..' // The parent directory
})
],
});You do not need a separate setup to use Vite. Install the packages, add the configurations, and you are ready to go.
Django recommends placing static files and templates in app_name/static/app_name and app_name/templates/app_name. When STATIC_LOOKUP is enabled, you can skip the static/app_name part in import paths.
For example, instead of writing:
{% vite 'app_name/static/app_name/path/to/asset' %}You write:
{% vite 'app_name/path/to/asset' %}The behavior of this setting is as follows:
| Vite Argument | Resulting Asset Path |
|---|---|
| app_name/script.js | app_name/static/app_name/script.js |
| app_name/static/script.js | app_name/static/script.js |
| static/script.js | static/script.js |
To disable this behavior, set STATIC_LOOKUP to False.
Note: This feature uses Django's built-in static file finder.
The plugin automatically reloads your browser whenever a relevant file is changed.
Similar to STATIC_LOOKUP, helpers are available for JavaScript imports. Vite's alias feature is used under the hood. The default aliases are:
| Alias | Maps to |
|---|---|
| @ | <project root> |
| @s:<app_name> | <app_path>/static/<app_name> |
| @t:<app_name> | <app_path>/templates/<app_name> |
If you set STATIC_LOOKUP to False, the aliases change as follows:
| Alias | Maps to |
|---|---|
| @ | <project root> |
| @s:<app_name> | <app_path>/static |
| @t:<app_name> | <app_path>/templates |
Enable autocompletions for these import aliases in IDEs that support jsconfig.json. Simply add a jsconfig.json file in your project's root or alongside vite.config.js.
If you use TypeScript, the paths are added automatically when you run the development command.
To verify that your build files work before deploying to production:
-
In your project's
urls.py, add:urlpatterns = [ # Other URL patterns path('', include('django_vite_plugin.urls')), # More URL patterns ]
-
In
settings.py, configure:STATICFILES_DIRS = [ BASE_DIR / 'build' ] DJANGO_VITE_PLUGIN = { # Other options 'DEV_MODE': False, 'BUILD_DIR': 'build' }
Replace
buildwith your build directory. Ensure this directory is different fromSTATIC_ROOTif it is set. -
If your
BUILD_URL_PREFIXcontainshttp://orhttps://, comment it out. -
Run
npm run buildto build your assets and enjoy the results.
