aboutsummaryrefslogtreecommitdiff
path: root/memos/WM-095.txt
blob: 779763abc88157bd1572b42e9d81f7c05912ba9f (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
Document: WM-095                                                 P. Webb
Category: Project                                             2026-06-16

                           I made a database

Abstract

   Technically it's a big fancy wrapper around Postgres but that
   still counts!

Body

   In December of last year the developers of my favorite database, Gel,
   announced[1] they were quitting the project to work for Vercel on
   building "the best Python cloud in the world." Six years was a good
   run but it wasn't enough for them to figure out how to turn a profit
   after VC money ran out. Alas.

   My previous favorite database was RethinkDB[2], though I discovered
   it about a year after its creators closed shop. Gel is now in the
   hands of the community and while there is a "blessed fork[3]," said
   fork hasn't seen much activity aside from refactored tests.

   Having experienced working with a "dead database" before, I had no
   interest in revisiting the pain that comes with eventually needing to
   grow beyond it. What drew me to RethinkDB and Gel was the built-in
   interface they both come with. I'm not a database whiz and I have
   zero interest in learning SQL; otherwise I'd use many of the popular
   ones. I'm a designer turned developer turned whomever I need to be to
   achieve a goal.

   With that in mind, I set out to see if I could build the database I
   want to use forever.

   📸[Disc][IMG1]

   ## Why?

   > Why waste the tokens building your own thing when you could
   > contribute to the existing project? Do you understand the deep
   > inner workings of Postgres and complex database logic? To what end?
   > What feature necessitates TypeScript over Python? If you're
   > consuming the database it doesn't matter what language the database
   > itself is in.

   I don't understand Python, but I understand TypeScript well enough to
   be productive with it. Deno has proven itself to be more than capable
   as a runtime to build upon and create cross-platform executables.
   Postgres is the industry standard for databases; you don't need to be
   an expert to know that. You don't need to understand the language a
   database is written in if you're using an ORM. When your database IS
   the ORM however, it'd make sense to understand that.

   These questions were posed to me when I presented my intent to the
   Gel community on Discord. Which…fair, but I'm not swayed by cynics
   (especially when I have a fantastic domain name, `disc.sh`
   is insane).

   I regularly used the chatbot in the Gel documentation for
   clarification on how to shape my esoteric queries in a way the
   database understands. When that stopped working I knew I had to begin
   work on Disc.

   ## How?

   The first order of business was going through Gel's backlog of Github
   issues and processing them against Disc's roadmap. To automate this,
   I made a script that uses Github's API to batch process all 800+
   issues. I then got Claude to analyze them; I won't share the full
   matrix because it's a LOT but here's the high-level stats from the
   analysis I ran in April.

   The category breakdown:

   - `database-core`: 1514 issues
   - `query-language`: 852 issues
   - `migrations`: 405 issues
   - `devtools`: 359 issues
   - `documentation`: 292 issues
   - `performance`: 200 issues
   - `auth`: 157 issues
   - `cli-tooling`: 132 issues
   - `cloud-hosting`: 103 issues
   - `sdk-client`: 63 issues
   - `storage`: 29 issues
   - `unrelated`: 24 issues
   - `compiler`: 7 issues
   - `code-quality`: 1 issue
   - `sql`: 1 issue

   Of these, 231 issues were deemed of high relevance, 789 issues were
   medium relevance, and 1,676 issues were low relevance.

   ## What?

   Merely having feature parity wasn't worth a new implementation, I
   wanted ease of use. I know I'm using a database but I don't have to
   fight against it.

   Here are the original Disc features that I'm super excited about.

   1. Codegen-free TypeScript query builder

      Gel's TypeScript client requires running
      `npx @gel/generate edgeql-js` after **every** schema change to
      regenerate a typed query builder that must be checked in and kept
      in sync. Disc's query builder is a runtime module; it reads a
      schema declaration and returns a structurally-typed builder which
      allows schema changes  to flow through with no rebuild step.

   2. Schema-derived REST surface (auto-generated)

      Gel exposes EdgeQL over HTTP and GraphQL via `ext::graphql`, but
      generates no conventional REST surface. REST is the default for
      many integrations (locked-down mobile clients, anything that wants
      OpenAPI, &c). Disc auto-generates a REST surface from the schema,
      runs it through the same access-policy and auth pipeline as EdgeQL
      queries, and emits a matching OpenAPI 3.1 spec.

   3. Admin UI features

      The diff tool watches `.disc` files in real time and shows the
      unsaved-but-edited schema next to the currently applied schema as
      a visual diff (added types in green, removed in red, modified with
      side-by-side property lists). An "apply" button generates and runs
      the migration in-line.

      The watcher's events are streamed over SSE at
      `/admin/schema-watch`; `POST /admin/schema-apply` runs through the
      standard `MigrationEngine`, so the lock-timeout pragma,
      advisory-lock serialization, and unsafe/ambiguous-op gate all
      compose for free.

      Gel's UI shows applied schema only; you switch to your editor and
      CLI to make changes.

      The visual query builder works by picking a root type, checking
      the fields and links to include, adding filter rows (field +
      operator + value, auto-typed by the field's SDL scalar), and
      setting order / limit / offset.

      The synthesized EdgeQL renders live in a side pane; The "run"
      button sends it through the same `/query` endpoint as the
      text editor.

      Gel's UI has a text editor with autocomplete and no
      visual builder.

      The most exciting thing about the Disc UI to me is that it's
      written in Svelte. I've been sick of the chokehold React has over
      the developer community for at least a decade. Disc, coupled with
      my recent GraphiQL UI[4] and GraphQL server[5] releases, means I'm
      finally React-free! (Ask your doctor if Svelte is right for you)

   4. Single-binary distribution

      Self-hosting Gel is an exercise in frustration. It's always felt
      like I was juggling the Gel server, Postgres, and the UI.

      Disc ships **one binary** that contains the Disc server, Postgres,
      and the UI. That's it. I'm a huge fan of Caddy's single binary
      existence and the ease with which I can spin up a new site. Happy
      to finally have a database with the same experience.

      If you hate UI, you can use Disc without it! Please look at my
      pretty pixels though.

   5. Deno-permission-aware access policies

      Because Disc runs on Deno, every running piece of code has a
      runtime permission set that access policies can reference. Disc's
      extensions share the server's permission set so all checks are
      deployment-time gates.

      Gel has application-level identity only; its Python/Rust runtime
      has no structured permission model to check against.

   ## Future?

   There's lots left to do! The documentation needs to live on its own
   site and I need to figure out Homebrew deployment. If you're skittish
   about using a new database for RealWorld™ Deployment, fret not, I'm
   insane and am building a new product using Disc as its backing store
   (I actually paused development on said product to get Disc across the
   finish line). Disc works well in development but the production story
   has yet to be tested.

   Follow me on Mastodon[6] or join the Disc board[7] on my forum to
   stay up to date. 🕸️

References

   [1] <https://www.geldata.com/blog/gel-joins-vercel>
   [2] <https://rethinkdb.com>
   [3] <https://github.com/gelstable/gel>
   [4] <https://code.webb.page/eol/graphiql.git/about/>
   [5] <https://code.webb.page/eol/gq.git/about/>
   [6] <https://social.coop/@netopwibby>
   [7] <https://www.webb.page/index.php?board=6.0>
   [IMG1] <https://cdn.webb.page/blog/2026/wm-095-a.png>