Farm.js

Upgrading to 0.1

Farm 0.1.0 is the first stable release. It follows 0.1.0-beta.108 and carries the stability policy: patch releases keep stable APIs working, and a minor release removes a stable API only after deprecating it first.

Upgrade the packages

Run the upgrade command from the app root:

farm upgrade --latest

It moves every published @farm.js/* dependency to its latest tag with the app's package manager. Packages in the shared release group, such as @farm.js/core, @farm.js/cli, @farm.js/devtools, and the integrations, move to 0.1.0. Renderer packages and plugins that are still in beta move to their newest beta, which is what their latest tag points to. Preview the commands first with farm upgrade --latest --dry-run.

To upgrade by hand, drop the @beta tag and keep every shared-group package on the same version. The integration packages pin @farm.js/core exactly, so mixing versions produces peer conflicts:

pnpm add @farm.js/core@latest
pnpm add -D @farm.js/cli@latest @farm.js/devtools@latest

pnpm 10.16 and newer can hold back versions published in the last day through minimumReleaseAge. Templates add @farm.js/* to minimumReleaseAgeExclude; add the same entry to your pnpm-workspace.yaml if an upgrade right after a release resolves an older version.

Behavior changes

These changes landed between the last beta and 0.1.0. Most apps need no code change.

  • React streaming on Node targets. With React 19, production servers on Node presets now stream through renderToPipeableStream, the same primitive development uses. Earlier betas used React's Web stream on Node when it was available. Response bodies are unchanged.
  • React on edge targets. Edge presets bundle React DOM's edge server build (server.browser on React 18) instead of its Node build. Cloudflare module Workers now bundle React instead of failing at startup with No such module "react".
  • Content Security Policy nonces and hashes. Enable security.csp.nonce for a strict script policy. Farm generates a per-request nonce for dynamic HTML and applies it to streamed script elements. Fully prerendered pages stay static and receive per-page SHA-256 hashes instead. See Content Security Policy.
  • Caller-owned databases. storage.dispose() no longer closes a database you passed to databaseStorage(database). Databases Farm creates from storage configuration are still closed by Farm.
  • DevTools version. @farm.js/devtools is now released with core and shares its version.

Deprecated APIs to replace before 0.2

These still work in 0.1 and are scheduled for removal in a later minor release.

Plugin lifecycle hooks

DeprecatedUse instead
initsetup
configconfigure
readyruntime.start
shutdownruntime.close
devServerCreateddev.server
hmrUpdatedev.update
buildStart, beforeBundlebuild.before
buildEnd, afterBundlebuild.after
beforeNitroBuildbuild.configure
routeDiscovered, middlewareDiscovered, apiRouteDiscoveredrouter.discovered
routesGeneratedrouter.generated
beforeRouteMatch / afterRouteMatchrouter.before / router.after
beforeRenderrender.before
afterRender, transformHTMLrender.html
transformPagerender.before or render.html
beforeApiHandler, beforeRequestruntime.before
afterApiHandler, afterResponseruntime.after
requestContext on the plugin contextctx.req

Integrations and schemas

DeprecatedUse instead
slot on integration descriptors, FarmIntegrationSlotcategory, FarmIntegrationCategory
requestContext, FarmIntegrationRequestContextStorereq, FarmRequestStore
defineIntegrationSchemadefineSchema (an exact alias)
FarmIntegrationSchema* typesthe matching FarmSchema* types

Configuration and routes

DeprecatedUse instead
The built-in DevTools dashboard (devtools)devtools() from @farm.js/devtools in plugins
defineCron()cron in farm.config.ts, pointing at an API route
generateStaticParamsgetStaticPaths
md.routesmd.expose
security.contentSecurityPolicysecurity.csp

Getting help

If an app behaves differently after upgrading, run farm doctor and open an issue with its output, the renderer, and the deployment target.