Building a Quasar SPA for Production: CLI Command, Configuration, and Verification
Step‑by‑step guide to building a Quasar SPA for production: configure quasar.conf.js, run quasar build, verify the dist/spa output, and recover from failed builds.
15 Jan 2026, 17:55 UTC

Desired Outcome
Produce a minified, cache-busted static asset bundle in dist/spa that can be served by any static web server or CDN. The build must exit with code 0, emit an index.html that references hashed filenames, and respect the publicPath configured for the deployment base URL.
Prerequisites
- Node.js 18+ (LTS) and a package manager (npm, pnpm, or yarn).
- A Quasar project scaffolded with
@quasar/app-vite(Quasar v2, Vue 3, Vite) or@quasar/app-webpack(legacy). Verify withquasar --versionfrom the project root; expect@quasar/cli3.x+. - Dependencies installed: run
npm ci(orpnpm install --frozen-lockfile) in the project root. - Optional but recommended:
@quasar/cliinstalled globally (npm i -g @quasar/cli) so you can runquasardirectly; otherwise prefix withnpx.
Configure the Production Build
Open quasar.conf.js at the project root. The build object controls output. Key properties for a SPA deployment:
// quasar.conf.js (excerpt)
module.exports = function (/* ctx */) {
return {
build: {
// Base URL where the app will be hosted. Use '/' for domain root,
// '/my-app/' for a subdirectory. Must match the web server config.
publicPath: '/',
// Vue Router mode. 'history' requires server fallback to index.html.
// 'hash' works on any static host without rewrite rules.
vueRouterMode: 'history',
// Generate source maps for debugging production issues.
// Set to false to reduce bundle size and hide source.
sourceMap: true,
// Minification is on by default. Explicitly disable only for debugging.
// minify: true,
// Extend the Vite or Webpack config if you need custom plugins.
// extendViteConf (viteConf) { ... }
},
// Environment variables inlined at build time.
// Reference via process.env.MY_VAR in this file only.
env: {
API_BASE: process.env.API_BASE || 'https://api.example.com'
}
}
}
Note: process.env values are captured at build time. They are not available at runtime unless you also inject them into the client via build.env or a runtime config strategy.
Run the Production Build
From the project root (where package.json and quasar.conf.js reside), execute:
# Using global CLI
quasar build
# Or via npx (no global install)
npx quasar build
This command defaults to SPA mode. For other targets you must have the mode installed and specify --mode pwa, --mode ssr, --mode electron, etc. The build compiles Vue components, transpiles with Vite (or Webpack), minifies JS/CSS, hashes filenames (e.g., app.abc123.js), and writes the complete tree to dist/spa/.
Expected Checks
- Exit code: The command must return 0. Capture with
echo $?(POSIX) or%ERRORLEVEL%(Windows). - Artifact presence: Verify
dist/spa/index.htmlexists and references hashed assets:ls -la dist/spa/ # Expect index.html, js/app.[hash].js, css/app.[hash].css, etc. - Static serve test: Serve the output locally to confirm no console errors:
# Using serve (npm i -g serve) or any static server serve dist/spa -p 8080 # Open http://localhost:8080 and check DevTools Network tab: # - All JS/CSS return HTTP 200 # - No 404 for hashed files # - No JavaScript errors in Console - publicPath validation: If deploying to a subdirectory (e.g.,
https://example.com/my-app/), setpublicPath: '/my-app/'inquasar.conf.js, rebuild, and verify the generatedindex.htmlloads assets from/my-app/js/.... - Cache-busting verification: Make a trivial change (e.g., add a comment in
src/App.vue), rebuild, and confirm the asset hashes change. This proves long-term caching works.
Recovery Options
The build does not modify source code; it only writes to dist/. If a build fails or produces broken output:
- Redeploy previous artifact: In CI/CD, keep the last successful
dist/spatarball or container layer. Deploy that instead of the new build. - Revert source and rebuild:
git revert <bad-commit>(or reset), then rerunquasar build. This is the standard rollback for source-level regressions. - Clean and retry: Remove
dist/andnode_modules/.cache/(orpnpm store prune) to eliminate stale intermediates, then rebuild.
Limitations and Version Notes
- CLI flags and default output paths differ between Quasar v1 (Webpack) and v2 (Vite). The above assumes
@quasar/cli3.x with@quasar/app-vite. - SSR and PWA builds require
quasar mode add ssrorpwafirst; they generate additional server bundles and service-worker files. - Environment variables referenced in
quasar.conf.jsviaprocess.envare inlined at build time. They cannot be changed at runtime without a rebuild or a separate runtime config mechanism. - Do not commit
dist/to version control. Generate it in CI/CD and deploy the artifact directly.
Quick Verification Checklist
| Check | Command / Action | Pass Criteria |
|---|---|---|
| Exit code | quasar build && echo $? |
0 |
| index.html exists | test -f dist/spa/index.html |
File present |
| Hashed assets referenced | grep -E '\\.[a-f0-9]{8,}\\.(js|css)' dist/spa/index.html |
At least one match |
| Static serve loads | serve dist/spa then browse |
No 404, no JS errors |
| publicPath matches deploy URL | Inspect index.html script/src links |
Paths start with configured base |
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.