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

Evaluated Mar 06, 2026 (0d ago) v1.x
Homepage ↗ Repo ↗ Developer Tools scala database jdbc postgresql functional-programming typelevel cats-effect sql pure-fp
⚙ Agent Friendliness
64
/ 100
Can an agent use this?
🔒 Security
89
/ 100
Is it safe for agents?
⚡ Reliability
82
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
85
Error Messages
82
Auth Simplicity
90
Rate Limits
88

🔒 Security

TLS Enforcement
100
Auth Strength
88
Scope Granularity
82
Dep. Hygiene
88
Secret Handling
85

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

Uptime/SLA
85
Version Stability
82
Breaking Changes
78
Error Recovery
85
AF Security 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

REST API
No
GraphQL
No
gRPC
No
MCP Server
No
SDK
Yes
Webhooks
No

Authentication

Methods: none
OAuth: No Scopes: No

Doobie manages database credentials via HikariTransactor configuration. Database username/password passed through Transactor.fromHikariConfig or environment variables. No web auth.

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

Doobie is MIT licensed, maintained by Rob Norris (tpolecat). Free for all use.

Agent Metadata

Pagination
cursor
Idempotent
Full
Retry Guidance
Documented

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.

$99

Scores are editorial opinions as of 2026-03-06.

5220
Packages Evaluated
26151
Need Evaluation
173
Need Re-evaluation
Community Powered