Axiom 3 takes your bytes from the socket to the database and back as
immutable data. No JDBC, no connection pool, no ORM, no reflection, and no third-party JARs.
It's plain Java 26 calling libpq, OCI and
ODBC directly through Project Panama.
Zero reflectionOnly java.* importsImmutable by defaultOn Maven Central
PQexecParamsbound out-of-band · OID typed
Result.successno exception escaped
AccountQuery.javacompiles on Java 26
Native drivers · no JDBC
PostgreSQL libpq
MySQL libmysqlclient
Oracle OCI
SQLite sqlite3
SQL Server ODBC
0
production modules, released in lock-step
0
databases reached natively via Panama
0
third-party runtime dependencies
0
uses of java.lang.reflect
0
Java baseline, with modern preview APIs
~0k
lines of auditable Java across the stack
What's new in 3.0
The biggest release yet. The smallest dependency tree ever.
Axiom 3.0 replaces the JDBC and Vert.x engines with five native drivers, moves parsing off-heap onto
MemorySegment, and splits the forensic flight recorder out into its own module.
Native drivers through Project Panama
Every driver binds the vendor's own C client with the Foreign Function & Memory API. Connections are created per
wield(..) inside a confined Arena, and they're closed and freed before the call returns.
Nothing is pooled, and nothing leaks between calls.
your code→JDBC→pool→Panama downcall→libpq · OCI · ODBC→database
postgresqlmysqloraclesqlitesqlserver
axiom-telemetry
A rolling black-box recorder. When an operation fails, the failure arrives with a snapshot of everything that succeeded just before it.
new modulelock-free
Off-heap parsing
JsonParser, CsvRowParser, AxiomDopParser and SchemaGuard all read a MemorySegment directly. They can read files memory-mapped from disk, without first copying them into a byte[].
Contract-verified bulk ingest
Before a single CSV row is sent, Hammer checks your declared headers and types against the live catalog and reports every mismatch at once.
Scoped native memory
BoundScope binds a confined arena to each call through ScopedValue. It has no thread-locals and no finalizers, and it runs safely on virtual threads.
Typed binds, native syntax
You write :java.name once. Each driver rewrites it to the engine's own placeholder ($1, :1 or ?) and binds it out-of-band with an explicit type.
dynamicQuery("… WHERE status = :java.status LIMIT :java.limit")
.to("ACTIVE").bind(PostgresType.TEXT)
.to(10).bind(PostgresType.INT8)
Ten modules, one version
The stack has five core modules and five drivers, all at 3.0.0 and all signed and published together. Each is a plain JAR with its own JPMS automatic module name, and you import only what you use.
Each module depends only on the layers below it, and the whole graph sits on axiom, which itself depends on nothing but the JDK.
Select a module to see its dependency chain, packages and coordinates.
Layer 4Native drivers
Layer 3Validation
Layer 2Contracts & grammar
Layer 1Foundation
Layer 0Platform
JDK 26java.base · java.lang.foreign
Anatomy of a request
From socket to SQL and back, in six honest steps.
This is a real handler from the 3.0 reference strike. Scroll through it: every step is a function call you can read, and there's no framework hiding the rest.
01
Bytes arrive
The request body becomes a MemorySegment. Parsers read it in place, without building intermediate Strings.
java.lang.foreign
02
Parse and guard the perimeter
JsonParser builds a frozen PersistentMap, and SchemaGuard validates it against a cached .axiom schema. The first violation comes back as a Result, with its exact path.
axiom-spec · axiom-language
03
Extract typed values at the edge
The data stays untyped inside. Types are asserted only where you need them, with targetKey(..).toStringVal().
axiom
04
Wield a native connection
wield binds a confined arena, opens one libpq connection, runs your lambda and always disconnects, whether it succeeds or fails.
axiom-warp-postgresql-driver
05
Bind out-of-band with explicit types
Each :java.name becomes $n and goes through PQexecParams with an explicit OID. Values never touch the SQL text.
PostgresType
06
Emit immutable rows
Rows come back as a PersistentList<PersistentMap>. map shapes the response, and JsonEmitter writes it out. Failures stay values the whole way.
Every artifact lives under com.ensemblu at version 3.0.0, ships with sources and Javadoc, and is GPG-signed on Maven Central.
Native drivers
One shape. Five engines.
Every driver exposes the same Executioner: wield, transaction, shot, dynamicQuery and fromFile.
Under the hood, each one does what's idiomatic for its engine. Pick an engine to see exactly how.
PostgreSQL
com.ensemblu:axiom-warp-postgresql-driver:3.0.0
Engine
Native client
Placeholder → bind
Bulk ingest
Transactions
Provisioning chain
Type catalog
PostgreSQL
libpq
$n · PQexecParams + OID
COPY … FROM STDIN stream
BEGIN / COMMIT / ROLLBACK
host → port → dbName → user → password?
PostgresType
MySQL
libmysqlclient
? · escaped literal splice
batched multi-row INSERT
BEGIN / COMMIT / ROLLBACK
host → port → dbName → user → password?
MySqlType
Oracle
OCI (Instant Client)
:n · OCIBindByPos
prepared INSERT, bind-once buffers
OCITransCommit / Rollback
host → port → serviceName → user → password?
OracleType
SQLite
sqlite3
positional · sqlite3_bind_*
prepare once, step / reset per row
BEGIN / COMMIT / ROLLBACK
path
SqliteType
SQL Server
ODBC + MS ODBC 18
? · SQLBindParameter
prepared INSERT, bind-once buffers
BEGIN TRANSACTION / COMMIT
host → port → dbName → user → password?
SqlServerType
Code lab
The API, one recipe at a time.
Every snippet below is written against the 3.0.0 sources: real class names, real method chains, nothing invented for the brochure.
Why Axiom exists
Seven failure modes, removed at the root.
Each of these is a problem that enterprise Java stacks accept as normal. Open one to see what goes wrong, what Axiom 3 does instead, and which module does it.
Your dependency tree
Count what you ship.
Here's the same feature (a validated JSON endpoint that queries PostgreSQL) on a typical stack and on Axiom 3. The 2.x strike itself shipped HikariCP, slf4j and the PostgreSQL JDBC driver. The 3.0 strike ships none of them.
axiom-warp-jdbc (JDBC + your pool) and axiom-warp-reactive (Vert.x 5)
Five native drivers over Panama, with no JDBC and no pool
Engines
PostgreSQL-centric, with dialect translation on the reactive path
PostgreSQL, MySQL, Oracle, SQLite and SQL Server, each idiomatic
Parser input
byte[]
MemorySegment (heap, native or memory-mapped)
Parameter typing
AxiomProtocol contract map + ::cast
One explicit engine type per bind: .to(v).bind(PostgresType.X)
Parallel reads
warp.parallel(tasks)
One wield per virtual thread, with independent connections
Bulk ingest
warp.ingest().fromFile(..)
fromFile(..).withDataTypes(..), verified against the catalog first
Failure forensics
withHistory(..) inside the reactive engine
Standalone axiom-telemetry that works with any Result
axiom-spec scope
Parsers + DB contracts, binders, registries
Parsers and the emitter only. DB contracts moved into each driver
Published modules
6
10
Upgrade guide
2.x → 3.0, side by side.
3.0 is a SemVer-major release. Here are the eight changes you'll actually touch, each shown before and after. The full breaking-change inventory is in the 3.0 changelog.
The curried chain makes a missing step a compile error, and a bad value fails at boot.
var pg = PostgreSQL
.connect(file("database.properties"))
.requiredHost().requiredPort()
.requiredDbName().requiredUser()
.optionalPassword()
.getPostgreSqlDriverOrThrow();
Wield a query
You get a Result of immutable rows. Nothing throws unless you ask it to.
var rows = pg.wield(conn ->
pg.dynamicQuery(
"SELECT * FROM accounts WHERE status = :java.s")
.to("ACTIVE").bind(PostgresType.TEXT)
.execute(conn));
Runtime flags. Axiom 3 compiles against Java 26 preview APIs, so run with --enable-preview. Add --enable-native-access=ALL-UNNAMED to silence restricted-method warnings for the Panama downcalls.
The vendor client (libpq, libmysqlclient, Oracle Instant Client, sqlite3 or an ODBC driver) has to be findable by your OS loader. On Windows, that means it's on PATH.
Long-form articles on design decisions, migration paths and the opinions behind them.
Licensing
Evaluate freely. Ship with a contract.
Axiom is published under the Limited Commercial License. You can pull, read, test and build with it at no cost.
Running it in production, or for any commercial purpose, requires a paid annual agreement.
JDBC is an abstraction over vendor wire protocols, and it brings type inference, driver-specific quirks and, in practice, a pool and its tuning along with it. Since Project Panama is final, Java can call the vendor's own C client directly. So that's what Axiom 3 does: one explicit downcall per operation, with typed parameters and nothing in between.
No connection pool? Isn't that slow?
Each wield(..) opens a dedicated native connection and closes it when the call returns. That makes resource ownership trivial, with no leaked connections and no shared state, and it fits virtual threads. Put batches, transactions and related reads inside a single wield so they share one session. For very high request rates, measure against your own latency budget; it's an explicit trade-off, and it's documented as one.
Which Java version do I need?
Java 26. Axiom uses java.lang.foreign, ScopedValue and other modern APIs, and it's compiled with --enable-preview, so your application must run with --enable-preview too.
Do I need the native client libraries installed?
Yes. That's the point: Axiom ships no wire-protocol reimplementation. Install libpq (PostgreSQL), libmysqlclient (MySQL), Oracle Instant Client, sqlite3, or the Microsoft ODBC Driver 18 for SQL Server, and make sure the OS loader can find it.
Can I still use Axiom without a database?
Absolutely. axiom on its own gives you persistent collections, Result, guards, navigation, config and effects. Add axiom-spec for JSON/CSV, axiom-language for schema validation, and axiom-telemetry for failure forensics. None of these touch a database.
What happened to axiom-warp-jdbc and axiom-warp-reactive?
They're retired in 3.0. The native drivers replace the JDBC engine, plain virtual threads replace the Vert.x engine's concurrency, and the reactive engine's forensic history now lives in axiom-telemetry. The 2.x artifacts stay on Maven Central. See the migration guide above.
Is it safe against SQL injection?
PostgreSQL, Oracle, SQLite and SQL Server send values out-of-band as typed parameters, so values never become SQL text. The MySQL C API has no out-of-band text-protocol parameters, so its driver escapes each value through mysql_real_escape_string before quoting it with bindQuotedValue. Use bindValue only for trusted numeric literals.
Can I use it commercially?
Evaluation, testing, education and non-commercial development are free. Production or other commercial use requires a paid annual Commercial Enterprise License Agreement. Email contact@ensemblu.com.
Sovereign by default
Stop renting your architecture from frameworks.
Pull Axiom 3 from Maven Central today, read every line it runs, and decide for yourself.