Skip to Content
🐺 Vovk.ts is released. Read the blog post →
Manual Install

Manual Install

Create a Next.js project (App Router + TypeScript)

npx create-next-app my-app --ts --app --src-dir
cd my-app

Install vovk, vovk-client and vovk-cli

  • vovk is the core/runtime library.
  • vovk-client re-exports the generated TypeScript client (optional).
  • vovk-cli is the command-line interface for Vovk.ts (development dependency).
npm i vovk vovk-client
npm i -D vovk-cli

More info:

Create the config file

Create vovk.config.mjs at the project root with the following content:

vovk.config.mjs
// @ts-check /** @type {import('vovk').VovkConfig} */ const vovkConfig = {}; export default vovkConfig;

More info:

Install a validation library and enable client-side validation

For Zod validation on the server and Ajv on the client, install:

npm i zod vovk-ajv

Configure validateOnClient in your config file to enable client-side validation:

vovk.config.mjs
// @ts-check /** @type {import('vovk').VovkConfig} */ const vovkConfig = { outputConfig: { imports: { validateOnClient: 'vovk-ajv', }, }, }; export default vovkConfig;

More info:

Update the dev script and add a prebuild script

There are two ways to run Vovk.ts and the Next.js server together: explicitly and implicitly. The explicit option uses the concurrently package to run both processes (you must set PORT). The implicit option lets the Vovk.ts CLI start Next.js for you; in that case, vovk-cli assigns the port automatically.

The prebuild script runs vovk generate before next build so the client library is generated ahead of the Next.js build.

Install concurrently:

npm i -D concurrently

Update the “dev” script in package.json:

"scripts": { "build": "next build", "dev": "PORT=3000 concurrently 'vovk dev' 'next dev' --kill-others", "prebuild": "vovk generate" }

More info:

Enable decorators (optional)

In your tsconfig.json, set "experimentalDecorators" to true.

{ "compilerOptions": { "experimentalDecorators": true // ... } }

This is required only if you want to use decorators in your controllers and procedures. As an alternative you can use decorate(...) from the library to achieve the same result without enabling decorators. See Decorators Overview for details.

Create a controller

Create HelloController.ts in /src/modules/hello/ with a class of the same name.

src/modules/hello/HelloController.ts
import { get, prefix } from 'vovk'; @prefix('greetings') // prefix is optional export default class HelloController { @get('greeting') static getHello() { return { greeting: 'Hello, World!' }; } }

More info:

Create a root segment

Create the root segment /src/app/api/[[…vovk]]/route.ts, where [[…vovk]] is an “Optional Catch-all Segment” . The slug can be any valid name, such as [[…mySlug]].

In the code below, HelloRPC is the name of the generated RPC module, and HelloController is the controller created above.

src/app/api/[[...vovk]]/route.ts
import { initSegment } from 'vovk'; import HelloController from '../../../modules/hello/HelloController'; const controllers = { HelloRPC: HelloController }; // export types that are inferred by the client export type Controllers = typeof controllers; // export Next.js route handlers export const { GET, POST, PUT, DELETE } = initSegment({ controllers });

More info:

Run the dev server

Run npm run dev to start Vovk.ts and Next.js concurrently.

npm run dev

Navigate to http://localhost:3000/api/greetings/greeting  to see the result.

Create a React component

Once the client is generated, you can import it from vovk-client.

src/app/page.tsx
'use client'; import { useState } from 'react'; import { HelloRPC } from 'vovk-client'; import type { VovkReturnType } from 'vovk'; export default function MyComponent() { const [serverResponse, setServerResponse] = useState<VovkReturnType<typeof HelloRPC.getHello>>(); return ( <> <button onClick={async () => { const response = await HelloRPC.getHello(); setServerResponse(response); }} > Get Greeting from Server </button> <div>{serverResponse?.greeting}</div> </> ); }

Open http://localhost:3000  to see the result.

ℹ️

If you’re using VSCode, you may need to restart the TS server when you add a new controller class. This is the only time a manual restart is typically required; other changes—like adding methods or updating validation—are picked up automatically.

More info:

Last updated on