Hey everyone – after coming off of 3 years building with Ecto, I’ve been working non-stop on Typegres, a new query builder that strongly aligns with Ecto’s philosophy around composabilty & purity.
The core, novel idea: write class methods that compile directly to composable SQL (try it in the playground)
// Extend your models
class Post extends posts.asClass<Post>() {
// by writing methods
trendingScore() {
return this.likes.divide(this.ageInHours().plus(2)); // → SQL, not JS!
}
}
// and use them anywhere in your queries:
await Post.select((p) => ({
content: p.content,
trending: p.trendingScore(),
}))
.orderBy((p) => p.trendingScore()) // Everything composes into a single query, just like Ecto
What you’ll appreciate coming from Ecto:
- Composability: Everything is composable SQL expressions (and since it’s Typescript, it’s fully typed too)
- Purity: no N+1 queries or obscure magic – just a translation layer meant to maximize the synergy between TypeScript and Postgres
What makes Typegres different:
- True OOP in SQL: Encapsulate business logic in methods (
post.trendingScore()
) instead of scattered helper functions (and relations and graph-based querying naturally follow as a result of the composability). This a huge step towards resolving the object-relational impedance mismatch - Postgres, Postgres, Postgres: coverage for all 3000+ built-in functions/operators without SQL strings (with coverage for all statements in the works)
Github:
As a huge admirer of Ecto, I’d love to hear what this community thinks. Does this approach to unifying objects and SQL resonate with you?