Gonvex

Quickstart

Create a new Gonvex app and run it locally.

Quickstart

This page creates a Vite React app against the local self-hosted runtime.

Before creating the app, start the reference stack in a separate terminal:

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

The runtime is then available at http://localhost:8080 and the dashboard at http://localhost:3000.

Create An App

npm create gonvex@latest my-app
cd my-app
npm install

Explicit Vite React template:

npm create gonvex@latest my-app -- --template vite-react
cd my-app
npm install

The initializer creates:

my-app/
  src/
  gonvex/
    schema.go
    messages.go
    _generated/
  package.json
  gonvex.json
  .env.local

Start Development

npx gonvex dev

Framework templates usually wrap this in the app dev command. For Vite React:

npm run dev

which runs:

gonvex dev -- vite

gonvex dev:

  • connects to the configured Gonvex runtime
  • watch the gonvex/ folder
  • generate TypeScript bindings
  • upload the Go source bundle and manifest
  • apply safe schema changes
  • run the child app dev server after --

Define Schema

// gonvex/schema.go
package backend

import "github.com/gonvex/gonvex/pkg/gonvex"

func Schema(s *gonvex.Schema) {
  s.Table("tasks", func(t *gonvex.Table) {
    t.ID("id")
    t.String("title")
    t.String("status")
    t.Time("created_at")

    t.Index("by_status", "status")
    t.Index("by_created_at", "created_at")
  })
}

Define Functions

// gonvex/tasks.go
package backend

import "github.com/gonvex/gonvex/pkg/gonvex"

type ListTasksArgs struct {
  Status string `json:"status,omitempty"`
}

func Register(app *gonvex.App) {
  app.Query("tasks.list", ListTasks)
  app.Mutation("tasks.create", CreateTask)
}

func ListTasks(ctx *gonvex.QueryCtx, args ListTasksArgs) ([]Task, error) {
  // query Postgres through Gonvex APIs
}

Use Generated Bindings

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

export function Tasks() {
  const tasks = useQuery(api.tasks.list, { status: "open" });
  const createTask = useMutation(api.tasks.create);

  return <TaskList tasks={tasks ?? []} onCreate={createTask} />;
}

Connect To A Runtime Project

For real projects, connect the repo to a Gonvex project:

npx gonvex login
npx gonvex project create my-product

Project creation writes the returned project ID, runtime URL, and project key to .env.local. Use gonvex project select <project-id> to connect an existing project.

For a self-hosted production runtime, use its public HTTPS origin:

VITE_GONVEX_WS_URL=wss://gonvex.example.com/ws

Add Tenants

Create a multi-tenant project and manage workspaces through the implemented auth commands:

npx gonvex project create my-product --database-mode multiTenant
npx gonvex auth tenants create "Acme" --owner owner@acme.example
npx gonvex auth memberships add \
  --tenant <tenant-id> \
  --email teammate@acme.example \
  --role member

Runtime-created tenants receive isolated PostgreSQL databases while sharing the project's code and generated bindings.

Next Steps

On this page