Exposed

JetBrains' SQL ORM library for Kotlin — provides two APIs: DSL (type-safe Kotlin SQL DSL) and DAO (ActiveRecord-style entity objects). The DSL API maps Kotlin operations to SQL: SchemaUtils.create(Users), Users.select { Users.name eq "agent" }.firstOrNull(). The DAO API provides Entity classes (similar to Hibernate) with automatic CRUD. Supports PostgreSQL, MySQL, SQLite, Oracle, H2, SQL Server, and MariaDB. Designed for Kotlin-first usage (coroutine support, Kotlin data types). The go-to database library for Ktor backend services.

Evaluated Mar 06, 2026 (0d ago) v0.50.x
Homepage ↗ Repo ↗ Developer Tools kotlin database sql orm dsl jetbrains jdbc type-safe ktor
⚙ Agent Friendliness
63
/ 100
Can an agent use this?
🔒 Security
85
/ 100
Is it safe for agents?
⚡ Reliability
75
/ 100
Does it work consistently?

Score Breakdown

⚙ Agent Friendliness

MCP Quality
--
Documentation
78
Error Messages
78
Auth Simplicity
92
Rate Limits
92

🔒 Security

TLS Enforcement
92
Auth Strength
85
Scope Granularity
80
Dep. Hygiene
85
Secret Handling
85

Parameterized DSL queries prevent SQL injection. Type-safe DSL structurally prevents SQL injection for DSL queries. Raw SQL via exec() requires careful parameterization. TLS via JDBC URL configuration.

⚡ Reliability

Uptime/SLA
78
Version Stability
72
Breaking Changes
65
Error Recovery
85
AF Security Reliability

Best When

You're building Kotlin backend services (especially with Ktor) and want a Kotlin-native database DSL with type-safe queries and optional DAO layer without Java ORM complexity.

Avoid When

You need robust migration tooling (use Flyway + JDBI), you're in a Java project (use jOOQ or MyBatis), or you need reactive JDBC (use R2DBC).

Use Cases

  • Build type-safe database access for Ktor agent backends using Exposed DSL — agent queries written in Kotlin DSL with compile-time type checking
  • Implement Kotlin-idiomatic agent data access using Exposed DAO — AgentEntity extends IntEntity with automatic CRUD (Agent.new { name = "agent" })
  • Use Exposed with coroutines for async agent database access — newSuspendedTransaction { ... } wraps database operations in coroutine context
  • Create and manage agent database schemas using Exposed SchemaUtils — SchemaUtils.create(AgentTable, TaskTable) in application startup; SchemaUtils.createMissingTablesAndColumns for incremental updates
  • Write complex agent query joins using Exposed DSL — (Agents innerJoin Tasks).select { Agents.status eq "active" } compiles to SQL JOIN with type safety

Not For

  • Non-Kotlin JVM projects — Exposed is Kotlin-specific; use jOOQ (Java DSL), MyBatis, or Hibernate for Java projects
  • Teams preferring Slick (Scala) or Doobie (Scala FP) — Exposed is the Kotlin equivalent; for Scala, use Slick or Doobie
  • Production apps requiring mature migration tooling — Exposed has basic SchemaUtils.createMissingTablesAndColumns; for robust migrations use Flyway or Liquibase alongside Exposed

Interface

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

Authentication

Methods: none
OAuth: No Scopes: No

Database library — no auth concepts. Database credentials via HikariCP DataSource or Exposed's Database.connect(url, driver, user, password).

Pricing

Model: open_source
Free tier: Yes
Requires CC: No

Exposed is Apache 2.0 licensed, maintained by JetBrains. Free for all use.

Agent Metadata

Pagination
offset
Idempotent
Full
Retry Guidance
Not documented

Known Gotchas

  • All operations must be inside transaction { } — Exposed throws IllegalStateException if DSL operations called outside transaction context; wrap all DB access in transaction { } or newSuspendedTransaction { } for coroutines
  • Exposed version is still pre-1.0 — active development with API changes between minor versions; pin exact version in build.gradle.kts; breaking changes in 0.x releases are common
  • DAO Entity classes are thread-unsafe — Exposed DAO Entity instances are tied to the transaction that loaded them; don't pass DAO entities across transaction boundaries or to other threads without reloading
  • Missing column after schema change — SchemaUtils.createMissingTablesAndColumns adds missing columns but doesn't rename or modify existing ones; schema drift requires manual migration SQL or Flyway scripts
  • Coroutine support requires exposed-kotlin-coroutines dependency — newSuspendedTransaction is in a separate artifact; missing dependency causes NoClassDefFoundError for coroutine transaction API
  • N+1 with DAO references — accessing .agentTasks on an AgentEntity within a loop triggers per-entity query; use DSL JOINs or eagerly load with preloadLinkedObjects for agent-tasks relationships

Alternatives

Full Evaluation Report

Detailed scoring breakdown, competitive positioning, security analysis, and improvement recommendations for Exposed.

$99

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

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