diff --git a/aleksis/core/management/commands/vite_bundle.py b/aleksis/core/management/commands/vite.py
similarity index 63%
rename from aleksis/core/management/commands/vite_bundle.py
rename to aleksis/core/management/commands/vite.py
index 01ab9654bb4bdfa813fd23241b80fbe7cf1c5c15..6a51217fff104beaf7e8282f10eb4f7c41cde758 100644
--- a/aleksis/core/management/commands/vite_bundle.py
+++ b/aleksis/core/management/commands/vite.py
@@ -11,6 +11,10 @@ from ...util.frontend_helpers import run_vite, write_vite_values
 class Command(BaseYarnCommand):
     help = "Create Vite bundles for AlekSIS"  # noqa
 
+    def add_arguments(self, parser):
+        parser.add_argument("command", choices=["build", "serve"], default="build")
+        parser.add_argument("--no-install", action="store_true", default=False)
+
     def handle(self, *args, **options):
         super(Command, self).handle(*args, **options)
 
@@ -18,7 +22,8 @@ class Command(BaseYarnCommand):
         write_vite_values(os.path.join(settings.NODE_MODULES_ROOT, "django-vite-values.json"))
 
         # Install Node dependencies
-        yarn_adapter.install(settings.YARN_INSTALLED_APPS)
+        if not options["no_install"]:
+            yarn_adapter.install(settings.YARN_INSTALLED_APPS)
 
         # Run Vite build
-        run_vite(["build"])
+        run_vite([options["command"]])
diff --git a/aleksis/core/settings.py b/aleksis/core/settings.py
index 78bd718a01f76fb4c5e985f6f55ee31a5a2f12ff..033f8824cf2453c780f9a630619b05215b992d4e 100644
--- a/aleksis/core/settings.py
+++ b/aleksis/core/settings.py
@@ -744,6 +744,7 @@ if _settings.get("dev.uwsgi.celery", DEBUG):
     UWSGI.setdefault("attach-daemon", [])
     UWSGI["attach-daemon"].append(f"celery -A aleksis.core worker --concurrency={concurrency}")
     UWSGI["attach-daemon"].append("celery -A aleksis.core beat")
+    UWSGI["attach-daemon"].append("aleksis-admin vite --no-install serve")
 
 DEFAULT_FAVICON_PATHS = {
     "pwa_icon": os.path.join(STATIC_ROOT, "img/aleksis-icon-maskable.png"),