nuxt / nuxt/ui

@nuxt/ui auto-enabled @nuxt/fonts appears to make clean Nuxt builds nondeterministic

Open
#6,446 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

triage
Dominant language
TypeScript
Stars
6.9k
Forks
1.1k
Avg merge
1d 7h
Merged PRs (30d)
57

Description

Environment

Nuxt: 4.4.2
Nuxt UI: 4.5.1
Vite: 7.3.2
Vue: 3.5.32
Package manager: yarn
OS: macOS
Is this bug related to Nuxt or Vue?

Nuxt

Package

v4.x

Version

V4.4.2

Reproduction

I tested by running two clean builds back to back and diffing the generated client assets:

rm -rf .nuxt .output /tmp/build-a /tmp/build-b

yarn build
cp -R .nuxt/dist/client /tmp/build-a

rm -rf .nuxt .output

yarn build
cp -R .nuxt/dist/client /tmp/build-b

diff -ru /tmp/build-a/_nuxt /tmp/build-b/_nuxt

Actual Result

With default Nuxt UI font behavior, generated client assets changed between clean builds even though source files did not change.

The changing file was initially entry.*.css, and that appeared to cascade into changed JS chunk hashes.

Expected Result

Two clean builds of the same source tree should emit the same client asset contents and filenames, assuming dependency versions and environment are unchanged.

Workaround

This fixes the issue in my app:

ui: {
  fonts: false,
}

After setting that, I confirmed two clean builds were byte-identical:

diff lines: 0
mjs files: 359 / 359
js files: 1 / 1
css files: 214 / 214
changed filenames: none

Description

I’m seeing nondeterministic client asset hashes between clean production builds when using @nuxt/ui with its default fonts: true behavior.

The same source tree, built twice from a clean state, produces different hashed files under .nuxt/dist/client/_nuxt. This can cause production dynamic import failures during or after deploys because browsers may request hashed chunk names from a previous build.

After narrowing it down locally, disabling Nuxt UI’s auto-enabled font module fixes the issue:

export default defineNuxtConfig({
  modules: ['@nuxt/ui'],

  ui: {
    colorMode: false,
    fonts: false,
  },
})

With ui.fonts: false, two clean builds are deterministic.

Additional context

Notes

Nuxt UI documents that it automatically registers @nuxt/fonts and that it can be disabled with ui.fonts: false.

Nuxt Fonts also documents that it processes CSS, injects @font-face rules, caches/proxies fonts, and includes hashed font files during build. My suspicion is that something in that CSS/font generation path is not ordered deterministically, which changes entry.*.css between builds.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by running the two clean-build commands in the reproduction and compare .nuxt/dist/client/_nuxt, especially entry.*.css and the generated filenames. Then inspect the default ui.fonts behavior and the @nuxt/fonts CSS/font processing path described in the issue. Done means identical client asset contents and filenames across both builds while keeping fonts enabled.

Written by the indexing model from the issue text.

Assessment

Tech stack
nuxt, typescript, vite
Domain
build-system, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.