Enkan is a middleware-chain-based web framework for Java 25. Its core idea is
explicitness over convention: every component, every middleware, and every
dependency is declared in plain Java code — no classpath scanning, no
auto-configuration, no magic.
The fastest path from zero to a running application is the /init command,
which turns a plain-English description of your app into a compilable project
skeleton in minutes.
/init)/init (recommended)/init is the entry point to the Enkan ecosystem. It is an AI-powered project
generator built into the standalone REPL client. You describe your application
in natural language, review a generated plan, and init writes a compilable
project skeleton — complete with routing, controllers, domain records, database
migrations, and a development REPL server — then compiles it and optionally
starts it for you.
No Enkan knowledge is required to run /init. It is intentionally designed as
the first thing a new user does.
You describe your app
↓
/init collects requirements interactively
↓
LLM generates a plan (you can revise it)
↓
Project files are written
↓
mvn compile runs (with auto-fix loop)
↓
App starts + REPL connects
↓
You are live inside a running Enkan application
Grab the standalone client jar from the
latest release:
curl -L -o enkan-repl-client.jar \
https://github.com/enkan/enkan/releases/latest/download/enkan-repl-client.jar
/init uses an OpenAI-compatible chat completion API. It works with OpenAI,
Anthropic’s OpenAI-compatible endpoint,
LM Studio, Ollama, vLLM, and any other server that speaks the same protocol.
| Env var | System property | Default |
|---|---|---|
ENKAN_AI_API_URL | enkan.ai.apiUrl | https://api.anthropic.com/v1 |
ENKAN_AI_API_KEY | enkan.ai.apiKey | (required) |
ENKAN_AI_MODEL | enkan.ai.model | claude-sonnet-4-5 |
The URL may be either a base (/v1) or the full path (/v1/chat/completions) —
both are accepted.
export ENKAN_AI_API_KEY=sk-...
/initjava -jar enkan-repl-client.jar
Enkan Project Generator
── Project Setup ─────────────────────────
? What kind of application do you want to build? REST API for a bookstore
? Project name [rest-api-bookstore]:
? Group ID [com.example]:
? Output directory [./rest-api-bookstore]:
── Plan Draft ────────────────────────────
(the LLM shows a proposed plan — components, routes, file list)
Plan feedback (say 'yes' to proceed, or describe changes, 'cancel' to abort) > yes
── Generating ────────────────────────────
✓ src/main/java/.../BookstoreApplicationFactory.java
✓ src/main/java/.../BookController.java
...
✓ Done! Created 5 file(s)
── Compiling ─────────────────────────────
✓ Compilation succeeded.
? Start and connect to the generated app? [Y]:
⚡ Starting app (mvn compile exec:exec -Pdev)...
Connected to server (port = 3001)
enkan(3001)❯
At the enkan(3001)❯ prompt you are connected to a running REPL server inside
your new project. From here you can run /routes,
/start, /stop, /reset, or evaluate live Java expressions.
/init generates/init writes the following files verbatim (without touching the LLM), so the
scaffold is always consistent:
pom.xml — including the dev profile that runs DevMainsrc/dev/java/.../DevMain.java — starts the REPL serversrc/main/java/.../<Project>SystemFactory.java — minimal EnkanSystem.of(...) skeletonThe LLM then fills in the ApplicationFactory, controllers, and domain classes
based on your approved plan. The default generated stack is:
| Layer | Technology |
|---|---|
| HTTP server | Jetty (virtual threads) |
| MVC | Kotowari |
| JSON | Jackson |
| Connection pool | HikariCP |
| SQL | jOOQ |
| Row mapping | Raoh |
| Migrations | Flyway |
| Database | H2 (in-memory, dev) |
If you prefer to wire everything by hand, add kotowari (MVC framework) and a
server component to your pom.xml:
<dependency>
<groupId>net.unit8.enkan</groupId>
<artifactId>kotowari</artifactId>
<version>0.15.0</version>
</dependency>
<dependency>
<groupId>net.unit8.enkan</groupId>
<artifactId>enkan-component-jetty</artifactId>
<version>0.15.0</version>
</dependency>
If you only need the middleware core without MVC routing, use enkan-web instead of kotowari.
An application factory builds the middleware stack and routing table:
import enkan.Application;
import enkan.application.WebApplication;
import enkan.config.ApplicationFactory;
import enkan.middleware.*;
import enkan.system.EnkanSystem;
import kotowari.middleware.*;
import kotowari.routing.Routes;
public class MyAppFactory implements ApplicationFactory {
@Override
public Application create(EnkanSystem system) {
WebApplication app = new WebApplication();
Routes routes = Routes.define(r -> {
r.get("/").to(HomeController.class, "index");
}).compile();
app.use(new DefaultCharsetMiddleware());
app.use(new ContentTypeMiddleware());
app.use(new ParamsMiddleware());
app.use(new RoutingMiddleware(routes));
app.use(new ControllerInvokerMiddleware(system));
return app;
}
}
Controllers are plain Java classes — no annotations, no base class:
import enkan.data.HttpResponse;
public class HomeController {
public HttpResponse index() {
return HttpResponse.of("Hello, World!");
}
}
import enkan.system.EnkanSystem;
import enkan.component.ApplicationComponent;
import enkan.component.jetty.JettyComponent;
import static enkan.system.EnkanSystem.component;
public class MySystemFactory {
public EnkanSystem create() {
return EnkanSystem.of(
"app", new ApplicationComponent(MyAppFactory.class.getName()),
"http", new JettyComponent()
).relationships(
component("http").using("app")
);
}
}
% mvn -e compile exec:java
Start the system with the /start command:
enkan> /start
Access http://localhost:3000/ in your browser.