A framework for building fast, full-stack, product-integrated applications.
Farm.js combines Vite's instant development experience with typed app-directory routing, secure Server Actions, streaming SSR, and production-ready deployment output. React is the default renderer, and beta Preact, Solid, Vue, and Svelte adapters use the same routing and server contracts. See Stability and Support for what 0.1 covers.
Documentation Β· Examples Β· Quick Start
| Feature | What it gives you |
|---|---|
| βοΈ Custom RSC renderer | A purpose-built RSC, streaming SSR, and client hydration pipeline, with optional Rust-native rendering for eligible host-only regions through Strata. |
| π Server Actions | Write mutations next to your components with "use server", form actions, optional encrypted bound arguments, and configurable request security. |
| β‘ Blazingly fast development | Vite-powered startup, on-demand transforms, and fast HMR keep the feedback loop nearly instant. |
| π§ Typed app-directory routing | Pages, layouts, route groups, dynamic segments, loading states, error boundaries, middleware, and generated route types. |
| π§© Flexible rendering | Choose streaming SSR, static generation, ISR, PPR, or deferred hydration islands route by route. |
| π οΈ Full-stack primitives | Build with API routes, server functions, middleware, caching, KV storage, cron handlers, OpenAPI, and post-response work. |
| π First-party integrations | Add authentication, billing, email, jobs, AI, API keys, databases, and provider-owned routes through one typed integration model. |
| π Renderer choice | React by default, with Preact, Solid, Vue, and Svelte renderers selected by one line of config β same routes, server functions, and integrations everywhere. |
| π§ͺ AOT React compiler | An experimental compiler turns eligible components into direct DOM updates that skip reconciliation (~6.8x faster keyed swaps, ~2x less CPU in the benchmark), falling back to normal React whenever eligibility can't be proven. |
| π Production-ready output | Build deployable server and client output with Nitro-powered adapters and per-route runtime controls. |
| π¨ Great defaults | Start with TypeScript, Tailwind CSS, sensible conventions, and a clean project structureβwithout assembling the framework yourself. |
Experimental native rendering: 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.
No install needed: open the playground on StackBlitz to see server rendering, client islands, and typed server calls in one page.
pnpm create @farm.js/app my-app --template basic --typescript
cd my-app
pnpm devYour app will be running at http://localhost:3000!
Use --list-templates to choose a ready-to-configure Auth0, Auth.js, Autumn, Clerk, Inngest,
Trigger.dev, Polar, Resend, Stripe, Supabase, Unkey, WorkOS, or AI starter.
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-domCreate a farm.config.ts:
import { defineConfig } from "@farm.js/core";
export default defineConfig({
deploy: {
target: "vercel",
},
});Farm uses src as the source directory by default. Add srcDir only when your app uses a
different directory.
defineFarmConfig remains available as a deprecated exact alias of defineConfig.
Create your first page in src/app/page.tsx:
export default function HomePage() {
return (
<div className="min-h-screen bg-gray-50 flex items-center justify-center">
<h1 className="text-5xl font-bold text-blue-600">Hello from Farm.js!</h1>
</div>
);
}π‘ Tailwind CSS is pre-configured! Just use Tailwind classes - no setup needed. See TAILWIND_SETUP.md for details.
Add a root layout in src/app/layout.tsx:
import type { LayoutProps } from "@farm.js/core";
export default function RootLayout({ children }: LayoutProps) {
return (
<html>
<body>{children}</body>
</html>
);
}Start the development server:
npx farm devmy-farm-app/
βββ src/
β βββ app/
β βββ layout.tsx # Root layout
β βββ page.tsx # Home page (/)
β βββ about/
β β βββ page.tsx # About page (/about)
β βββ users/
β βββ page.tsx # Users list (/users)
β βββ [id]/
β βββ page.tsx # User profile (/users/123)
βββ farm.config.ts
βββ package.json
Farm.js supports a powerful configuration system via farm.config.ts:
import { defineConfig } from "@farm.js/core";
export default defineConfig({
experimental: {
serverComponents: true,
},
// Routing
async redirects() {
return [{ source: "/old", destination: "/new", permanent: true }];
},
// Custom headers
async headers() {
return [
{
source: "/:path*",
headers: [{ key: "X-Frame-Options", value: "DENY" }],
},
];
},
// Environment variables
env: {
API_URL: "https://api.example.com",
},
// Plugins
plugins: [
/* your plugins */
],
// And much more...
});See farm.config.ts documentation for all options.
Farm.js supports Next.js-style route boundaries with special files inside a route segment:
loading.tsx- Route-level loading UI shown while the segment is suspendederror.tsx- Route-level error UI shown when the segment throws during render
Example structure:
src/app/
layout.tsx
page.tsx
loading.tsx
error.tsx
dashboard/
page.tsx
loading.tsx
error.tsx
Required config:
import { defineConfig } from "@farm.js/core";
export default defineConfig({
experimental: {
serverComponents: true,
},
});How it works:
loading.tsxis used automatically as the Suspense fallback for that segmenterror.tsxis used automatically as the error boundary for that segment- You do not need to import or conditionally render
loading.tsxinpage.tsx - The route must actually suspend to show
loading.tsx(for example: async server component, async layout, or a child wrapped by Suspense) loading.tsxanderror.tsxdo not need'use client'unless they use client-only features like hooks or browser APIs
Example:
// src/app/dashboard/loading.tsx
export default function Loading() {
return <p>Loading dashboard...</p>;
}// src/app/dashboard/page.tsx
async function SlowContent() {
await new Promise((resolve) => setTimeout(resolve, 2000));
return <div>Dashboard ready</div>;
}
export default function DashboardPage() {
return <SlowContent />;
}Extend Farm.js with powerful plugins:
import { definePlugin } from "@farm.js/core";
export const myPlugin = definePlugin({
name: "my-plugin",
async beforeRequest(req, res, context) {
// Add custom logic before request processing
},
async transformHTML(html, context) {
// Modify HTML output
return html;
},
});See Plugin System Guide for comprehensive documentation.
Farm.js uses Next.js App Router-style file-based routing:
page.tsx- Creates a routelayout.tsx- Shared UI for a route segment[param]/- Dynamic route segment[...slug]/- Catch-all route segment
Server Components run on the server and can directly access databases, file systems, or other server-only resources:
// This runs on the server
export default async function BlogPost({ params }: { params: { slug: string } }) {
const post = await getPostFromDatabase(params.slug);
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}Use the 'use client' directive for interactive components:
"use client";
import { useState } from "react";
export default function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}Visit farmjs.dev for comprehensive documentation, guides, and API reference.
- Node.js 22.13 or newer
- pnpm 8+
git clone https://github.com/farming-labs/farm.js.git
cd farm.js
./scripts/setup.sh# Install dependencies
pnpm install
# Build all packages
pnpm build
# Run tests (from root: runs tests in all packages; @farm.js/core runs Vitest)
pnpm test
# Run only @farm.js/core tests
pnpm run test:farm
# Run tests and save output to test-run.log
pnpm run test:ci
# then: cat test-run.log
# Start playground
cd playground && pnpm dev
# Start documentation
cd docs && pnpm dev
# Run example
cd examples/basic && pnpm devfarm.js/
βββ packages/
β βββ farm/ # Core framework
β βββ farm-cli/ # @farm.js/cli tools
β βββ create-farm-app/ # App creation tool
β βββ farm-react/ # React renderer + AOT compiler
β βββ farm-{preact,solid,vue,svelte}/ # Other renderers
βββ examples/
β βββ basic/ # Basic example
β βββ rsc-demo/ # Server components, actions, and queries
β βββ stripe-integration/ # Typed integration usage
βββ docs/ # Documentation (Farm.js)
βββ playground/ # Development testing
βββ tests/ # Integration tests
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes and add tests
- Push and create a Pull Request
- Basic Example - Routing, boundaries, middleware, storage, and rendering modes in one app
- RSC Demo - Server components, server actions, and server queries
- React Compiler - The experimental AOT compiler side by side with baseline React
- Stripe Integration - Typed billing integration with provider-owned routes
- Solid Renderer - A Solid app on the same framework contracts
- Preact Renderer - A Preact app on the same framework contracts
- Vue Renderer - A Vue app on the same framework contracts
- Svelte Renderer - A Svelte app on the same framework contracts
- Vite - Build tool and development server
- React - UI library with Server Components
- TypeScript - Type safety and developer experience
MIT Β© Farming Labs
Farm.js is inspired by:
- Next.js - For the excellent App Router API design
- Vite - For the incredible development experience
- @lazarv/react-server - For RSC implementation insights
- Remix - For web-first development principles
Documentation β’ Examples β’ Contributing
Made with β€οΈ byβΒ Farming Labs team