Doobie
Pure functional JDBC layer for Scala built on Cats Effect. Doobie wraps JDBC in IO effects — SQL queries are values, not side effects. Provides composable fragments (fr'SQL'), type-safe query construction, automatic Scala type mapping for query results, and connection pool management (HikariCP). Queries are simple string interpolation with typed results: sql'SELECT name FROM users WHERE id = $id'.query[String].unique
Score Breakdown
⚙ Agent Friendliness
🔒 Security
Prepared statements via JDBC prevent SQL injection. Fragment composition is injection-safe. Database credentials via HikariCP config from environment. TLS via JDBC URL ssl=true parameter.
⚡ Reliability
Best When
You're building a Typelevel/Cats Effect Scala backend that needs PostgreSQL/MySQL and want to write plain SQL with type-safe result mapping and proper effect management.
Avoid When
You prefer an ORM abstraction over SQL (use Slick or Quill), or aren't using the Cats Effect ecosystem. Doobie's value is tightly coupled to its IO/Resource integration.
Use Cases
- • Query PostgreSQL/MySQL from Scala agent backends using simple SQL string interpolation with automatic result mapping to case classes
- • Compose SQL queries as values using doobie's Fragment type — build dynamic WHERE clauses by combining fragments without string concatenation SQL injection risks
- • Manage database connections in Cats Effect agents using HikariTransactor with proper resource lifecycle management
- • Test database queries in isolation using Doobie's Check trait — verifies column types and nullability match Scala types at compile time against a real database
- • Execute transactional agent operations atomically using transact — wraps multiple queries in a single Cats Effect IO transaction
Not For
- • Non-Scala stacks — Doobie is Scala-specific; use SQLAlchemy (Python), JOOQ (Java), or Ecto (Elixir) for other languages
- • Teams preferring ORM-style models over SQL — Doobie is SQL-first; use Slick or Quill for ORM-style table mapping
- • Simple scripts not using Cats Effect — if you're not already using Cats Effect IO, Doobie's transactor setup adds friction
Interface
Authentication
Doobie manages database credentials via HikariTransactor configuration. Database username/password passed through Transactor.fromHikariConfig or environment variables. No web auth.
Pricing
Doobie is MIT licensed, maintained by Rob Norris (tpolecat). Free for all use.
Agent Metadata
Known Gotchas
- ⚠ HikariTransactor must be created inside Resource — using Transactor.fromHikariConfig directly without Resource leaks the connection pool on application shutdown
- ⚠ Doobie queries are not type-safe at compile time for column names — incorrect column name in SQL string only fails at runtime; use Check.run in tests to catch schema mismatches early
- ⚠ Fragment interpolation prevents SQL injection by using prepared statements — but fr'...' fragments must be composed, not concatenated with Scala string interpolation, to maintain injection safety
- ⚠ Streams from doobie (sql'...'.stream) require transact — Doobie streams must be transacted before fs2 Stream operations; failing to transact releases the connection before data is consumed
- ⚠ Null handling in Doobie requires Option types — non-optional Scala types in queries mapped to nullable SQL columns throw NullPointerException at runtime; always use Option[T] for nullable columns
- ⚠ Large result sets should use .stream not .list — sql'...'.query[T].list loads all rows into memory; use .stream for paginated consumption of large agent datasets
Alternatives
Full Evaluation Report
Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Doobie.
Scores are editorial opinions as of 2026-03-06.