Public Beta

One command.Full stack. Running.

One command. Database, API, and UI — running locally. Define your schema once. Everything else is derived. Zero config.

View on GitHub →

The problem

The typical stack

// schema.prisma — define the shape
// server/todos.ts — define it again for the API
// lib/validators.ts — define it again for validation
// hooks/useTodos.ts — define it again for fetching
// components/TodoForm.tsx — define it again for the form

5 files. Same shape. Pray they stay in sync.

With Vertz

// schema.ts — define it once
const todos = d.table('todos', {
  id:    d.uuid().primary(),
  title: d.text(),
  done:  d.boolean().default(false),
});
// TodoList.tsx — use it everywhere
const todos = query(api.todos.list());
const todoForm = form(api.todos.create);

1 schema. Everything else is derived.

How it works

One schema. Three layers. Zero wiring.

01Define your data
import { d } from '@vertz/db';

const users = d.table('users', {
  id:    d.uuid().primary({ generate: 'uuid' }),
  name:  d.text(),
  email: d.email().unique(),
});

const todos = d.table('todos', {
  id:     d.uuid().primary({ generate: 'uuid' }),
  title:  d.text(),
  done:   d.boolean().default(false),
  userId: d.uuid(),
});

export const todosModel = d.model(todos, {
  user: d.ref.one(() => users, 'userId'),
});
02Get a typed API for free
import { entity } from '@vertz/server';
import { todosModel } from './schema';

export const todos = entity('todos', {
  model: todosModel,
  access: {
    list:   (ctx) => ctx.authenticated(),
    create: (ctx) => ctx.authenticated(),
    update: (ctx, row) => ctx.userId === row.userId,
    delete: (ctx, row) => ctx.userId === row.userId,
  },
  before: {
    create: (data, ctx) => ({ ...data, userId: ctx.userId }),
  },
});
// GET  /api/todos     — auto-generated
// POST /api/todos     — auto-generated
// GET  /api/openapi   — auto-generated
03Use it with full type safety
import { query, form } from '@vertz/ui';
import { api } from './generated/client';

export function TodoList() {
  const todos = query(api.todos.list());
  const todoForm = form(api.todos.create, {
    onSuccess: () => todos.refetch(),
  });

  return (
    <form onSubmit={todoForm.onSubmit}>
      <input name="title" placeholder="What needs to be done?" />
      <button type="submit">Add</button>
      {todos.data.map((t) => (
        <li key={t.id}>{t.title}</li>
      ))}
    </form>
  );
}

Type safety

Rename a field. The compiler catches everything.

One rename. Every bug found at compile time. Zero runtime surprises.

The change

const todos = d.table('todos', {
  id:   d.uuid().primary(),
- title: d.text(),
+ name: d.text(),
done: d.boolean().default(false), });

Compile errors

API call
api.todos.create({ title: 'Buy milk' });
Property 'title' does not exist. Did you mean 'name'?
UI render
<li>{t.title}</li>
Property 'title' does not exist on type 'Todo'.

Why Vertz

One schema, every layer

Define your data once. The compiler derives your database, API, client SDK, and form validation. Change a field — it updates everywhere.

One way to do things

No choice paralysis. No tribal knowledge. Every API has one canonical pattern. Your team and your AI agent write the same code — correctly, on the first try.

Production-ready by default

Auth, validation, error handling, OpenAPI docs, deployment — built in, not bolted on. You add business logic. Vertz handles the rest.

The stack

One framework. Not fifteen npm installs.

Every layer works together because they were built together.

@vertz/schema
Runtime-safe type definitions
replaces Zod
@vertz/db
Typed queries & migrations
replaces Drizzle / Prisma
@vertz/server
Entity-based CRUD + OpenAPI
replaces Express + tRPC
@vertz/compiler
Static analysis + SDK codegen
replaces Manual glue code
@vertz/ui
Signals, query(), form(), css()
replaces React + Tailwind
@vertz/ui-primitives
Accessible components
replaces Radix / Base UI
@vertz/theme-shadcn
Pre-built styled components
replaces shadcn/ui
@vertz/ui-server
SSR, streaming, HMR dev server
replaces Next.js + Vite
@vertz/testing
API & UI test utilities on Bun
replaces Vitest + Testing Library
@vertz/cloudflare
Edge deployment
replaces Dockerfile + infra
@vertz/icons
Tree-shakeable Lucide icons
replaces lucide-react

Get started in 30 seconds.

SQLite database, REST API, and UI — all running locally. No Docker. No config files. Edit any layer and see it update instantly.

$ bun create vertz my-app
$ cd my-app
$ bun dev
✓ SQLite database ready
✓ API server on http://localhost:3000/api
✓ UI on http://localhost:3000

What about...

Is it production-ready?

Pre-v1 and moving fast. Cloudflare Workers deployment works today. We break APIs intentionally to find the best design — and we ship every improvement as a patch.

Can I use existing libraries?

Yes. Standard TypeScript, runs on Bun, npm-compatible. Use any library you want alongside Vertz.

What if I only want the UI?

Use @vertz/ui standalone. The full stack is optional — each layer works independently.

What about React / Next.js?

Vertz isn't a React wrapper. It's a different model: signals instead of VDOM, compile-time instead of runtime. If you're happy with React, stay. If you're tired of the ceremony, try Vertz.

We spent years stitching together ORMs, API frameworks, validation libraries, and UI toolkits — and watching them drift apart. We built Vertz so the next team doesn't have to.

Vinicius Dacal

Vinicius Dacal

Co-founder

15+ years building at scale. Senior Engineer at Scrunch. Previously Staff Engineer at Voiceflow. Led Angular-to-React migrations, built GraphQL servers, shipped NestJS backends — and got tired of fighting the frameworks.

@vinicius_dacal
Matheus Poleza

Matheus Poleza

Co-founder

10+ years full-stack. Seed to Series C startups. Microservices, AI integration, performance at scale — now channeling it all into one stack that does it right.

@matheeuspoleza