PRNext 0.1.19: compile on first use, preserve state
An editor used on one page should not add its compilation work to every startup. A form in progress should not disappear because a code edit arrives while it is submitting. PRNext 0.1.19-alpha addresses these situations with deferred client compilation, more focused development updates and better coordination between Server Actions and Fast Refresh.
This release also gives you more context before a migration and a complete example for exercising an application with accounts, a database and authentication. Here is what changes in your project, how to enable the useful options and where their limits matter.
Keep work in progress through a code edit
Consider a dashboard with a filter in its layout and a form that calls a Server Action. You save a component while the form response arrives. PRNext coordinates those operations to preserve the mounted layout when the update is compatible, instead of treating refreshed action references as a reason to start the page again.
Actions whose source is unchanged keep their identity within the development session, including with Cache Components. Changed actions receive new identities. Production builds retain independent identities. An old Flight response cannot overwrite a render from a newer generation, and an action error remains observable even when navigation replaces its render.
The mutation and its display remain separate operations. A newer interaction can make an older display irrelevant, but PRNext never submits the mutation again. Incompatible edits, some configuration changes and a full document reload can still reset state held in memory.
Compile a large tool when you open it
An ordinary dynamic import produces a chunk during compilation, even when downloading it waits for an interaction. In development, experimental.lazyDynamicImports goes further: it keeps eligible client targets outside the initial browser graph and waits for their first use before transforming and compiling them.
Enable this option in an App Router application using the native compiler. An editor, a viewer or a rarely opened panel is a useful place to compare the behavior. The option is disabled by default.
export default {
experimental: {
lazyDynamicImports: true
}
};First use pays the cost of compiling that subgraph. Files are prepared in private staging and published complete. Styles load before the import resolves. Once activated, the module participates in JavaScript and CSS updates. Already loaded ESM dependencies retain their identity and live bindings; two importers also share the same JSON object.
The intended benefit is to move work out of startup when your workflow does not use that tool. Measure startup and the first-use delay together. The option changes neither production chunks nor server rendering behavior.
An example with a browser-only editor
A next/dynamic component with ssr: false keeps the editor in the browser. In this example, the component is requested only after the panel opens. With deferred compilation enabled, its eligible client code waits until that use.
'use client';
import { useState } from 'react';
import dynamic from 'next/dynamic';
const Editor = dynamic(() => import('./editor'), {
ssr: false,
loading: () => <p>Loading the editor…</p>
});
export default function EditorPanel() {
const [open, setOpen] = useState(false);
return open
? <Editor />
: <button onClick={() => setOpen(true)}>Open the editor</button>;
}The initial scope excludes webpack hooks and custom loaders. Computed imports, import attributes and literal paths containing ? or # keep ordinary compilation. A suffix introduced by an alias or dependency inside a deferred graph produces an explicit error. A shared CommonJS dependency whose identity cannot be preserved and a new Server Action discovered only through that graph also require the ordinary path or a suitable static import.
Activated styles remain loaded for the development generation, including with parallel routes. Prefer CSS Modules or selectors local to the tool. The mechanism requires hardlinks on the generation’s filesystem; disable the option when that environment cannot create them.
Edit a stylesheet without copying the JavaScript build
A compatible CSS edit rebuilds the affected bundles and publishes a small style generation over the current JavaScript generation. PRNext retains resources still in use, including images, fonts and source maps, without scanning or copying every JavaScript file for that update.
If you edit one panel’s styles and then edit another panel several times, the first panel’s modified resources remain available in the bounded style catalogue. Unchanged resources stay accessible in the base generation. Incomplete provenance, an oversized catalogue or an incompatible change falls back to a full build.
Incremental graphs also divide their budget between main compilation and styles. Styles can borrow unused capacity without continually evicting main graphs when a project has many CSS scopes. Limits remain global and work is disposed when the session closes.
On macOS, a directory notification can combine several changes. PRNext checks the files in that source subtree to detect a deep edit, both in development and with build --watch. If verification remains incomplete, it reports a recoverable error and keeps the previous build without starting a compilation loop.
Understand an incompatibility before changing runtimes
A supported next/* import in your source can hide a dependency that uses a different private API. The migration audit follows reachable static imports into installed packages. It accounts for browser, Node and React Server Component contexts and reports the file, line and import chain behind a diagnostic.
A use server boundary remains a server boundary when a Client Component reaches it through a re-export. A browser dependency on a Node API is checked with browser mappings and installed implementations, rather than accepted merely because the package exists.
From a project with the intended PRNext version already installed, start with checks that do not apply a migration:
npx --no-install prnext migrate --dry-run
npx --no-install prnext migrate --check --jsonThe report distinguishes inspected behavior from unknown behavior. A computed import, loader output or traversal limit does not become an implicit success. The audit does not execute the dependency modules it inspects, but evaluating configuration can run project code. It is neither a sandbox for untrusted code nor a compatibility certificate. A real build and your application workflows are still necessary.
Move beyond a demo page to an application with accounts
The saas-reference example combines Better Auth, PostgreSQL, Drizzle and next-intl in a French and English application. Each account owns its notes. The dashboard checks the session, and every mutation checks the user and data ownership again. Hiding a button or protecting only the page is insufficient.
Authentication forms apply shared, atomic PostgreSQL budgets before expensive password hashing. Qualification workflows exercise session revocation, CSRF rejection and invalid OpenID Connect callbacks, using a controlled local provider and an HTTPS proxy that checks secure cookies.
The same application is tested after relocating its standalone output, with two workers and the original source removed. It is a verifiable starting point. Access rules, account recovery, verification and abuse limits still need to match your product. In deployment, keep the backend private behind a trusted proxy that overwrites forwarding headers.
Adopt the release with the right checks
After an update, check the actual installed version and aligned React dependencies, then rebuild and restart the application. If you are migrating from Next.js, keep the audit report and exercise authenticated routes, forms, styles and navigation. Compare an experimental option in your own project before keeping it enabled.
PRNext remains an alpha with partial Next.js compatibility. Functional qualification covers Linux, macOS and Windows, as well as Chromium, Firefox and WebKit. These checks do not establish a general performance gain. A historical campaign remains inconclusive because process observations are incomplete; it does not establish this release’s performance. Earlier Windows EPERM failures during atomic development-state publication remain documented, with no demonstrated cause or specific fix.
A representative workflow is a useful starting point: open a cold route, edit its styles, submit a form and return to a previously visited page. This checks what the release changes for your application, with its dependencies, authentication and deployment constraints.