Skip to main content
Version: 1.13.0

Storm

Storm is an ORM for Kotlin 2.0+ and Java 21+, built on a SQL template engine. It aims for simplicity, type safety, and predictable performance, through immutable models and metadata generated at compile time.

Key benefits:

  • Minimal code: Define entities with simple records/data classes and query with concise, readable syntax, no boilerplate.
  • Parameterized by default: String interpolations are automatically converted to bind variables, making queries SQL injection safe by design.
  • Close to SQL: Storm stays close to SQL rather than abstracting it away, so you keep control of what runs against your database.
  • Type-safe: Storm's DSL mirrors SQL, so a wrong column or a wrong type is a compile error rather than a runtime one.
  • Direct Database Interaction: Method calls translate directly into database operations. Entity graphs load in a single query, which removes the N+1 problem.
  • Stateless: Record-based entities carry no session state, so there is no lazy initialization to fail later and nothing to attach, detach, or merge.
  • Performance: Template caching, transaction-scoped entity caching, and zero-overhead dirty checking (thanks to immutability). Batch processing, lazy streams, and upserts are built in.
  • Universal Database Compatibility: Works with all SQL databases.

Why Storm?

Storm draws inspiration from established ORMs such as Hibernate, but is built from scratch around a clear design philosophy: capture intent using the minimum amount of code, optimized for Kotlin and modern Java.

Storm's mission: Make database development productive and enjoyable, with full developer control and high performance.

Storm embraces SQL rather than abstracting it away. Database interactions stay simple without becoming opaque.

Traditional ORM PainStorm Solution
N+1 queries from lazy loadingEntity graphs load in a single query
Hidden magic (proxies, implicit flush, cascades)Stateless records; explicit, predictable behavior
Entity state confusion (managed/detached/transient)Immutable records; no state to manage
Entities tied to session/contextStateless records easily cached and shared across layers
Dirty checking via bytecode manipulationDirty checking that costs almost nothing, thanks to immutability
Complex mapping configurationConvention over configuration
Runtime query errorsCompile-time type-safe DSL
SQL hidden behind abstraction layersSQL-first design; stay close to the database

Storm is ideal for developers who want a database-first approach, where records mirror the schema. Custom mappings are supported when you need them, but the model works best when the two line up.

Choose Your Language

Both Kotlin and Java support SQL Templates for query composition. Kotlin additionally provides a type-safe DSL with infix operators.

// Define an entity
data class User(
@PK val id: Int = 0,
val email: String,
val name: String,
@FK val city: City
) : Entity<Int>

// Type-safe predicates — query nested properties like city.name in one go
val users = orm.findAll(User_.city.name eq "Sunnyvale")

// Custom repository — inherits all CRUD operations, add your own queries
interface UserRepository : EntityRepository<User, Int> {
fun findByCityName(name: String) = findAll(User_.city.name eq name)
}

// Block DSL — build queries with where, orderBy, joins, pagination
val users = userRepository.select {
where(User_.city.name eq "Sunnyvale")
orderBy(User_.name)
}.resultList

// SQL Template for full control; parameterized by default, SQL injection safe
val users = orm.query { """
SELECT ${User::class}
FROM ${User::class}
WHERE ${User_.city.name} = $cityName"""
}.resultList<User>()

Full coroutine support with Flow for streaming and programmatic transactions:

// Streaming with Flow
val users: Flow<User> = orm.entity<User>().select().resultFlow
users.collect { user -> println(user.name) }

// Programmatic transactions
transaction {
val city = orm insert City(name = "Sunnyvale", population = 161_884)
val user = orm insert User(email = "bob@example.com", name = "Bob", city = city)
}

AI Assisted Development

Storm is the ORM that AI coding assistants get right. Its stateless, immutable entities mean what you see in the source code is exactly what exists at runtime: no hidden proxies, no lazy loading surprises, no persistence context rules that trip up AI-generated code. When you ask your AI tool to write a query, define an entity, or build a repository, the output is straightforward data classes and explicit SQL, the same code a senior developer would write by hand.

Get started in seconds:

npx @storm-orm/cli

This configures your AI tool (Claude Code, Cursor, Copilot, Windsurf, or Codex) with Storm's patterns, conventions, and slash commands. See more on ai for details.

Quick Start

The Storm Gradle plugin sets up a Kotlin project in one line: it imports the BOM, adds the core dependencies, and wires the metamodel processor and Kotlin compiler plugin. Maven users import the BOM once and omit version numbers from individual Storm dependencies.

plugins {
kotlin("jvm") version "2.4.0"
id("com.google.devtools.ksp") version "2.3.10"
id("st.orm") version "1.13.1"
}

Ready to get started? Head to the Getting Started guide.

Learning Paths

Not sure where to begin? Pick the path that fits your situation.

New to Storm

If you are new to Storm, follow these guides in order to build a solid foundation:

  1. Installation -- add Storm to your project
  2. First Entity -- define entities, insert and fetch records
  3. First Query -- filtering, repositories, and streaming
  4. Entities -- annotations, nullability, naming conventions
  5. Queries -- the full query DSL and builder reference
  6. Repositories -- the repository pattern and custom query methods
  7. Relationships -- foreign keys, entity graphs, and many-to-many

Migrating from JPA

If you are coming from JPA or Hibernate, these pages explain the key differences and how to transition:

  1. Migration from JPA -- annotation mapping, concept translation, coexistence strategy
  2. Storm vs Other Frameworks -- feature comparison with JPA, jOOQ, MyBatis, and others
  3. Entities -- how Storm entities differ from JPA entities
  4. Repositories -- Storm repositories vs. Spring Data repositories
  5. Transactions -- transaction management without an EntityManager
  6. Spring Integration -- Spring Boot Starter and auto-configuration

Evaluating for Production

If you are a tech lead or architect evaluating Storm for a production system, these pages cover the areas that matter most:

  1. Storm vs Other Frameworks -- feature-level comparison across frameworks
  2. Spring Integration -- Spring Boot auto-configuration, repository scanning, DI
  3. Ktor Integration -- Ktor plugin, HOCON configuration, coroutine-native transactions
  4. Batch Processing and Streaming -- bulk operations and large dataset handling
  5. Testing -- JUnit 5 integration, statement capture, and test isolation
  6. Configuration -- runtime tuning, dirty checking modes, cache retention
  7. Database Dialects -- database-specific optimizations

What Storm Does Not Do

Storm is focused on being a great ORM and SQL template engine. It intentionally does not include:

  • Schema migration or DDL generation. Storm does not automatically create, alter, or drop tables at runtime. With Storm's AI integration, your coding assistant can read your database schema and generate Flyway or Liquibase migration scripts on demand. For schema versioning, use Flyway or Liquibase.
  • Second-level cache. Storm's entity cache is transaction-scoped and cleared on commit. For cross-transaction caching, use Spring's @Cacheable or a dedicated cache layer like Caffeine or Redis.
  • Lazy loading proxies. Entities are plain records with no proxies. Related entities are loaded eagerly in a single query via JOINs. For deferred loading, use Refs to explicitly control when related data is fetched.

Database Support

Storm works with any JDBC-compatible database. Dialect packages provide optimized support for:

Oracle SQL Server PostgreSQL MySQL MariaDB SQLite H2

See Database Dialects for installation and configuration details.

Requirements

  • Kotlin 2.0+ or Java 21+
  • Maven 3.9+ or Gradle 8+

Glossary

New to Storm's terminology? See the Glossary for definitions of key terms like Entity, Projection, Metamodel, Ref, Hydration, and more.

License

Storm is released under the Apache 2.0 License.