Skip to main content
Gel (formerly EdgeDB) is a graph-relational database built on Postgres. It provides a declarative schema language, migrations system, and object-oriented query language, and also supports raw SQL queries. It solves object-relational mapping at the database layer, so your application code doesn’t need an ORM library.
First, install Gel if you haven’t already.
curl https://www.geldata.com/sh --proto "=https" -sSf1 | sh

Use bun init to create a fresh project.
terminal
mkdir my-edgedb-app
cd my-edgedb-app
bun init -y

Initialize a Gel instance for the project with the Gel CLI. The gel project init command creates a gel.toml file in the project root.
terminal
gel project init
No `gel.toml` found in `/Users/colinmcd94/Documents/bun/fun/examples/my-gel-app` or above
Do you want to initialize a new project? [Y/n]
> Y
Specify the name of Gel instance to use with this project [default: my_gel_app]:
> my_gel_app
Checking Gel versions...
Specify the version of Gel to use with this project [default: x.y]:
> x.y
┌─────────────────────┬──────────────────────────────────────────────────────────────────┐
│ Project directory   │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app         │
│ Project config      │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/gel.toml│
│ Schema dir (empty)  │ /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema│
│ Installation method │ portable package                                                 │
│ Version             │ x.y+6d5921b                                                      │
│ Instance name       │ my_gel_app                                                       │
└─────────────────────┴──────────────────────────────────────────────────────────────────┘
Version x.y+6d5921b is already downloaded
Initializing Gel instance...
Applying migrations...
Everything is up to date. Revision initial
Project initialized.
To connect to my_gel_app, run `gel`

To check that the database is running, open a REPL and run a query.
terminal
gel
gel> select 1 + 1;
2
Then run \quit to exit the REPL.
terminal
gel> \quit

Next, define a schema. The gel project init command already created a dbschema/default.esdl file to hold it.
File Tree
dbschema
├── default.esdl
└── migrations

Open that file and paste the following contents.
default.esdl
module default {
  type Movie {
    required title: str;
    releaseYear: int64;
  }
};

Then generate and apply an initial migration.
terminal
gel migration create
Created /Users/colinmcd94/Documents/bun/fun/examples/my-gel-app/dbschema/migrations/00001.edgeql, id: m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq
terminal
gel migrate
Applied m1uwekrn4ni4qs7ul7hfar4xemm5kkxlpswolcoyqj3xdhweomwjrq (00001.edgeql)

With the schema applied, query the database with Gel’s JavaScript client library. Install the client library and Gel’s codegen CLI, then create a seed.ts file.
terminal
bun add gel
bun add -D @gel/generate
touch seed.ts

Paste the following code into seed.ts. The client auto-connects to the database. The script inserts a few movies with the .execute() method, using EdgeQL’s for expression to turn the bulk insert into a single query.
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bseed.ts
import { createClient } from "gel";

const client = createClient();

const INSERT_MOVIE = `
  with movies := <array<tuple<title: str, year: int64>>>$movies
  for movie in array_unpack(movies) union (
    insert Movie {
      title := movie.title,
      releaseYear := movie.year,
    }
  )
`;

const movies = [
  { title: "The Matrix", year: 1999 },
  { title: "The Matrix Reloaded", year: 2003 },
  { title: "The Matrix Revolutions", year: 2003 },
];

await client.execute(INSERT_MOVIE, { movies });

console.log(`Seeding complete.`);
process.exit();

Then run this file with Bun.
terminal
bun run seed.ts
Seeding complete.

Gel implements several code generation tools for TypeScript. To write typesafe queries against the seeded database, generate the EdgeQL query builder with @gel/generate.
terminal
bunx @gel/generate edgeql-js
Generating query builder...
Detected tsconfig.json, generating TypeScript files.
   To override this, use the --target flag.
   Run `npx @edgedb/generate --help` for full options.
Introspecting database schema...
Writing files to ./dbschema/edgeql-js
Generation complete! 🤘
Checking the generated query builder into version control
is not recommended. Would you like to update .gitignore to ignore
the query builder directory? The following line will be added:

   dbschema/edgeql-js

[y/n] (leave blank for "y")
> y

In index.ts, import the generated query builder from ./dbschema/edgeql-js and write a select query.
https://mintcdn.com/bun-1dd33a4e/JUhaF6Mf68z_zHyy/icons/typescript.svg?fit=max&auto=format&n=JUhaF6Mf68z_zHyy&q=85&s=7ac549adaea8d5487d8fbd58cc3ea35bindex.ts
import { createClient } from "gel";
import e from "./dbschema/edgeql-js";

const client = createClient();

const query = e.select(e.Movie, () => ({
  title: true,
  releaseYear: true,
}));

const results = await query.run(client);
console.log(results);

results; // { title: string, releaseYear: number | null }[]

Run the file with Bun to see the movies you inserted.
terminal
bun run index.ts
[
  {
    title: "The Matrix",
    releaseYear: 1999
  }, {
    title: "The Matrix Reloaded",
    releaseYear: 2003
  }, {
    title: "The Matrix Revolutions",
    releaseYear: 2003
  }
]

See the Gel docs.