Migrate to laroux from other frameworks.
| Feature | Next.js | Remix | Fresh | laroux |
|---|---|---|---|---|
| Runtime | Node.js/Edge | Node.js | Deno | Deno |
| Components | RSC | Islands | Islands | RSC |
| Routing | File-based | File-based | File-based | File-based |
| Data Loading | Server Comp. | loader() |
Handlers | Server Comp. |
| Mutations | Server Actions | action() |
Handlers | Server Actions |
| Config | next.config.js | remix.config | fresh.gen | laroux.config |
curl -fsSL https://deno.land/install.sh | shdeno run -Ar jsr:@eser/cli install# Clone the repository
git clone https://github.com/eser/laroux.git
cd larouxComing Soon: Cloning templates via eser cli.
Static components → Server Components (no changes needed):
// Works the same in laroux
export function Header() {
return <h1>My App</h1>;
}Interactive components → Add "use client":
"use client";
import { useState } from "react";
export function Counter() {
const [count, setCount] = useState(0);
return <button onClick={() => setCount(count + 1)}>{count}</button>;
}Before (useEffect):
const [data, setData] = useState([]);
useEffect(() => {
fetch("/api/data").then((r) => r.json()).then(setData);
}, []);After (Server Component):
export default async function Page() {
const data = await fetch("https://api.example.com/data").then((r) =>
r.json()
);
return <div>{data.title}</div>;
}Before (API routes / loaders):
// Next.js: app/api/posts/route.ts
export async function POST(request) {
const data = await request.json();
await db.posts.create(data);
return Response.json({ success: true });
}After (Server Actions):
// actions.ts
"use server";
export async function createPost(formData: FormData) {
await db.posts.create({ title: formData.get("title") });
return { success: true };
}
// form.tsx
"use client";
import { createPost } from "./actions.ts";
export function Form() {
return (
<form action={createPost}>
<input name="title" />
<button>Submit</button>
</form>
);
}| From | To |
|---|---|
next/image |
<img> or laroux/image |
next/link |
<a> or Link component |
process.env.VAR |
Deno.env.get("VAR") |
useLoaderData() |
async Server Component |
useRouteError() |
React Error Boundary |
Both use Tailwind CSS (laroux uses v4.0):
/* src/styles/global.css */
@import "tailwindcss";- File-based routing (use component composition)
next/imageoptimization (use standard<img>)next/linkprefetching (use standard<a>)- Middleware
- International routing
- Install Deno v2.6+
- Create project
- Identify Server vs Client Components
- Add
"use client"to interactive components - Migrate data fetching to async Server Components
- Convert API routes to Server Actions
- Update
process.envtoDeno.env.get() - Test thoroughly