RCMV
InstallWeb ElementsLoginDatabase formDatabase API

See the exact application produced by the default installer.

Open the install demo
01

Create the foundation

Node.js runs the creator. npm retrieves the versioned RCMV package and installs the project. TypeScript makes every boundary visible before the application runs.

Node.jsnpmTypeScript
npx @rcmv/rcmv create hello-rcmv
cd hello-rcmv
npm install
02

See the four responsibilities

The generated folders are the map, and their order is the architecture: the Route receives the request, the Controller coordinates the work, the Model owns dependable data, and the View presents the outcome.

RCMV conventions
src/
├── routes/
├── controllers/
├── models/
└── views/
03

Define the Route

RCMV begins at the Route. It declares which request enters the feature and explicitly connects that request to its Controller and View without absorbing either responsibility.

Web StandardsTypeScript
src/routes/greeting.route.ts
import { defineRoute } from '@rcmv/rcmv'
import { showGreeting } from '../controllers/greeting.controller'
import { renderGreeting } from '../views/greeting.view'

export const greetingRoute = defineRoute({
  method: 'GET', path: '/hello',
  controller: showGreeting, view: renderGreeting,
})
04

Let the Controller coordinate

The Controller reads the user intention, calls the Model, and chooses a semantic outcome. It knows nothing about HTML, colors, or deployment.

Web StandardsRCMV contracts
src/controllers/greeting.controller.ts
import { controller } from '@rcmv/rcmv'
import { readGreeting } from '../models/greeting.model'

export async function showGreeting({ url }) {
  const result = await readGreeting(url.searchParams.get('name') ?? 'world')
  return result.status === 'found'
    ? controller.ready(result.data)
    : controller.unavailable(false)
}
05

Make the Model trustworthy

The Model owns the greeting data and its contract. Zod ensures the same dependable shape reaches every consumer, regardless of where the data may come from later.

ZodTypeScript
src/models/greeting.model.ts
import { model } from '@rcmv/rcmv'
import { z } from 'zod'

const greeting = z.object({ message: z.string() })

export async function readGreeting(name: string) {
  const data = greeting.parse({ message: `Hello, ${name}!` })
  return model.found(data)
}
06

Give the View full control

React defines the DOM component, React DOM turns it into HTML, Lucide supplies the icon, and Tailwind provides consistent visual guardrails. The View depends only on the Controller outcome.

ReactReact DOMLucideTailwind CSS
src/views/greeting.view.ts
import { CircleCheck } from 'lucide-react'
import { createElement } from 'react'
import { renderToStaticMarkup } from 'react-dom/server'

export function renderGreeting(outcome) {
  const page = createElement('main', { className: 'grid min-h-screen place-items-center' },
    createElement(CircleCheck),
    createElement('h1', null, outcome.data.message))
  return new Response(renderToStaticMarkup(page), {
    headers: { 'content-type': 'text/html; charset=utf-8' },
  })
}
07

Register and run

Register the route once. Vite builds the View assets and provides the fast development loop; Wrangler runs the same request through the Cloudflare Workers runtime.

ViteWranglerCloudflare Workers
src/index.ts
import { createApp } from '@rcmv/rcmv'
import { greetingRoute } from './routes/greeting.route'

export default createApp({ routes: [greetingRoute] })

// Then run:
npm run dev
08

Follow the complete request

Open the URL below. The Worker receives a standards-based Request; Route selects the work; Controller coordinates; Model validates; View renders a standards-based Response.

All 12, one request path
http://localhost:8787/hello?name=Martin

Request → Route → Controller → Model
                         ↓
Response ← View ← ready outcome
09

Check and deploy

Type-check before release, build the production assets, then let Wrangler publish the Worker. Cloudflare runs the application at the edge without changing any MVC code.

TypeScriptViteWranglerCloudflare Workers
npm run check
npm run build
npm run deploy