I’ve been delving into PostgreSQL for JavaScript developers recently, and it’s clear that many JavaScript developers prefer to avoid writing non-JavaScript code. They embed CSS in JavaScript, HTML in JSX, and now, SQL in JavaScript! This trend is evident in the way developers use abstractions like Supabase, which sits atop PostgREST. I propose we call this syntax SamQL-Jackson.
JavaScript developers often avoid “raw SQL” for several reasons:
- I haven’t got time to learn SQL.
- I don’t want to learn SQL.
- SQL isn’t type safe.
1. “I haven’t got time to learn SQL.”
This is subjective and understandable. If you’re too busy to learn new things, that’s perfectly valid.
2. “I don’t want to learn SQL.”
This point is also subjective. Learning something uninteresting can be challenging, but SQL is widely used, making it a valuable skill.
3. “SQL isn’t type safe.”
Addressing this concern, Jiri Cincura explains that SQL commands are type-safe on the server, but not necessarily in your code. Without type definitions, there’s no type preview in the code editor, making it harder to work with database responses. Manually creating these types can be time-consuming and prone to change.
JavaScript developers often prefer SamQL-Jackson over “raw SQL” because many JavaScript database vendors offer built-in type safety in their clients and SDKs. However, each vendor’s syntax differs, requiring developers to learn new syntax if they switch providers.
For example, a simple SQL query selecting first_name
, country
, and email
from a users
table would look different in Supabase and Xata:
Supabase
View the code on Gist.
Xata
View the code on Gist.
Both queries differ, and switching providers means learning new syntax and rewriting queries. Writing SQL ensures compatibility with any PostgreSQL solution, challenging the points about time and interest in learning SQL.
For those opting for “raw SQL” but needing types, here are two solutions: kysely-codegen and pg-to-ts. Both generate TypeScript types from your database schema.
How to Use kysely-codegen
kysely-codegen generates Kysely type definitions from your database.
Kysely Installation
View the code on Gist.
Kysely package.json script
Add a script to your package.json
to create a kysely-db.d.ts
file at the root of your project.
View the code on Gist.
Kysely .env
Add a DATABASE_URL
environment variable in your .env
file.
View the code on Gist.
Kysely generate
Run the script to generate a .d.ts file with all the types for your database tables and columns.
View the code on Gist.
Kysely typed query
Use the generated types in your PostgreSQL query or as part of a component’s props interface.
View the code on Gist.
How to Use pg-to-ts
pg-to-ts generates TypeScript types matching your Postgres database schema.
pg-to-ts Installation
View the code on Gist.
pg-to-ts package.json script
Add a script to your package.json
to create a pg-to-ts-db.d.ts
file at the root of your project.
View the code on Gist.
pg-to-ts generate
Run the script to generate a .d.ts file with all the types for your database tables and columns.
View the code on Gist.
pg-to-ts typed query
Use the generated types in your PostgreSQL query or as part of a component’s props interface.
View the code on Gist.
In conclusion, SQL can be typesafe in the JavaScript sense. With automated type generation, schema changes are manageable, making “raw SQL” a viable option for JavaScript developers.