DEV Community

Alex Spinov
Alex Spinov

Posted on

EdgeDB Has a Free API — Here's How to Build Apps with the Next-Gen PostgreSQL

Why EdgeDB?

EdgeDB is a next-generation database built on top of PostgreSQL. It fixes PostgreSQL's pain points: no more JOINs for simple queries, no more ORMs, built-in schema migrations, and a powerful query language (EdgeQL) that's more intuitive than SQL.

EdgeDB Cloud free tier: 1 GB storage, 1 instance.

Getting Started

Install

curl --proto '=https' --tlsv1.2 -sSf https://sh.edgedb.com | sh
edgedb project init
Enter fullscreen mode Exit fullscreen mode

Define Schema

# dbschema/default.esdl
module default {
  type User {
    required name: str;
    required email: str {
      constraint exclusive;
    };
    plan: str {
      default := 'free';
    };
    multi posts := .<author[is Post];
    created_at: datetime {
      default := datetime_current();
    };
  }

  type Post {
    required title: str;
    content: str;
    required author: User;
    published: bool {
      default := false;
    };
    tags: array<str>;
    views: int64 {
      default := 0;
    };
  }
}
Enter fullscreen mode Exit fullscreen mode

Migrate

edgedb migration create
edgedb migrate
Enter fullscreen mode Exit fullscreen mode

EdgeQL (Better Than SQL)

# Insert with nested relation — no separate INSERT needed
insert User {
  name := 'Alice',
  email := 'alice@example.com',
  plan := 'pro'
};

insert Post {
  title := 'Getting Started with EdgeDB',
  content := 'EdgeDB makes databases enjoyable...',
  author := (select User filter .email = 'alice@example.com'),
  published := true,
  tags := ['edgedb', 'tutorial']
};

# Query with nested objects — NO JOIN!
select Post {
  title,
  views,
  author: { name, email, plan }
}
filter .published = true
order by .views desc
limit 10;

# Aggregation
select User {
  name,
  post_count := count(.posts),
  total_views := sum(.posts.views),
  published_posts := count(.posts filter .published = true)
}
order by .total_views desc;
Enter fullscreen mode Exit fullscreen mode

TypeScript Client (Fully Typed!)

import { createClient } from "edgedb";
import e from "./dbschema/edgeql-js"; // auto-generated query builder

const client = createClient();

// Type-safe query builder
const users = await e.select(e.User, (user) => ({
  name: true,
  email: true,
  plan: true,
  posts: (post) => ({
    title: true,
    views: true,
    filter: e.op(post.published, "=", true)
  }),
  order_by: { expression: user.name, direction: e.ASC }
})).run(client);

users.forEach(u => {
  console.log(`${u.name} (${u.plan}): ${u.posts.length} posts`);
});

// Or use EdgeQL strings
const result = await client.query(`
  select Post {
    title, views, author: { name }
  } filter .published = true
  order by .views desc
  limit 5
`);
Enter fullscreen mode Exit fullscreen mode

Python Client

import edgedb

client = edgedb.create_client()

# Query
users = client.query("""
    select User {
        name,
        email,
        post_count := count(.posts),
        recent_posts := (
            select .posts {
                title, views
            } order by .views desc
            limit 3
        )
    }
    filter .plan = 'pro'
""")

for user in users:
    print(f"{user.name}: {user.post_count} posts")
    for post in user.recent_posts:
        print(f"  - {post.title} ({post.views} views)")
Enter fullscreen mode Exit fullscreen mode

EdgeDB vs Traditional ORMs

Pain Point SQL + ORM EdgeDB
N+1 queries Common trap Impossible (nested by design)
Schema migrations Manual/fragile Auto-generated
Type safety Runtime errors Compile-time (query builder)
JOINs Required Not needed (computed links)
Setup ORM + migration tool + DB One tool

Need data for your EdgeDB app? I build production-ready scrapers. Check out my Apify actors or email spinov001@gmail.com for custom data pipelines.

Have you tried EdgeDB? How does EdgeQL feel vs SQL? Share below!

Top comments (0)