Skip to content

Getting started ​

Prerequisites ​

Node.js 20 or newer. Check with node -v.

Install ​

bash
npm i clovejs
bash
pnpm add clovejs
bash
yarn add clovejs

Scaffold the project ​

bash
npx clove scaffold          # TypeScript layout
npx clove scaffold --js     # JavaScript layout

Scaffolding is an explicit command rather than an install-time prompt: package managers suppress or sandbox postinstall, and prompts break CI.

It never overwrites an existing file — anything already present is reported as skipped. Pass --force to overwrite deliberately.

The command creates the directory structure, a few starter files, a tsconfig.json (TypeScript only), a .gitignore, and adds dev, build and start scripts to your package.json:

src/
  api/
    hello.get.ts
  ws/
  di/
    config.ts
  services/
    greeter.ts
  middlewares/
  main.ts
tsconfig.json
.gitignore

Teach your editor the conventions ​

If you code with an AI assistant, do this once now — before it writes its first route:

bash
npx clove skills

It writes the framework's conventions where Claude Code, Cursor, Antigravity and Codex look for them, so your assistant drops files into api/ instead of inventing a router. See AI editors.

Run it ​

bash
npm run dev

clove dev watches the source directory, regenerates .clove/types.d.ts and reloads on change. Visit http://localhost:3000/api/hello:

json
{ "message": "Hello from CloveJS" }

Add a route ​

Create src/api/v1/greet/[name].get.ts:

ts
import { get } from "clovejs"

export default get(async (req, res, ctx) => {
  return { message: ctx.greeter.greet(req.params.name) }
})

GET /api/v1/greet/ada responds with {"message":"Hello, ada!"}. Nothing was registered — the file's path became the route, and ctx.greeter came from src/services/greeter.ts.

Add a service ​

Services are singletons created once at boot. Create src/services/users.ts:

ts
import { service } from "clovejs"

export default service(async (ctx) => {
  const users = new Map<number, { id: number; name: string }>([
    [1, { id: 1, name: "Ada" }],
  ])

  return {
    findById(id: number) {
      return users.get(id) ?? null
    },
  }
})

ctx.users is now available — and typed — in every handler, middleware and other service. Returning null from a GET handler produces a 404; see the JSON middleware.

Build for production ​

bash
npm run build      # clove build: generate types, then tsc
npm start          # node dist/main.js

Where to go next ​

If you want to…Read
Understand the directory conventionsProject structure
Teach an AI assistant those conventionsAI editors
Map URLs onto filesRoutes and Route parameters
Share database clients and configValues and lifetimes
Run code around every requestMiddlewares
Add realtime endpointsWebSockets
Deploy the appDeployment

Released under the MIT License.