# farm.js is a full-stack framework where the renderer is a config choice

> farm.js is a Vite-based full-stack framework with typed app-directory routing, server actions and streaming SSR, and its most unusual feature is that React is the default renderer rather than the only one, with beta Preact, Solid, Vue and Svelte adapters that share the same routing and server contracts. It also carries an experimental ahead-of-time React compiler that skips reconciliation when it can prove a component is eligible.

**farming-labs/farm.js** — a full-stack, renderer-agnostic framework with experimental AOT React compiler.

- Repository: https://github.com/farming-labs/farm.js
- Website: https://farmjs.dev
- Stars: 577 · Forks: 18
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/farming-labs-farm-js

## A framework built for products, and the version line says early

farm.js describes itself as a framework for building fast, full-stack, product-integrated applications, and the version line is 0.1.27.

That combination is the first thing to take in. The feature list is long and confident, and the version number is not. The documentation links a Stability and Support page for what 0.1 covers, which is the kind of page a project publishes when it wants you to know exactly which of its promises are firm.

The core idea is that farm.js combines Vite's instant development experience with typed app-directory routing, secure Server Actions, streaming SSR and production-ready deployment output.

So the shape is familiar. This is a Next-like framework in the broad sense, with an app directory, file-based routes, server functions, and a build that produces deployable output. What is unusual is the second half of that sentence in the earlier description: React is the default renderer, and beta Preact, Solid, Vue and Svelte adapters use the same routing and server contracts.

That last clause is the interesting engineering claim. A framework that lets you swap the component renderer but keeps the routing, the server functions and the integrations identical is doing something quite different from a set of adapters that only work in a demo. Either way, the adapters are described as beta, so that is the qualifier to hold on to.

The releases come thick and fast, v0.1.27, v0.1.26 and v0.1.25 published across 18 and 19 October 2026, and the last push was on 2026-10-22. The project is TypeScript, MIT licensed, with the homepage at farmjs.dev.

## The feature table is really a list of rendering modes

The eleven-row feature table is worth reading row by row, because several rows describe choices you make per route rather than features you get.

The custom RSC renderer is a purpose-built RSC, streaming SSR and client hydration pipeline, with optional Rust-native rendering for eligible host-only regions through a separate project called Strata. The experimental native rendering note repeats this: farm.js can automatically send eligible, server-only React subtrees through the Strata native renderer while safely falling back to normal React rendering for unsupported trees.

So there are three tiers of rendering: server-only subtrees that might be rendered by a Rust engine, client islands that hydrate normally, and everything else.

The flexible rendering row is where the routing decisions live. Choose streaming SSR, static generation, ISR, PPR, or deferred hydration islands route by route. That is a lot of options, and the phrase route by route is the important qualifier, since it means the framework does not force one rendering strategy on the whole application.

Then there is the Server Actions row, which describes writing mutations next to your components with a use server directive, form actions, optional encrypted bound arguments and configurable request security.

The typed app-directory routing row lists what is supported: pages, layouts, route groups, dynamic segments, loading states, error boundaries, middleware, and generated route types. The generated route types are the part that matters for the typing claim, since it means the router knows your route names as types rather than as strings.

The full-stack primitives row covers API routes, server functions, middleware, caching, KV storage, cron handlers, OpenAPI and post-response work. The first-party integrations row covers authentication, billing, email, jobs, AI, API keys, databases and provider-owned routes through one typed integration model.

The last integration item is interesting. Provider-owned routes means the framework can host routes for an external provider, which is how a service like a payment provider or an email provider gets a callback URL without you writing it.

And the production-ready output row says builds produce deployable server and client output with Nitro-powered adapters and per-route runtime controls.

## The experimental compiler is the boldest claim here

The AOT React compiler row is the one to read twice.

An experimental compiler turns eligible components into direct DOM updates that skip reconciliation, at about 6.8 times faster keyed swaps and about 2 times less CPU in the benchmark, and it falls back to normal React whenever eligibility cannot be proven.

The numbers are from a benchmark in the repository, and the directory listing confirms there is a benchmarks/ folder with a compiler entry. That is the right place for a claim like this, though it is a benchmark of the project's own making and the comparison is against normal React rather than against another compiler.

The design detail is the fallback. This is not a compiler that runs on all of your components and hopes for the best. It proves eligibility per component, and anything it cannot prove stays on the normal path. That is a defensible design for an experimental feature, because the failure mode is a slower app rather than a broken one.

It also connects to the Rust rendering note. If server-only subtrees can be rendered natively in Rust, and client components can skip reconciliation in the browser, then the JavaScript that remains is the smallest possible part, and the framework is trying to remove it from both ends.

There is a second compiler reference in the repository layout that is easy to miss. The root has skills/, rfcs/ and an ARCHITECTURE.md, and there is a playwright.rsc.config.ts alongside configs for i18n, isolated hydration, production sites, production, wasm and devtools. So the RSC behaviour has its own end-to-end test configuration, which is a reasonable sign that the feature is exercised rather than aspirational.

The wasm configuration is intriguing and unexplained in the documentation available here, and it is one of those things a reader would have to investigate in the repository.

## Getting started, and the template list is a directory of integrations

There is a playground that needs no install, which is the fastest way to see what the framework does. The StackBlitz link opens an example with a page file, and the description says you can see server rendering, client islands and typed server calls in one page.

Creating a new app is a create command:

```bash
pnpm create @farm.js/app my-app --template basic --typescript
cd my-app
pnpm dev
```

And the application is then running at http://localhost:3000.

The template flag is the interesting part. There is a list of ready-to-configure starters named Auth0, Auth.js, Autumn, Clerk, Inngest, Trigger.dev, Polar, Resend, Stripe, Supabase, Unkey, WorkOS, or an AI starter, and you use --list-templates to see them.

That list is a map of the commercial services a product team might need, and it is the clearest statement of what farm.js is for. Authentication providers, payment providers, email, jobs, database, API keys and AI, each with a starter. A framework that ships working starters for a dozen vendors is making a bet about its audience, and the audience is clearly teams building products rather than people learning a framework.

The manual installation path is the standard one:

```bash
npm install @farm.js/core react react-dom
# or
pnpm add @farm.js/core react react-dom
# or
yarn add @farm.js/core react react-dom
```

And then the config file, which is where the deployment target lives:

```ts
import { defineConfig } from "@farm.js/core";

export default defineConfig({
  deploy: {
    target: "vercel",
  },
});
```

Farm uses src as the source directory by default, and the documentation says to add srcDir only when your app uses a different directory. There is also a naming detail worth knowing: defineFarmConfig remains available as a deprecated exact alias of defineConfig, so an existing project using the older name still works.

The repository layout shows the workspace structure. There are packages/ for the framework packages, examples/ for the examples and the starter templates, docs/, a playground/, rfcs/, skills/, benchmarks/ and scripts/. The workspace globs cover packages/*, examples/*, examples/*/* with stackblitz excluded, plus docs and playground.

The scripts in the root package are mostly test orchestration, and the number of them is itself informative. There is a test script that runs a long list of node test files for packaging, release and promotion, then the package tests. There are separate scripts for renderers, packed integrations, packed app, packed compiler and deploy runtimes. And a set of Playwright configurations for each rendering mode.

## What the repository layout says about how this is built

The top-level entries tell you that this is a serious piece of engineering rather than a prototype, even at version 0.1.

There is an ARCHITECTURE.md at the root, an rfcs/ directory, and a RELEASING.md. The RFC directory is the one that stands out, because a framework with published RFCs is a project where design decisions are written down and argued about rather than emerging from pull requests.

There is also a skills/ directory at the root, which is a newer idea in this ecosystem. It is separate from the documentation and it sits next to an AGENTS.md and a CLAUDE.md, so the project expects both human contributors and automated agents to work in it, and the skills directory presumably holds the procedural guidance for doing so.

The build tooling is a mix of Turbo and pnpm workspaces. There is a turbo.json at the root, the pnpm-workspace.yaml, and the root package scripts call pnpm with a recursive filter over./packages/* for build and turbo with the same filter for dev. There is a bump.config.ts for versioning, and the release scripts referenced in the test command cover beta releases and promoting betas, so the project publishes a beta channel and promotes it.

The linting is worth a note because it is not the usual choice. There is an.oxlintrc.json and an.oxfmtrc.json, which is oxlint and oxfmt rather than ESLint and Prettier, the Rust-based linting and formatting tools. That is a performance decision and a statement about which tools the maintainers follow.

There is a.npmrc at the root and a vercel.json, and the tests directory alongside the scripts. The vitest.shared.ts at the root is a shared Vitest configuration, and the many Playwright configurations suggest that the rendering modes are each covered by their own end-to-end suite, which is the right way to test a framework whose whole promise is that six rendering strategies behave differently.

And the examples directory is long. There are api-mcp, auth0-integration, authjs-integration, autumn-integration, basic, cf-agent, clerk-integration, content-demo, deployment-presets, docs-integration, email-integrations, eve-agent, farm-auth, federation-demo, hints-demo, i18n, isolated-hydration, jobs-inngest, jobs-integration, jobs-trigger, local-first, msw-demo, partytown-demo, polar-integration and preact-renderer, among others.

Each of those names is a feature: MCP support, federation, hints, isolated hydration, local-first, Partytown, Mock Service Worker, and internationalisation.

## Conclusion

Adopt farm.js if you want a full-stack TypeScript application with typed routing and server actions and you are willing to be an early adopter, since the version is 0.1 and the documentation points at a stability page for what 0.1 covers. Skip it if you need a battle-tested framework with a long support history, or if the experimental compiler is what you actually need rather than a bonus, since it falls back to normal React whenever eligibility cannot be proven. Verify first which renderer adapter you want, since Preact, Solid, Vue and Svelte are described as beta, that you can run the project tests, which include many Playwright configurations for different rendering modes, and that your deployment target is one of the Nitro adapters, since the deploy target is part of the config.

## FAQ

### What is farm.js and how do I start a project with it?

It is a full-stack TypeScript framework combining Vite's development experience with typed app-directory routing, server actions and streaming SSR. You create a project with `pnpm create @farm.js/app my-app --template basic --typescript`, change into it and run `pnpm dev`, and the app runs at http://localhost:3000. The `--list-templates` flag shows ready-to-configure starters for Auth0, Auth.js, Clerk, Stripe, Supabase and others, and there is a StackBlitz playground that needs no install.

### Which renderers does farm.js support?

React is the default renderer, and beta Preact, Solid, Vue and Svelte adapters use the same routing and server contracts, so the renderer is selected by one line of config and the routes, server functions and integrations stay the same. Rendering mode is also chosen per route, with streaming SSR, static generation, ISR, PPR and deferred hydration islands all available.

### What does the experimental AOT React compiler do?

It turns eligible components into direct DOM updates that skip reconciliation, with the project reporting about 6.8 times faster keyed swaps and about 2 times less CPU in its own benchmark, and it falls back to normal React whenever eligibility cannot be proven. Separately, farm.js can route eligible server-only React subtrees through the Strata Rust native renderer, also with a fallback to normal React.

## Sources

- [farming-labs/farm.js on GitHub](https://github.com/farming-labs/farm.js)
- [License: MIT](https://github.com/farming-labs/farm.js/blob/main/LICENSE)
- [Project website](https://farmjs.dev)
- [README](https://github.com/farming-labs/farm.js/blob/main/README.md)
- [Releases](https://github.com/farming-labs/farm.js/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/farming-labs-farm-js
