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, with first-class Preact, Solid, Vue, and Svelte support behind the same routing and server contracts.
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 --config.minimumReleaseAge=0 create @farm.js/app@beta 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@beta react react-dom
# or
pnpm add @farm.js/core@beta react react-dom
# or
yarn add @farm.js/core@beta 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