{"id":13515026,"url":"https://github.com/instant-dev/instant","last_synced_at":"2025-04-07T12:07:26.612Z","repository":{"id":194891738,"uuid":"691811503","full_name":"instant-dev/instant","owner":"instant-dev","description":"JavaScript API framework with ORM, migrations and vectors","archived":false,"fork":false,"pushed_at":"2024-08-23T03:18:07.000Z","size":776,"stargazers_count":269,"open_issues_count":0,"forks_count":5,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-31T10:06:27.911Z","etag":null,"topics":["api","bun","deno","javascript","migrations","nodejs","orm","postgres","postgresql"],"latest_commit_sha":null,"homepage":"https://instant.dev","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/instant-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-09-15T00:15:07.000Z","updated_at":"2025-02-28T10:20:38.000Z","dependencies_parsed_at":"2024-04-16T06:28:01.328Z","dependency_job_id":"7a911bbd-adab-4df2-80ee-0af6479ee951","html_url":"https://github.com/instant-dev/instant","commit_stats":null,"previous_names":["instant-dev/instant.dev","instant-dev/cli","instant-dev/instant"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instant-dev%2Finstant","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instant-dev%2Finstant/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instant-dev%2Finstant/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/instant-dev%2Finstant/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/instant-dev","download_url":"https://codeload.github.com/instant-dev/instant/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247648977,"owners_count":20972945,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","bun","deno","javascript","migrations","nodejs","orm","postgres","postgresql"],"created_at":"2024-08-01T05:01:05.472Z","updated_at":"2025-04-07T12:07:26.594Z","avatar_url":"https://github.com/instant-dev.png","language":"JavaScript","readme":"\u003cdiv align=\"center\"\u003e\n  \u003ch1\u003einstant.dev \u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/instant.dev?label=\"\u003e\u003c/h1\u003e\n  \u003cimg src=\"/_assets/instant.png\" height=\"128\"\u003e\n  \u003ch3\u003e\n    \u003ca href=\"https://github.com/instant-dev/orm\"\u003e@instant.dev/orm\u003c/a\u003e \u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/@instant.dev/orm?label=\"\u003e \u003cimg alt=\"build status\" src=\"https://app.travis-ci.com/instant-dev/orm.svg?branch=main\"\u003e\n  \u003c/h3\u003e\n  \u003ch3\u003e\n    \u003ca href=\"https://github.com/instant-dev/api\"\u003e@instant.dev/api\u003c/a\u003e \u003cimg alt=\"npm\" src=\"https://img.shields.io/npm/v/@instant.dev/api?label=\"\u003e \u003cimg alt=\"build status\" src=\"https://app.travis-ci.com/instant-dev/api.svg?branch=main\"\u003e\n  \u003c/h3\u003e\n  \u003chr\u003e\n\u003c/div\u003e\n\n## JavaScript + Postgres API Framework with ORM, Migrations and Vectors\n\n[**`instant.dev`**](https://instant.dev) provides a fast, reliable and\nbattle-tested ORM and migration management system for Postgres 13+ built in\nJavaScript. For those familiar with Ruby on Rails, instant.dev adds\nfunctionality similar to ActiveRecord to the Node.js, Deno and Bun ecosystems.\nWe have been using it since 2016 in production at\n[Autocode](https://autocode.com) where it has managed over 1 billion records in\na 4TB AWS Aurora Postgres instance.\n\nWith `instant.dev` you can:\n\n- Add the [Instant ORM](https://github.com/instant-dev/orm) and migrations to\n  your existing JavaScript or TypeScript project\n- Scaffold new Postgres-backed API projects from scratch using\n  [Instant API](https://github.com/instant-dev/api)\n- Generate new migrations, models and endpoints\n- Migrate remote databases and deploy in a single step\n- Connect to any PostgreSQL host: AWS RDS, Railway, Vercel Postgres, Neon,\n  Supabase\n- Instantly deploy to [Vercel](https://vercel.com)\n\nAre you interested in connecting? [Join us on Discord](https://discord.gg/puVYgA7ZMh) or follow us on\nX, [@instantdevs](https://x.com/instantdevs).\n\n\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"/_assets/instant-demo.gif\"\u003e\u003cbr\u003e\n\u003c/div\u003e\n\n## Features\n\n- [**CRUD operations**](#crud-operations)\n  - Create, Read, Update and Destroy records easily\n- [**Vector fields**](#vector-fields)\n  - Build AI-integrated applications and add search by easily creating, updating and\n    querying against vectorized representations of your data\n- [**Query composition**](#query-composition)\n  - Build complex SELECT and UPDATE queries with many layers of nested joins and\n    conditional statements\n- [**Transactions**](#transactions)\n  - Ensure data consistency within logical transaction blocks that can be rolled\n    back to prevent writing orphaned data\n- [**Input validation**](#input-validation)\n  - Synchronously validate object fields to ensure the right data is stored\n- [**Relationship verification**](#relationship-verification)\n  - Asynchronously validate relationships between one or more fields and\n    external resources before saving\n- [**Calculated and hidden fields**](#calculated-and-hidden-fields)\n  - Automatically populate object fields based on existing data\n- [**Lifecycle callbacks**](#lifecycle-callbacks)\n  - Execute custom logic beforeSave(), afterSave(), beforeDestroy() and\n    afterDestroy() to perform necessary build and teardown steps inside of\n    transactions\n- [**Migrations**](#migrations)\n  - Manage local database state via the filesystem to make branched git\n    development a breeze\n- [**Seeding**](#seeding)\n  - Provide custom JSON files so that all developers can share the same test\n    data across development, testing and staging environments\n- [**Code generation**](#code-generation)\n  - Automatically generate models, migrations and endpoints for your project\n\n## Table of Contents\n\n1. [Installation and Usage](#installation-and-usage)\n2. [Getting Started](#getting-started)\n3. [Using the `instant` CLI](#using-the-instant-cli)\n4. [Using the Instant ORM](#using-the-instant-orm)\n5. [Feature breakdown](#feature-breakdown)\n6. [Kits](#kits)\n   1. [Kit: auth](#kit-auth)\n      1. [Kit: auth on Autocode](#kit-auth-on-autocode)\n      2. [Kit: auth on Vercel](#kit-auth-on-vercel)\n7. [Acknowledgements](#acknowledgements)\n\n## Installation and Usage\n\n```shell\nnpm i instant.dev -g\ncd ~/projects/my-awesome-project\ninstant init\n```\n\nThat's it! The command line tool will walk you through the process of\ninitializing your `instant.dev` project. It will;\n\n- Automatically detect whether this is a new project or an existing one\n- Scaffold a new [Vercel](https://vercel.com) or [Autocode](https://autocode.com)\n  project, if necessary\n- Ask for your local database credentials\n- Initialize necessary files in the `_instant/` directory of your project\n- Create an initial migration\n\nTo install the basic `auth` kit which comes with a `User` and `AccessToken`\nmodel and associated user registration and login endpoints, use:\n\n```shell\ninstant kit auth\n```\n\nYou can read more in [Kit: auth](#kit-auth)\n\n## Using the `instant` CLI\n\nYou can look up documentation for the `instant` command line utility at any\npoint by running `instant` or `instant help`. The most commonly used methods\nare:\n\n- `instant g:model` to create a new model\n- `instant g:relationship` to create one-to-one or one-to-many relationships\n  between models\n- `instant g:endpoint` to automatically scaffold Vercel or Autocode endpoints,\n  if applicable\n- `instant db:migrate` to run migrations\n- `instant db:rollback` to rollback migrations\n- `instant db:rollbackSync` to rollback to last synchronized (filesystem x\n  database) migration\n- `instant db:bootstrap` to reset your database, run migrations, and seed data\n- `instant db:add` to add remote databases (AWS RDS, Railway, Vercel Postgres,\n  Neon, Supabase)\n- `instant serve` to run your server using Vercel, Autocode or the command\n  specified in `package.json[\"scripts\"][\"start\"]`\n- `instant sql` is a shortcut to `psql` into any of your databases\n- `instant deploy` to run outstanding migrations and deploy to Vercel or\n  Autocode\n\n## Using the Instant ORM\n\nFull documentation for the ORM can be found in the\n[@instant.dev/orm](https://github.com/instant-dev/orm) repository. Here's\na quick overview of using the ORM:\n\nImporting with CommonJS:\n\n```javascript\nconst InstantORM = require('@instant.dev/orm');\nconst Instant = new InstantORM();\n```\n\nImporting with ESM:\n\n```javascript\nimport InstantORM from '@instant.dev/orm';\nconst Instant = new InstantORM();\n```\n\nUsing the ORM:\n\n```javascript\n// Connect to your database\n// Defaults to using instant/db.json[process.env.NODE_ENV || 'development']\nawait Instant.connect();\n\n// Get the user model: can also use 'user', 'users' to same effect\nconst User = Instant.Model('User');\n\n// Create a user\nlet user = await User.create({username: 'Billy'});\n\n// log user JSON\n// {id: 1, username: 'Billy', created_at: '...', updated_at: '...'}\nconsole.log(user.toJSON());\n\n// Create multiple models at once\nconst UserFactory = Instant.ModelFactory('User');\nlet createdUsers = await UserFactory.create([\n  {username: 'Sharon'},\n  {username: 'William'},\n  {username: 'Jill'}\n]);\n\n// Retrieves users with username containing the string 'ill'\nlet users = await User.query()\n  .where({username__icontains: 'ill'})\n  .orderBy('username', 'ASC')\n  .select();\n\n// [{username: 'Billy'}, {username: 'Jill'}, {username: 'William'}]\nconsole.log(users.toJSON());\n\nusers[0].set('username', 'Silly Billy');\nawait users[0].save();\n\n// [{username: 'Silly Billy'}, {username: 'Jill'}, {username: 'William'}]\nconsole.log(users.toJSON());\n```\n\n## Feature breakdown\n\n### CRUD operations\n\n```javascript\nconst User = Instant.Model('User');\n\n/* Create */\nlet user = await User.create({\n  email: 'keith@instant.dev',\n  username: 'keith'\n});\n// Can also use new keyword to create, must save after\nuser = new User({\n  email: 'keith@instant.dev',\n  username: 'keith'\n});\nawait user.save();\n\n/* Read */\nuser = await User.find(1); // uses id\nuser = await User.findBy('email', 'keith@instant.dev');\nuser = await User.query()\n  .where({email: 'keith@instant.dev'})\n  .first();\nlet users = await User.query()\n  .where({email: 'keith@instant.dev'})\n  .select();\n\n/* Update */\nuser.set('username', 'keith_h');\nawait user.save();\n\n// Update by reading from data\nuser.read({username: 'keith_h'});\nawait user.save();\n\n// Update or Create By\nuser = await User.updateOrCreateBy(\n  'username',\n  {username: 'keith', email: 'keith+new@instant.dev'}\n);\n\n// Update query: this will bypass validations and verifications\nusers = await User.query()\n  .where({username: 'keith_h'})\n  .update({username: 'keith'});\n\n/* Destroy */\nawait user.destroy();\nawait user.destroyCascade(); // destroy model + children (useful for foreign keys)\n\n/* ModelArray methods */\nusers.setAll('username', 'instant');\nusers.readAll({username: 'instant'});\nawait users.saveAll();\nawait users.destroyAll();\nawait users.destroyCascade();\n```\n\n### Vector fields\n\n`instant.dev` comes with built-in support for [pgvector](https://github.com/pgvector/pgvector) and the\n`vector` field type. For full instructions on using vectors please check out the\n[Instant ORM: Vector fields](https://github.com/instant-dev/orm#vector-fields) documentation.\n\nSet a vector engine via a plugin (OpenAI is the default):\n\nFile `_instant/plugins/000_set_vector_engine.mjs`:\n\n```javascript\nimport OpenAI from 'openai';\nconst openai = new OpenAI({apiKey: process.env.OPENAI_API_KEY});\n\nexport const plugin = async (Instant) =\u003e {\n  Instant.Vectors.setEngine(async (values) =\u003e {\n    const embedding = await openai.embeddings.create({\n      model: 'text-embedding-ada-002',\n      input: values\n    });\n    return embedding.data.map(entry =\u003e entry.embedding);\n  });\n};\n```\n\nExplain how we want to automatically store vector fields:\n\nFile: `_instant/models/blog_post.mjs`\n\n```javascript\nimport InstantORM from '@instant.dev/orm';\n\nclass BlogPost extends InstantORM.Core.Model {\n\n  static tableName = 'blog_posts';\n\n}\n\n// Stores the `title` and `content` fields together as a vector\n// in the `content_embedding` vector field\nBlogPost.vectorizes(\n  'content_embedding',\n  (title, content) =\u003e `Title: ${title}\\n\\nBody: ${content}`\n);\n// optional, just prevents .toJSON() printing the entire array\nBlogPost.hides('content_embedding');\n\nexport default BlogPost;\n```\n\nAnd query our vector fields:\n\n```javascript\nconst blogPost = await BlogPost.create({title: `My first post`, content: `some content`});\nconst vector = blogPost.get('content_embedding'); // length 1,536 array\n\n// Find the top 10 blog posts matching \"blog posts about dogs\"\n// Automatically converts query to a vector\nlet searchBlogPosts = await BlogPost.query()\n  .search('content_embedding', 'blog posts about dogs')\n  .limit(10)\n  .select();\n```\n\nYou can read more on vector queries at\n[Composer#search](https://github.com/instant-dev/orm#composersearch) and [Composer#similarity](https://github.com/instant-dev/orm#composersimilarity).\n\n### Query composition\n\n```javascript\nconst User = Instant.Model('User');\n\n// Basic querying\nlet users = await User.query()\n  .where({id__in: [7, 8, 9]})\n  .orderBy('username', 'ASC')\n  .limit(2)\n  .select();\n\n// Query with OR by sending in a list of where objects\nusers = await User.query()\n  .where( // Can pass in arguments or an array\n    {id__in: [7, 8, 9]},\n    {username__istartswith: 'Rom'}\n  )\n  .select();\n\n// evaluate custom values with SQL commands\n// in this case, get users where their username matches the first part of their\n// email address\nusers = await User.query()\n  .where({\n    username: email =\u003e `SPLIT_PART(${email}, '@', 1)`\n  })\n  .select();\n\n// Joins\nusers = await User.query()\n  .join('posts', {title__icontains: 'hello'}) // JOIN ON\n  .where({\n    username: 'fred',\n    posts__like_count__gt: 5 // query joined table\n  })\n  .select();\nusers.forEach(user =\u003e {\n  let posts = user.joined('posts');\n  console.log(posts.toJSON()); // log all posts\n});\n\n// Deeply-nested joins:\n// only get users who have followers that have posts with images from imgur\nusers = await User.query()\n  .join('followers__posts__images')\n  .where({followers__posts__images__url__contains: 'imgur.com'})\n  .select();\n// Access user[0].followers[0].posts[0].images[0] with...\nusers[0].joined('followers')[0].joined('posts')[0].joined('images')[0];\n\n// Queries are immutable and composable\n// Each command creates a new query object from the previous one\nlet query = User.query();\nlet query2 = query.where({username__istartswith: 'Rom'});\nlet query3 = query2.orderBy('username', 'ASC');\nlet allUsers = await query.select();\nlet romUsers = await query2.select();\nlet orderedUsers = await query3.select();\n\n// You can also just query raw SQL!\nawait Instant.database().query(`SELECT * FROM users`);\n```\n\n### Transactions\n\n```javascript\nconst User = Instant.Model('User');\nconst Account = Instant.Model('Account');\n\nconst txn = Instant.database().createTransaction();\n\nconst user = await User.create({email: 'keith@instant.dev'}, txn);\nconst account = await Account.create({user_id: user.get('id')}, txn);\nawait txn.commit(); // commit queries to database\n// OR...\nawait txn.rollback(); // if anything went wrong, rollback nullifies the queries\n\n// Can pass transactions to the following Class methods\nawait Model.find(id, txn);\nawait Model.findBy(field, value, txn);\nawait Model.create(data, txn);\nawait Model.update(id, data, txn);\nawait Model.updateOrCreateBy(field, data, txn);\nawait Model.query().count(txn);\nawait Model.query().first(txn);\nawait Model.query().select(txn);\nawait Model.query().update(fields, txn);\n// Instance methods\nawait model.save(txn);\nawait model.destroy(txn);\nawait model.destroyCascade(txn);\n// Instance Array methods\nawait modelArray.saveAll(txn);\nawait modelArray.destroyAll(txn);\nawait modelArray.destroyCascade(txn);\n```\n\n### Input validation\n\nFile: `_instant/models/user.mjs`\n\n```javascript\nimport InstantORM from '@instant.dev/orm';\n\nclass User extends InstantORM.Core.Model {\n\n  static tableName = 'users';\n\n}\n\n// Validates email and password before .save()\nUser.validates(\n  'email',\n  'must be valid',\n  v =\u003e v \u0026\u0026 (v + '').match(/.+@.+\\.\\w+/i)\n);\nUser.validates(\n  'password',\n  'must be at least 5 characters in length',\n  v =\u003e v \u0026\u0026 v.length \u003e= 5\n);\n\nexport default User;\n```\n\nNow validations can be used;\n\n```javascript\nconst User = Instant.Model('User');\n\ntry {\n  await User.create({email: 'invalid'});\n} catch (e) {\n  // Will catch a validation error\n  console.log(e.details);\n  /*\n    {\n      \"email\": [\"must be valid\"],\n      \"password\": [\"must be at least 5 characters in length\"]\n    }\n  */\n}\n```\n\n### Relationship verification\n\nFile: `_instant/models/user.mjs`\n\n```javascript\nimport InstantORM from '@instant.dev/orm';\n\nclass User extends InstantORM.Core.Model {\n\n  static tableName = 'users';\n\n}\n\n// Before saving to the database, asynchronously compare fields to each other\nUser.verifies(\n  'phone_number',\n  'must correspond to country and be valid',\n  async (phone_number, country) =\u003e {\n    let phoneResult = await someAsyncPhoneValidationAPI(phone_number);\n    return (phoneResult.valid === true \u0026\u0026 phoneResult.country === country);\n  }\n);\n\nexport default User;\n```\n\nNow verifications can be used;\n\n```javascript\nconst User = Instant.Model('User');\n\ntry {\n  await User.create({phone_number: '+1-416-555-1234', country: 'SE'});\n} catch (e) {\n  // Will catch a validation error\n  console.log(e.details);\n  /*\n    {\n      \"phone_number\": [\"must correspond to country and be valid\"],\n    }\n  */\n}\n```\n\n### Calculated and hidden fields\n\nFile: `_instant/models/user.mjs`\n\n```javascript\nimport InstantORM from '@instant.dev/orm';\n\nclass User extends InstantORM.Core.Model {\n\n  static tableName = 'users';\n\n}\n\nUser.calculates(\n  'formatted_name',\n  (first_name, last_name) =\u003e `${first_name} ${last_name}`\n);\nUser.hides('last_name');\n\nexport default User;\n```\n\n```javascript\nconst User = Instant.Model('User');\n\nlet user = await User.create({first_name: 'Steven', last_name: 'Nevets'});\nlet name = user.get('formatted_name') // Steven Nevets\nlet json = user.toJSON();\n/*\n  Last name is hidden from .hides()\n  {\n    first_name: 'Steven',\n    formatted_name: 'Steven Nevets'\n  }\n*/\n```\n\n### Lifecycle callbacks\n\nFile: `_instant/models/user.mjs`\n\n```javascript\nimport InstantORM from '@instant.dev/orm';\n\nclass User extends InstantORM.Core.Model {\n\n  static tableName = 'users';\n\n  async beforeSave (txn) {\n    const NameBan = this.getModel('NameBan');\n    const nameBans = NameBan.query()\n      .where({username: this.get('username')})\n      .limit(1)\n      .select(txn);\n    if (nameBans.length) {\n      throw new Error(`Username \"${this.get('username')}\" is not allowed`);\n    }\n  }\n\n  async afterSave (txn) {\n    // Create an account after the user id is set\n    // But only when first creating the user\n    if (this.isCreating()) {\n      const Account = this.getModel('Account');\n      await Account.create({user_id: this.get('id')}, txn);\n    }\n  }\n\n  async beforeDestroy (txn) { /* before we destroy */ }\n  async afterDestroy (txn) { /* after we destroy */ }\n\n}\n\nexport default User;\n```\n\n### Migrations\n\n```shell\ninstant g:migration\n```\n\nCan be used to generate migrations like:\n\n```json\n{\n  \"id\": 20230921192702,\n  \"name\": \"create_users\",\n  \"up\": [\n    [\n      \"createTable\",\n      \"users\",\n      [\n        {\n          \"name\": \"email\",\n          \"type\": \"string\",\n          \"properties\": {\n            \"nullable\": false,\n            \"unique\": true\n          }\n        },\n        {\n          \"name\": \"password\",\n          \"type\": \"string\",\n          \"properties\": {\n            \"nullable\": false\n          }\n        }\n      ]\n    ]\n  ],\n  \"down\": [\n    [\n      \"dropTable\",\n      \"users\"\n    ]\n  ]\n}\n```\n\n### Seeding\n\nReset your database and seed values from `_instant/seed.json`;\n\n```shell\ninstant db:bootstrap\n```\n\n`seed.json` is an Array of seeds. Anything in the same object is seeded\nsimultaneously and there are no guarantees on order. Otherwise, the seeds are\nrun in the order provided by the Array.\n\n```json\n[\n  {\n    \"User\": [\n      {\"email\": \"keith@instant.dev\"}\n    ]\n  },\n  {\n    \"User\": [{\"email\": \"scott@instant.dev\"}],\n    \"Post\": [{\"title\": \"Post by Keith\", \"user_id\": 1}]\n  }\n]\n```\n\n### Code Generation\n\nFive types of code generation are supported:\n\n- **Kits**: Generated from `src/kits`, add in complete models,\n  migrations and automatically adds dependencies\n  - `instant kit [kitName]`\n- **Models**: Generates a new model and associated migration\n  - `instant g:endpoint`\n- **Migrations**: Generates a new migration\n  - `instant g:migration`\n- **Relationships**: Generates a new migration that connect models in a\n  one-to-one or many-to-many orientation\n  - `instant g:relationship`\n- **Endpoints**: Generates CRUD endpoints for a model from `src/endpoint`\n  - `instant g:endpoint`\n\n## Kits\n\nKits provide an easy way to add complex functionality to your `instant.dev` apps\nwithout having to write code from scratch. Currently kits support development\nusing [Autocode](https://autocode.com/) and [Vercel](https://vercel.com/).\n\nNote that the [Autocode CLI](https://github.com/acode/cli) comes packaged with\nits own HTTP wrapper, where `lib .fn.name` will call `/fn/name` on the service\nwith a POST request. The `-a` option is shorthand for providing an\n`Authorization: Bearer` header.\n\n### Kit: auth\n\n```shell\ninstant kit auth\n```\n\nCreates a `User` and `AccessToken` model, as well as corresponding\nendpoints.\n\n#### Kit: auth on Autocode\n\n##### POST `users/create`\n\n```shell\nlib .users.create \\\n  --email keith@instant.dev \\\n  --password mypass \\\n  --repeat_password=mypass\n```\n\n```json\n{\n  \"id\": 1,\n  \"email\": \"keith@instant.dev\",\n  \"created_at\": \"2023-09-18T22:46:44.866Z\",\n  \"updated_at\": \"2023-09-18T22:46:44.940Z\"\n}\n```\n\n##### POST `auth`\n\n```shell\nlib .auth \\\n  --username keith@instant.dev \\\n  --password=mypass \\\n  --grant_type=password\n```\n\n```json\n{\n  \"key\": \"secret_development_XXX\",\n  \"ip_address\": \"::ffff:127.0.0.1\",\n  \"user_agent\": \"curl/7.79.1\",\n  \"expires_at\": \"2023-10-18T22:53:36.967Z\",\n  \"is_valid\": true,\n  \"created_at\": \"2023-09-18T22:53:36.967Z\",\n  \"updated_at\": \"2023-09-18T22:53:36.967Z\",\n}\n```\n\n##### GET `users/me`\n\n```shell\nlib .users.me -a secret_development_XXX\n```\n\n```json\n{\n  \"id\": 1,\n  \"email\": \"keith@instant.dev\",\n  \"created_at\": \"2023-09-18T22:46:44.866Z\",\n  \"updated_at\": \"2023-09-18T22:46:44.940Z\"\n}\n```\n\n##### GET `users`\n\n```shell\nlib .users -a secret_development_XXX\n```\n\n```json\n[\n  {\n    \"id\": 1,\n    \"email\": \"keith@instant.dev\",\n    \"created_at\": \"2023-09-18T22:46:44.866Z\",\n    \"updated_at\": \"2023-09-18T22:46:44.940Z\"\n  }\n]\n```\n\n#### Kit: auth on Vercel\n\n##### POST `api/users`\n\n```shell\ncurl localhost:3000/api/users --data \\\n  \"email=keith@instant.dev\u0026password=mypass\u0026repeat_password=mypass\"\n```\n\n```json\n{\n  \"id\": 1,\n  \"email\": \"keith@instant.dev\",\n  \"created_at\": \"2023-09-18T22:46:44.866Z\",\n  \"updated_at\": \"2023-09-18T22:46:44.940Z\"\n}\n```\n\n##### POST `api/auth`\n\n```shell\ncurl localhost:3000/api/auth --data \\\n  \"username=keith@instant.dev\u0026password=mypass\u0026grant_type=password\"\n```\n\n```json\n{\n  \"key\": \"secret_development_XXX\",\n  \"ip_address\": \"::ffff:127.0.0.1\",\n  \"user_agent\": \"curl/7.79.1\",\n  \"expires_at\": \"2023-10-18T22:53:36.967Z\",\n  \"is_valid\": true,\n  \"created_at\": \"2023-09-18T22:53:36.967Z\",\n  \"updated_at\": \"2023-09-18T22:53:36.967Z\",\n}\n```\n\n##### GET `api/users/me`\n\n```shell\ncurl localhost:3000/api/users/me \\\n  -H \"Authorization: Bearer secret_development_XXX\"\n```\n\n```json\n{\n  \"id\": 1,\n  \"email\": \"keith@instant.dev\",\n  \"created_at\": \"2023-09-18T22:46:44.866Z\",\n  \"updated_at\": \"2023-09-18T22:46:44.940Z\"\n}\n```\n\n##### GET `api/users`\n\n```shell\ncurl localhost:3000/api/users \\\n  -H \"Authorization: Bearer secret_development_XXX\"\n```\n\n```json\n[\n  {\n    \"id\": 1,\n    \"email\": \"keith@instant.dev\",\n    \"created_at\": \"2023-09-18T22:46:44.866Z\",\n    \"updated_at\": \"2023-09-18T22:46:44.940Z\"\n  }\n]\n```\n\n# Acknowledgements\n\nSpecial thank you to [Scott Gamble](https://x.com/threesided) who helps run all of the front-of-house work for instant.dev 💜!\n\n| Destination | Link |\n| ----------- | ---- |\n| Home | [instant.dev](https://instant.dev) |\n| GitHub | [github.com/instant-dev](https://github.com/instant-dev) |\n| Discord | [discord.gg/puVYgA7ZMh](https://discord.gg/puVYgA7ZMh) |\n| X / instant.dev | [x.com/instantdevs](https://x.com/instantdevs) |\n| X / Keith Horwood | [x.com/keithwhor](https://x.com/keithwhor) |\n| X / Scott Gamble | [x.com/threesided](https://x.com/threesided) |\n","funding_links":[],"categories":["JavaScript","api"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstant-dev%2Finstant","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Finstant-dev%2Finstant","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Finstant-dev%2Finstant/lists"}