SkillAgentSearch skills...

Orm

Instant ORM: JavaScript ORM for Postgres

Install / Use

/learn @instant-dev/Orm
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Instant ORM

npm version Build Status

JavaScript ORM for Postgres with built-in Vector Support

This is the core ORM package for instant.dev. It is recommended that you use it with the instant command line utility available at instant-dev/instant for easy migration management, however, it can be used as a standalone ORM. By default, upon connecting to a database, the Instant ORM will introspect your Database schema and determine appropriate models and relationships.

Table of Contents

  1. Getting Started
  2. Connecting to a Database
    1. Connecting to another Database
    2. Querying your databases directly
    3. Disconnecting
  3. Loading a Schema
  4. Loading custom Model logic
  5. Using Models
    1. CRUD operations
      1. Create
      2. Read
      3. Update
        1. Incrementing values and custom SQL
      4. Destroy
    2. Vector fields
      1. Setting a vector engine
      2. Setting a vector engine globally
      3. Using vector fields
    3. Query composition
      1. Composer instance methods
        1. Composer#safeWhere
        2. Composer#safeJoin
        3. Composer#where
          1. Custom SQL
        4. Composer#join
          1. One-to-many
          2. One-to-one
          3. Naming conventions
        5. Composer#orderBy
        6. Composer#limit
        7. Composer#groupBy
        8. Composer#aggregate
        9. Composer#search
        10. Composer#similarity
    4. Transactions
    5. Input validation
    6. Relationship verification
    7. Calculated and hidden fields
    8. Lifecycle callbacks
  6. Using Migrations, Seeding and Code Generation
  7. Acknowledgements

Getting Started

Installing the Instant ORM:

npm i @instant.dev/orm@latest --save

Initializing (CommonJS):

const InstantORM = require('@instant.dev/orm');
const Instant = new InstantORM();

Initializing (ESM):

import InstantORM from '@instant.dev/orm';
const Instant = new InstantORM();

Connecting to a Database

By default, the Instant ORM will attempt to load database credentials from _instant/db.json[process.env.NODE_ENV]["main"]:

await Instant.connect(); // connects based on _instant/db.json

However, you can also provide custom credentials to any database you'd like by passing in a cfg configuration object with the credentials in the following format:

const cfg = {
  host: 'my.postgres.host',
  port: 5432,
  user: 'postgres',
  password: '',
  database: 'postgres',
  ssl: false, // optional: acceptable values are [true, false, "unauthorized"]
  in_vpc: false, // optional: if false, will use provided SSH tunnel when deployed
  tunnel: { // optional: use this if we need to SSH tunnel into database
    host: 'my.ssh.host.com',
    port: 22,
    user: 'ec2-user',
    private_key: 'path/to/private_key.pem'
  }
};
await Instant.connect(cfg); // now connected to custom Database

You can also opt to provide a connectionString instead:

const cfg = {
  connectionString: 'postgres://postgres:mypass@my.postgres.host:5432/postgres?sslmode=true',
  in_vpc: false, // optional: if false, will use provided SSH tunnel when deployed
  tunnel: { // optional: use this if we need to SSH tunnel into database
    host: 'my.ssh.host.com',
    port: 22,
    user: 'ec2-user',
    private_key: 'path/to/private_key.pem'
  }
};
await Instant.connect(cfg); // now connected to custom Database

Connecting to another database

By default, the Instant.connect() method will assign your initial database connection the alias "main". You can access your Database object directly via:

const db = Instant.database();
const mainDb = Instant.database('main');
console.log(db === mainDb); // true, "main" is an alias for your main db

To connect to another database, simply use:

// connect
Instant.addDatabase(name, cfg);
// read
const otherDb = Instant.database(name);

Querying your databases directly

Querying your database directly is easy. To run a standalone query;

const db = Instant.database();
const result = await db.query(`SELECT * FROM my_table WHERE x = $1`, [27]);

To execute a batched transaction from prepared statements and queries;

const db = Instant.database();
// Pass in an array of statements
const result = await db.transact([
  `SELECT * FROM my_table`,
  `INSERT INTO my_table(field) VALUES((1))`,
  // Parameterized statements can be passed in as well
  [`INSERT INTO my_other_table(other_field) VALUES(($1))`, [2]]
]);

And to create a transaction that you want to work with in real-time, potentially querying third party services before deciding whether or not to commit the query:

const db = Instant.database();
const txn = db.createTransaction();

let result = await txn.query(`SELECT * FROM my_table WHERE x = $1`, [27]);
let result2 = await txn.query(`INSERT INTO my_table(field) VALUES(($1))`, [5]);
let manyQueries = await txn.transact([
  `SELECT * FROM my_table`,
  `INSERT INTO my_table(field) VALUES((1))`,
]);
// to commit
await txn.commit();
// to rollback
await txn.rollback();

Disconnecting

To disconnect from a specific database:

Instant.closeDatabase(name);

And to disconnect from all open databases and reset your connection:

await Instant.disconnect();

Loading a Schema

When you connect to a database, Instant ORM will attempt to determine the schema of your database in a few ways.

  • First, it will check to see if _instant/cache/schema.json exists
    • If it does, it will load the schema from this file
  • Next, it will check to see if an _instant_migrations table exists in your database
    • This table holds all migrations applied to the database and is generated by the instant.dev CLI automatically
    • If it does exist and has entries, it will load the schema from the latest migration
  • Finally, it will introspect your database structure
    • All tables, columns, sequences and constraints will be inspected
    • Foreign keys and uniqueness will be used to determine one-to-one and one-to-many relationships

Additionally, you can also pass a custom schema object to the Instant.connect(cfg) method as a second argument, but this is not recommended. It is usually reserved for testing purposes.

Loading custom Model logic

By default, the Instant ORM will load models from the _instant/models directory. You do not need a model file for every, or even any, table in your database. These are only meant to extend models in the case you want to add Lifecycle callbacks, validations, verifications, calculated fields or hide data. Each file should look something like this;

File: _instant/models/sample_model.mjs

import InstantORM from '@instant.dev/orm';

class SampleModel extends Model {

  static tableName = 'sample_models';

  async beforeSave (txn) {}
  async afterSave (txn) {}
  async beforeDestroy (txn) {}
  async afterDestroy (txn) {}

}

SampleModel.calculates(/* ... */);
SampleModel.validates(/* ... */);
SampleModel.verifies(/* ... */);
SampleModel.hides(/* ... */);

export default SampleModel;

The Instant ORM will automatically associate each file with the appropriate table in your database schema, provided SampleModel.tableName matches a table on your Database. You can access your Models using;

// Note that "SampleModels", "samplemodel", "sample_models" etc.
// will all work as well as long as there's no ambiguity
Instant.Model('SampleModel');

Using Models

Models are accessible via the Instant.Model(modelName) method. This method will automatically look up the most likely model based on the matching table in your database schema.

const User = Instant.Model('User');

This method would also accept the strings Users, user, users. If your table has pluralization and underscores we recommend using the singular version, but you can access using the table name as well. For example, the table name object_children could be accessed via:

const ObjectChild = Instant.Model('ObjectChild'); // recommended

However, the following would also work:

Instant.Model('ObjectChildren');
Instant.Model('object_child');
Instant.Model('object_children');

In the case of ambiguity - multiple tables potentially matching the object name - Instant.Model() will throw an error and ask you to use the specific table.

CRUD Operations

Create

You can create new model instances and save them to the database with Model.create(data) or new Model(data) and then a subsequent model.save():

const User = Instant.Model('User');

// Model.crea
View on GitHub
GitHub Stars65
CategoryData
Updated7d ago
Forks2

Languages

JavaScript

Security Score

100/100

Audited on Mar 19, 2026

No findings