Migration Guide: 0.x → 1.0
This page covers the changes needed when upgrading from NextFs 0.x to 1.0.
Breaking Change: Entry Manifest
The biggest change in 1.0 is the elimination of handwritten nextfs.entries.json.
Before (0.x)
You maintained nextfs.entries.json manually:
{
"entries": [
{
"fable": ".fable/App.Page/App.Page.js",
"output": "app/page.js",
"directive": "use client",
"default": "Page"
}
]
}
After (1.0)
Annotate each entry module directly in F#:
[<NextFs.NextFsEntry("app/page.js", Directive="use client", Default="Page")>]
module App.Page
Then generate the manifest automatically:
node tools/nextfs-scan.mjs path/to/YourProject.fsproj
The scanner reads [<NextFsEntry>] attributes from your .fs files and writes nextfs.entries.json for you.
Step-By-Step Upgrade
1. Update the package
dotnet add package NextFs --version 1.0.0
2. Add attributes to every entry module
For each entry in your existing nextfs.entries.json, add a matching [<NextFs.NextFsEntry(...)>] attribute before the module declaration and before any open statements.
| JSON field | Attribute parameter |
|---|---|
"output" | positional: "app/page.js" |
"directive" | Directive="use client" or Directive="use server" |
"default" | Default="Page" |
"named" | Named="metadata viewport" (space-separated) |
"exportAll" | ExportAll=true |
Example — a client page with metadata:
// Before: only module declaration
module App.Page
// After: add attribute before module
[<NextFs.NextFsEntry("app/page.js", Directive="use client", Default="Page", Named="metadata")>]
module App.Page
For static literal exports (e.g. proxy config), use [<NextFs.NextFsStaticExport>]:
[<NextFs.NextFsEntry("proxy.js", Named="proxy")>]
[<NextFs.NextFsStaticExport("config", """{"matcher":["/((?!_next).*)"]}""")>]
module Proxy
3. Add scan script to package.json
{
"scripts": {
"scan": "node tools/nextfs-scan.mjs src/YourProject.fsproj"
}
}
4. Regenerate the manifest
npm run scan
This overwrites nextfs.entries.json from your F# attributes. Verify the output matches your previous manual file.
5. Regenerate wrappers
node tools/nextfs-entry.mjs nextfs.entries.json
The generated wrapper files should be identical to what you had before.
6. Verify the build
dotnet fable src/YourProject.fsproj
npm run build
7. Remove manual JSON maintenance
From this point, nextfs.entries.json is generated — never edit it by hand. Add the scan step to your dev workflow:
{
"scripts": {
"scan": "node tools/nextfs-scan.mjs src/YourProject.fsproj",
"sync:app": "npm run scan && node tools/nextfs-entry.mjs nextfs.entries.json"
}
}
API Changes
Renamed modules (0.9 → 1.0)
No module renames in 1.0. The client/server split introduced in 0.9 (NavigationClient, LinkClient, WebVitals for client hooks vs Navigation, Server for server helpers) remains unchanged.
New APIs in 1.0
[<NextFs.NextFsEntry>]attribute[<NextFs.NextFsStaticExport>]attributetools/nextfs-scan.mjsscanner
Experimental APIs
The following APIs are included in 1.0 but depend on Next.js experimental flags. They may change without a NextFs major bump if Next.js changes or removes them:
Navigation.forbidden()/Navigation.unauthorized()— requireexperimental.authInterrupts: trueDirective.useCachePrivate()/Directive.useCacheRemote()— requireexperimental.dynamicIONavigationClient.unstableIsUnrecognizedActionError— wraps an upstreamunstable_*functionProxyConfig— proxy support varies by Next.js version
Questions?
See the FAQ or open a GitHub Discussion.