Gonvex

Initialize an Existing Project

Add Gonvex to a Vite React app, connect a runtime, and start the development loop.

Existing app · about 5 minutes

Bring your frontend.
Add a realtime Go backend.

Run one command from the root of an existing Vite React project. Gonvex adds a colocated backend, generated TypeScript bindings, and local runtime settings.

01 Install02 Initialize03 Review04 Run

Before you begin

You need an existing Vite + React project and a recent Node.js/npm installation. The initializer currently ships one template, vite-react.

!
Hosted Gonvex is not publicly available

There is no generally available paid or public Gonvex Cloud runtime today. Use the local self-hosted stack below for development, or operate the open-source runtime on your own infrastructure.

i
Starting from an empty directory?

Use npm create gonvex@latest my-app instead. It creates the complete starter and gives it the right package name.

1. Install the packages

From your app's root directory:

npm install @gonvex/client @gonvex/react
npm install --save-dev @gonvex/cli

The CLI is a development dependency; the client and React hooks ship with your app.

2. Initialize Gonvex

npx gonvex init

By default, the project ID is the current directory name and the runtime is http://localhost:8080. You can set both explicitly:

npx gonvex init \
  --project my-product \
  --runtime http://localhost:8080

The full command surface available today is:

OptionDefaultPurpose
--template vite-reactvite-reactSelects the starter files to copy.
--project <id>current folder nameSets the local runtime project ID.
--runtime <url>http://localhost:8080Sets the Gonvex runtime URL.

3. Review what changed

The initializer copies the Vite React starter into your current directory. Existing files are never overwritten. Along with the Gonvex files below, it may add any missing Vite starter files such as vite.config.ts, tsconfig.json, or files under src/, so review the complete diff before continuing:

gonvex/
├── schema.go
├── messages.go
└── _generated/
    ├── api.ts
    ├── client.ts
    ├── manifest.json
    ├── react.ts
    ├── schema.ts
    └── types.ts

gonvex.json
.env.local
!
Existing config files are left untouched

If your app already has package.json, .env.local, Vite config, or source files, the initializer does not merge them. Add the scripts and environment values below yourself.

Add the development scripts

Merge these into the scripts object in your existing package.json:

{
  "scripts": {
    "dev": "gonvex dev -- vite",
    "vite": "vite",
    "gonvex:dev": "gonvex dev",
    "gonvex:once": "gonvex dev --once"
  }
}

gonvex dev -- vite watches backend files, syncs them to the runtime, regenerates bindings, and keeps Vite running in the same terminal.

Check the project config

gonvex.json tells the CLI where your backend and generated files live. The current initializer copies this file from the template; it does not rewrite its project field from --project or the current directory. Update it so it matches your app:

{
  "project": "my-product",
  "runtime": "http://localhost:8080",
  "backendDir": "gonvex",
  "generatedDir": "gonvex/_generated",
  "tenantMode": "single"
}

Environment variables take precedence over this file when the CLI loads project and runtime settings. Keeping both in sync still makes the project easier to understand. If gonvex.json already existed, it is also left unchanged.

Check the environment

For a new .env.local, the initializer writes:

GONVEX_PROJECT_ID=my-product
GONVEX_RUNTIME_URL=http://localhost:8080
GONVEX_PROJECT_KEY=
VITE_GONVEX_WS_URL=ws://localhost:8080/ws

GONVEX_PROJECT_KEY is intentionally blank until the app is connected to a runtime project. It is server-side only: never expose it through a VITE_ variable.

If .env.local already exists, add these values yourself. The CLI reads both .env.local and .env.

After interactive project setup, the CLI also adds the public project ID and runtime URL used by the browser client:

VITE_GONVEX_PROJECT_ID=my-product
VITE_GONVEX_URL=http://localhost:8080

4. Start development

You need a running Gonvex runtime before starting the app. The quickest supported path today is the repository's Docker Compose stack.

Run Gonvex locally with Docker

In a separate terminal, clone the Gonvex repository and start its reference stack:

git clone https://github.com/Whagons-International/gonvex.git
cd gonvex
make stack

This builds and starts:

ServiceLocal addressRole
Runtimehttp://localhost:8080Functions, HTTP, WebSockets, and project routing
Dashboardhttp://localhost:3000Local project and runtime inspection
Postgreslocalhost:5432Control-plane and application data
Valkeylocalhost:6380Cache and realtime coordination
MinIO APIhttp://localhost:9000Optional S3-compatible file storage
MinIO consolehttp://localhost:9001Local storage administration

make stack waits for the core services to become healthy and creates the gonvex-dev MinIO bucket. Confirm the runtime independently with:

curl http://localhost:8080/healthz

The credentials and ports in docker-compose.yml are development defaults. Do not expose this stack directly to the internet.

Connect and run your app

Back in your application directory, ensure GONVEX_RUNTIME_URL is http://localhost:8080, then run:

npm run dev

On the first run, gonvex dev checks the configured runtime. If it cannot find a matching project, it guides you through selecting an existing project or creating a new one, then saves the project ID and key to .env.local.

You should see the CLI generate bindings and report a successful runtime sync before Vite prints its local URL.

✓
Your app is connected

Edit a file in gonvex/. The CLI rebuilds the manifest, refreshes gonvex/_generated/, and syncs the change without restarting Vite.

Self-host beyond localhost

For a remote development or production-like environment, deploy the runtime from this repository and point your app at its public HTTPS address:

GONVEX_RUNTIME_URL=https://gonvex.example.com
VITE_GONVEX_URL=https://gonvex.example.com
VITE_GONVEX_WS_URL=wss://gonvex.example.com/ws

At minimum, replace all development credentials, terminate TLS at a reverse proxy, use durable Postgres and Valkey services, persist runtime data, and configure backups. S3-compatible storage is optional unless your app uses file APIs.

Gonvex is still beta: production auth, migrations, tenant operations, and deployment automation are not hardened. See Self-hosting and deployment before putting real workloads on the runtime.

Use the generated client

Import the generated API references and React hooks from your app:

import { api } from "./gonvex/_generated/api";
import { useMutation, useQuery } from "./gonvex/_generated/react";

export function Messages() {
  const messages = useQuery(api.messages.list, {});
  const send = useMutation(api.messages.send);

  return (
    <button onClick={() => send({ body: "Hello from Gonvex" })}>
      {messages?.length ?? 0} messages
    </button>
  );
}

Do not edit anything in gonvex/_generated/ by hand; gonvex dev owns those files. The generated API nests each function under its path segments, so messages.list is accessed as api.messages.list.

Troubleshooting

The runtime cannot be reached

Confirm GONVEX_RUNTIME_URL points to a running runtime. For local development the default is http://localhost:8080.

Runtime sync is unauthorized

Set GONVEX_PROJECT_KEY to the key for this project. The interactive first-run setup can create a project and write the key for you.

The frontend cannot connect

Check that VITE_GONVEX_WS_URL uses ws:// for HTTP runtimes or wss:// for HTTPS runtimes, with the /ws path.

Initialization did not change package.json

This is expected for an existing project. The initializer protects existing files rather than merging them; add the development scripts from step 3 manually.

Next steps

On this page