First impressions with EdgeDB

Somehow I totally missed the HN launch of EdgeDB v1 and the surrounding discussion. Luckily for me, the echo chambers of Twitter had my back…

This morning I had a little play around with EdgeDB and I have to say that I’m very impressed. These are some thoughts that I’ve cooked up in about five minutes that outline some of my impressions and wishes.


The install process (on a mac, at least) was extremely smooth. They have a section in the docs about deployment with docker and I believe, overall, they’re trying to push users away from that. I can get behind that since I tend to like to get hands-on with the tools that I’m using; the “docker everything crowd” might not be so receptive.

My one minor annoyance was the default installation location on a mac ends up in /Users/mattw/Library/<a variety of folders>. I’m not an apple person so I don’t understand if there is any significance to this, however, it’s a lot more awkward than /usr/local/. This comes up later.

Project Instantiation

More big points for this. Prisma v2 really seems to have raised the bar for a smooth experience (a connection to prisma being one that I seem to make a lot when reflecting on EdgeDB) and there’s a lot that feels familiar here: wizard-style scripts to initialize things, simple schema files and migrations that are mostly magically handled for you, clear, rich feedback from the CLI.


Again, lots of good things to say: clear, fairly concise, good pacing to introductory guides and understandable structure for reference material. The interactive widgets to start trying things out are an excellent addition and I totally agree on the choice to lean on these as learning aids.


After about 45 mins of playing around with things, I felt I had a pretty good understanding of how the syntax worked, what the major steps I would take to make anything of worth would be, how the types and fundamental building blocks like sets combined to form powerful tools etc. etc.

What I had not done was apply this to anything useful. My next port of call was to the client libraries. I’m a fan of typesript and it looks to also be the one that’s had the most amount of effort put into it. The others look like they should be more clearly marked as ‘works in progress’.

With a good handle on what I wanted to do and the syntax I needed to do it, I dove straight in to using the client. What surprised me was that this would turn out to be the most clunky experience of the day. There’s a few points where the docs espouse the clients as almighty and superior to SQL ORMs (a fair point) but they also provide code snippets that aren’t valid typescript and a layer of abstraction on top of the new mental model that I just had to learn that isn’t actually that close.

Of particular note here is the filter syntax when creating select queries. Here was my rough thought process for the above snippet in pseudo-code:

The reference query:

select Movie {
  uppercase_title := str_upper(.title)
filter .title = "Iron Man"

// my expected use of the library, movie => ({
	id: true,
	title: true,
	uppercase_title: e.str_upper(movie.title),
	title: e.eq("Iron Man")

// the actual use of the library (also a fix for the typo in the docs), movie => ({
  id: true,
  title: true,
  uppercase_title: e.str_upper(movie.title),
  filter: e.op(movie.title, '=', 'Iron Man')

To labour this point a little more, understanding the grammar of the query language is an important step towards understanding how the database works and what it can do for you. The structures that each type of bracket provide, the way that filters work and the context provided to each of them is an important point that I think the docs stumble over but this client library makes more clear.

The client library explicitly makes it clear that the filter is part of the same context as the select statement. The type that’s removed for brevity in the filter statement refers to a specific set of results yet it sits outside of the curly brackets used to choose the desired properties. None of this, in isolation, is difficult but it’s very easy to build up slightly the wrong mental model and have to break through it later. A better introduction to the client libraries from the beginning of the guides might solve some these issues.


On first thought the native GraphQL support seems pretty cool. On second thought, it seems a bit meaningless. It’s less feature-rich, there are a bunch of limitations and notices over the docs telling you to be careful about using it and (unsurprisingly) subscriptions aren’t a thing.

There’s nothing in the way of why you might want this in the docs. I’d be interested to understand the use case. Since you can send EdgeQL over HTTP, a simpler and more flexible model, no good use case springs to mind.

That said, I did check it out and it did do as advertised. However, the standard that the rest of the tool holds itself to seems to have dropped a bit here. It’s significantly more awkward to access the graphql endpoint than anything else. The awkward install location made it even harder to find the port that I needed.


The current deployment options are a bit over the “basically free” bar that I have for experiments and I’d assume that the hosted options will include a free tier. Lower barrier to entry = more room for experiments = more adoption!


I’m looking forward to using it more! It’ll be my go-to for the next project I start.