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.
Score Breakdown
⚙ Agent Friendliness
🔒 Security
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
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
Authentication
Database library — no auth concepts. Database credentials via HikariCP DataSource or Exposed's Database.connect(url, driver, user, password).
Pricing
Exposed is Apache 2.0 licensed, maintained by JetBrains. Free for all use.
Agent Metadata
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.
Scores are editorial opinions as of 2026-03-06.