SurrealDB Experience (WIP)

January 15, 2025, Rough Draft

First of all, I will start with the pros. I think it is a really interesting experience learning about the database and designing data structures with it, considering it has a hybrid approach that can both handle schema-ful and schemaless data, combining both the power of a traditional SQL database and a document database, although only the schema-ful one was useful to me. It can also act as a graph database: there are two types of tables you can create in SurrealDB, one called Normal, and one called Relational. Normal tables have ids, and relational tables have in and out fields.
The database interestingly uses record ids like user:dh3v2dc to refer to a row, and therefore it is super flexible since, for example, you can store an array of record ids that reference other tables in a single column, and use the union type, like media: record<picture> | record<video> to create polymorphic relations.
Many-to-many polymorphic relations, which is one of the hardest things to do in traditional relational databases, is literally a piece of cake to do in SurrealDB.

However, I think SurrealDB also has some cons. In particular, the ecosystem and tooling aren't really there. You won't be able to use things like PrismaORM. There is an official SDK for TypeScript, although it seems very crappy. It can only do very basic operations and isn't really type-safe, even with no type-safe select fields and where statements. Some details just seem off. For example, the update function to update a record will replace the entire object, and you must supply all required fields. You can't just update a row partially using the SDK. As an official SDK, it also surprisingly misses some features unique to SurrealDB, such as the INFO statement, which can retrieve detailed data/definitions about namespaces, databases, and tables. And weirdly, the SDK does have a function named the same as .info() although it gets user auth data.

Also keep in mind, the SurrealDB JSON field, if you do not define a specific type even if you pass in an error-typed value, it won’t throw any error. I had to manually change the field to flexible to make it behave like a JSON column in other databases. https://github.com/surrealdb/surrealdb/issues/1228

In my development with SurrealDB, I first used the Surrealist client to design table structures. One thing that annoys me is how if I need to add a common field to all tables, like created_at, I have to do that by hand with each table. Each table’s settings also pop up as a sidebar which you must collapse if you want to interact with other things so the UX isn’t super great. And also, on the Record Explorer page, you can’t multi-select records.
I used the official SDK initially but since it’s not type-safe, I switched to community tooling. While I initially stumbled upon a project named Cirql, an ORM specifically created for SurrealDB, it is no longer maintained just a week ago. I then looked at a Kysely dialect for SurrealDB, although its HTTP endpoint isn’t the newest one (/rpc) but the old one (/sql), and also due to some major changes requiring requests submitted to the /sql endpoint must have headers “surreal-ns” and “surreal-db” and not “ns” and “db”, I have to manually configure the dialect to override its fetch function for it to work. This isn’t all as I unluckily found out that SurrealDB variables cannot be defined beginning with a number, e.g. $1 $2 are invalid. This means that I also have to customize how Kysely complies with its queries since numbers are the default way Kysely generates param names. And also, the dialect added SurrealQL-specific stances like create and relate but they are not working at all. It was a lot of emm around and find out.

With that being said, I want to conclude that if unnecessary, e.g. your products database doesn’t need to utilize the flexibility of SurrealDB, doesn’t need graph-like storage, or does not have many polymorphic relations, you probably don't need it, and shouldn't be using SurrealDB as it's a lot of hassle. You'll be better off using PrismaORM with Postgres. I also want to recommend the SurrealDB team focus on working to improve the quality of these SDKs and dev tools, maybe taking official responsibility to create Kysely and Prisma integrations for the Developer Experience.