Parrot – Type-Safe SQL in Gleam, Supports Sqlite, Postgresql and Mysql
Posted3 months agoActive3 months ago
github.comTechstory
supportivepositive
Debate
20/100
GleamSQLType SafetyDatabase
Key topics
Gleam
SQL
Type Safety
Database
The HN community discusses Parrot, a Gleam library for type-safe SQL, and compares it to similar projects like sqlc and Kysely, highlighting the benefits of type safety and raw SQL queries.
Snapshot generated from the HN discussion
Discussion Activity
Active discussionFirst comment
3h
Peak period
15
6-12h
Avg / period
5.7
Comment distribution34 data points
Loading chart...
Based on 34 loaded comments
Key moments
- 01Story posted
Oct 4, 2025 at 8:51 PM EDT
3 months ago
Step 01 - 02First comment
Oct 5, 2025 at 12:17 AM EDT
3h after posting
Step 02 - 03Peak activity
15 comments in 6-12h
Hottest window of the conversation
Step 03 - 04Latest activity
Oct 7, 2025 at 9:25 PM EDT
3 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45478033Type: storyLast synced: 11/20/2025, 5:30:06 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
https://github.com/weedonandscott/omnimessage
I wonder how Gleam compares to the type checking support being added to Elixir?
To me, Gleam feels like if Elm’s type system met Rust’s syntax. I really like it. But I also really liked Elixir too, I just can’t live without Gleam’s type system anymore.
I think the sqlc approach is ultimately the right one for integrating SQL into code because it allows queries to be expressed using the full syntax of native SQL, and only needs to handle the input/output glue. So you get the best of both worlds: Pure SQL unencumbered by non-SQL code, and type safety. ORMs will always struggle to catch up with SQL's richness and expressiveness.
I've not used Gleam for anything yet, but this makes me more excited to try it out.
Even after years, the solutions are unsatisfactory from a database query planner perspective.
I wonder if a sufficiently smart sqlc could do the optimization itself. Basically have an SQL parser that is able to identify dynamic parts statically and encoding an efficient representation that allows constant folding at runtime.
Another weak point in sqlc is the absence of any composability, so every query has to be self-contained. But views can help you with that.
Anyway, at minimum you have prepared statements where a given plan may be great for one execution and terrible for the next. Maybe the database re-prepares for you, and then it's the same as a dynamic query.
https://www.postgresql.org/docs/current/sql-prepare.html
I've not compared the actual behaviour in the codebases I work on, however.
I'd love to see something like this for Typescript and Effect's SQL integration with schemas.
It reminds me of Jooq in Java-land. Does Parrot also try to fill-in the gaps in support between databases so that the same query works on all databases?
1. Compiles-to-SQL domain specific languages. This category spans from ORM DSLs embedded in another programming language, like Ruby/Rail's ActiveRecord/AREL or Django's ORM; to stand-alone text-based languages like PRQL Pipelined Relational Query Language" (https://prql-lang.org) that a compiler program converts to SQL text or SQL files. The downside to the DSL option is that it requires practitioners be fluent in both the SQL query they want, and in the DLS language - to know how to obtain the SQL query in the DSL.
2. Query fragment literals in the caller programming language, like sql`name = ${name}` in TypeScript (eg https://github.com/gajus/slonik). These are usually thin abstraction over concatenating a `{ queryText: string[], queryArgs: T[] }` structure. The author only needs to be fluent in SQL, and in the caller language, but do less to save you from the expressive limitations of SQL itself.
I've found query fragment composition to be the sweet spot. Easy SQL queries remain trivial to express and understand, since it's Just SQL:
But you can DRY up repetition in the codebase through regular function calls. Abbreviated example from Notion's client code: I'm not sure if it solves your "view problem", but it does a pretty good job for _my_ view problem.