Skip to content

Latest commit

Β 

History

1,542 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Farm.js

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

npm version MIT license TypeScript ready

Open in StackBlitz

✨ Built for Full-Stack Products

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.

πŸš€ Quick Start

Try It in Your Browser

No install needed: open the playground on StackBlitz to see server rendering, client islands, and typed server calls in one page.

Create a New App

pnpm --config.minimumReleaseAge=0 create @farm.js/app@beta my-app --template basic --typescript
cd my-app
pnpm dev

Your 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.

Manual Installation

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-dom

Create 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 dev

πŸ“ Project Structure

my-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

βš™οΈ Configuration

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.

Route-level Boundaries

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 suspended
  • error.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.tsx is used automatically as the Suspense fallback for that segment
  • error.tsx is used automatically as the error boundary for that segment
  • You do not need to import or conditionally render loading.tsx in page.tsx
  • The route must actually suspend to show loading.tsx (for example: async server component, async layout, or a child wrapped by Suspense)
  • loading.tsx and error.tsx do 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 />;
}

πŸ”Œ Plugin System

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.

🎯 Core Concepts

File-based Routing

Farm.js uses Next.js App Router-style file-based routing:

  • page.tsx - Creates a route
  • layout.tsx - Shared UI for a route segment
  • [param]/ - Dynamic route segment
  • [...slug]/ - Catch-all route segment

React Server Components

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>
  );
}

Client Components

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>;
}

πŸ“š Documentation

Visit farmjs.dev for comprehensive documentation, guides, and API reference.

πŸ—οΈ Development

Prerequisites

  • Node.js 22.13 or newer
  • pnpm 8+

Setup

git clone https://github.com/farming-labs/farm.js.git
cd farm.js
./scripts/setup.sh

Development Commands

# 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 dev

Project Structure

farm.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

🀝 Contributing

We welcome contributions! Please see our Contributing Guide for details.

Quick Contribution Steps

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes and add tests
  4. Push and create a Pull Request

🌟 Examples

  • 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

πŸ”— Ecosystem

  • Vite - Build tool and development server
  • React - UI library with Server Components
  • TypeScript - Type safety and developer experience

πŸ“„ License

MIT Β© Farming Labs

πŸ™ Acknowledgments

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

About

a full-stack, renderer-agnostic framework with experimental AOT React compiler.

Topics

Resources

Contributing

Stars

56 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages