Hot reload
VextJS has a built-in intelligent hot reload mechanism and starts development mode through the vext dev command. The framework will monitor file changes and automatically select the optimal reload strategy based on the type of change, from millisecond-level hot replacement to complete process restart, covering all development scenarios.
Starting from 0.3.7, vext dev will execute dev preflight once before each initial start, file change, manual reload / restart, and child process request cold restart:
- Automatically run basic
typegen, synchronize.vext/types/*.generated.d.tsandsrc/types/generated/index.d.ts - TypeScript semantic diagnosis is output asynchronously after ready / reload by default
- If the basic typegen finds a blocking issue, this round of reload / restart will be skipped; if you want TypeScript semantic diagnosis to also block, you can use
--strict-preflight
Quick Start
After startup, the terminal will display a Banner box, including the current operating mode, monitoring mode, anti-shake interval, and three-layer Tier icon description:
After modifying the files in the src/ directory, the terminal will output the change details and reload results:
After turning on --verbose-lifecycle, the time consumption of each stage and the number of cache evictions will be additionally output:
If the change involves the addition or deletion of files (structural changes), Tier 2 will be applied:
If the change involves configuration or plug-ins, a Tier 3 cold restart will be performed:
Frontend-only changes use a separate rebuild path:
This path rebuilds .vext/client/ and keeps the backend process running. React pages, layouts, and shared components use React Fast Refresh by default; CSS-only changes update stylesheet links; after backend soft reloads that affect render data, the browser action follows frontend.dev.renderRefresh.
If an error occurs during the soft reload process, the framework will keep the old version running and prompt for repair:
Three-layer reloading strategy
VextJS's hot reloading adopts a three-layer strategy and automatically selects the optimal method based on the type of changed file:
Tier 1 — Route hot replacement ⚡
Tier 1 is the fastest way to reload. When you modify the business logic of the routing handler (such as modifying response data, adjusting query parameters), the changes take effect almost instantly, without waiting.
Tier 2 — Service Reload ⚡
Tier 2 is suitable for business logic modifications in the service layer. Since services are accessed lazily through app.services, new requests after replacing the service instance will naturally use the new instance.
Modifying the Model definition file in the src/models/ directory also triggers Tier 2. The framework will atomically replace the Model definition through Model.redefine(), and automatically roll back to the old definition when it fails to ensure that the service continues to be available:
Tier 3 — Cold Reboot 🔄
Modifications to configuration, plugins, and middleware affect the behavior of the entire application and therefore require a complete restart. The framework will complete the restart process as quickly as possible.
Reload strategy decision table
Relationship with vext build
vext dev loads .ts files directly from src/ in development mode (on-the-fly compilation via esbuild), without the need to execute vext build beforehand.
Development process:
CLI options
By default, vext dev only prints the listening address and total startup time; --startup-profile-json <path> only writes JSON and does not automatically print summary/details. When you need to see the time taken for each stage in the terminal, use --startup-profile explicitly.
File monitoring rules
Monitoring range
vext dev monitors file changes in the src/ directory and the project root public/ directory by default:
Ignore rules
Changes to the following files and directories will not trigger a reload:
node_modules/dist/.git/- Test files:
*.test.ts,*.spec.ts - Hidden files starting with
. *.d.tstype declaration files
Anti-shake processing
By default, anti-shake is not turned on (debounce: 0), and reloading is triggered immediately after file changes, with the fastest response. If you want to merge multiple changes into one reload when saving in quick succession, you can turn on the debounce window through --debounce <ms>.
For example: if routes/users.ts (Tier 1) and config/default.ts (Tier 3) are modified at the same time, the framework will perform a Tier 3 cold restart (including all changes).
TypeScript support
vext dev uses esbuild for on-the-fly compilation and overlays a layer of development period preflight with the following features:
- Extremely fast compilation — esbuild compiles 10-100 times faster than tsc
- Diagnosis layering during development — typegen blocks reload/restart, TypeScript semantic diagnosis outputs asynchronously by default; strict mode can restore blocking
- Automatic generated statement synchronization — preflight will update
.vext/types/*.generated.d.tsandsrc/types/generated/index.d.tsfirst - Zero configuration — Automatically reads compilation options in
tsconfig.json
:::warning type checking
vext dev does not perform a full tsc --noEmit style full link build check. In default mode, TypeScript semantic diagnostics will not block the first ready or reload; if you want the diagnostics to block development startup, you can use:
The recommendation remains:
- Rely on real-time type checking of IDE (VS Code/WebStorm) during development
- Run
npm run typecheck(tsc --noEmit) for full type checking before committing - Execute
tsc --noEmitin CI to ensure the type is correct :::
FAQ
No reloading is triggered after modification?
- Check whether the file is in the
src/directory — Only changes to files in thesrc/directory will trigger reloading - Check whether it is an ignored file —
*.test.ts,src/types/generated/**, files starting with.will not trigger - Check the terminal output — whether there is an error message (such as syntax error causing compilation failure)
Behavior not as expected after hot reload?
- Try manual restart — Press
Ctrl+Cto stop and then re-runvext dev - Clear module cache — In rare cases, Node.js’s module cache may cause old code to remain
- Check inter-service dependencies — Tier 2 overloading only rebuilds the changed service. If other services cache old references in the constructor, Tier 3 may be required
Cold restart too slow?
- Reduce initialization operations at startup — Avoid time-consuming operations (such as preheating a large amount of data) in the plug-in's
setup()and change it toonReady() - Development environment skips non-essential plug-ins — Disable certain plug-ins through
development.tsconfiguration conditions - Use
local.tsto simplify configuration — turn off unnecessary functions (such as current limiting, access logs, etc.) during local development
What to do if the port is occupied?
VextJS no longer promises "internal automatic retries until recovery" if the port is still occupied during a cold restart. The current behavior is to enforce explicit policy by --port-conflict / VEXT_PORT_CONFLICT:
error(default): fail directlyprompt: interactive queryretry/kill/next/abortkill: Try to terminate the occupying processnext: automatically switch to the next available port
If you want to automatically and smoothly continue when the port is occupied during the development period, it is recommended:
If you need to manually check the occupied process:
Relationship with Cluster mode
vext dev does not support Cluster multi-process mode. Always run as a single process during development to ensure predictable hot reload behavior.
If the production environment requires multiple processes, use vext start with Cluster configuration:
Best Practices
1. Make full use of Tier 1/2
Put most of the development work in the routing and service layer and enjoy millisecond-level hot reload experience. Configuration and plugin modifications are relatively minor, and occasional cold restarts are acceptable.
2. Cooperate with IDE real-time type checking
Although vext dev will output TypeScript semantic diagnostics, the IDE's live type checking is still the fastest source of feedback. It is recommended to enable IDE prompts and npm run typecheck at the same time; then enable strict mode when blocking preflight is required.
3. Simplified configuration of development environment
Use development.ts to turn off functions that are only needed in the production environment to speed up cold restart:
4. Use _ prefix to share code
Files starting with _ in the routes and services directories are not automatically loaded as routes/services. When modifying these tool files:- If referenced by the routing file → trigger Tier 1 (because the dependencies of the routing module have changed)
- If referenced by service file → trigger Tier 2
Next step
- Learn the complete usage of CLI command
- Learn the production environment deployment of Cluster multi-process
- View the environment coverage mechanism of Configuration
- Explore Testing to ensure code correctness after hot reloading