Vasta Logo
Models

Defining Models

Building models with Vasta.

Define your Kysely instance and types

Begin by following the Kysely instructions for setting up your database Types and connection.

You can see an example of database types used by this repository for testing in test/types/database.ts. An example database connection can be found in test/database/db.ts.

This is all just standard Kysely setup up to this point, so follow their instructions for this part!

Define your Vasta Models

You'll need to create new classes for each of your models, extending the defineModel function provided by Vasta. Each model should specify the corresponding table name and define its attributes.

The defineModel function takes a configuration object as a paramter. Here are some minumum properties for the configuration object:

  • db: This should be set to your Kysely database instance.
  • table: This should be set to the name of the table in your database that this model represents. This should be a string typed as const.
  • primaryKey: (optional) the primary key column for the table, defaults to "id".
database/models/Person.ts
import { defineModel } from "vasta-orm";
import db from "@/database/db";

export default class Person extends defineModel({
  db, // Your Kysely database instance
  table: "people", // the name of the table in your Kysely database type that this model represents
  id: "id", // optional, defaults to "id"
}) {}

Model Functions

You can define your own functions on your models to handle common operations.

As an example, let's say we want to have a function to increment a counter on our model. We can define this function on our model like so:

export default class Pet extends defineModel({
  // ...model config
}) {
  // increment a counter and save the model in a single call
  incrementCounter() {
    console.log("Incrementing counter for pet:", this.attributes.name);
    this.attributes.counter += 1;
    return this.save();
  }
}

And then that function can be called on the model instance directly.

const pet = await Pet.findOrFail(1);
await pet.incrementCounter(); // This function will increment the counter and save the model in a single call

Hidden Fields

Use the hidden option to keep sensitive columns out of serialized model output. When a field is listed in hidden, it is omitted from toJSON() and JSON.stringify(model), but it still exists on model.attributes.

A good example of this is a password field on a User model. You want to be able to access the password when you need to, but you don't want it to be included when you serialize the model to JSON.

database/models/User.ts
import { defineModel } from "vasta-orm";
import db from "@/database/db";

export default class User extends defineModel({
  db,
  table: "users",
  hidden: ["password"],
}) {}

Default Attributes

You can also specify default attributes for your models. These attributes will be applied to the model instance if they are not provided in the new model constructor when creating a new instance of a model. Creating a new instance without passing in attributes included in the defaults will not throw a type error since they are provided by the default attributes setting.

export default class Pet extends defineModel({
  // ...other config
  attributes: {
    counter: 0,
    type: () => "dragon", // You can also use a function to set dynamic defaults
  },
}) {
Copyright © 2026