A simple web framework
for Java and Kotlin
- Java
- Kotlin
import io.javalin.Javalin;
public class HelloWorld {
public static void main(String[] args) {
var app = Javalin.create(/*config*/)
.get("/", ctx -> ctx.result("Hello World"))
.start(7070);
}
}
import io.javalin.Javalin
fun main() {
val app = Javalin.create(/*config*/)
.get("/") { ctx -> ctx.result("Hello World") }
.start(7070)
}
Why Javalin?
Simple
Unlike other Java and Kotlin web frameworks, Javalin has very few concepts that you need to learn. You never extend classes and you rarely implement interfaces.
Lightweight
Javalin is just a few thousand lines of code on top of Jetty, and its performance is equivalent to raw Jetty code. Due to its size, it's very easy to reason about the source code.
Interoperable
Other Java and Kotlin web frameworks usually offer one version for each language. Javalin is being made with inter-operability in mind, apps are built the same way in both Java and Kotlin.
Flexible
Javalin is designed to be simple and blocking, as this is the easiest programming model to reason about.
But, if you set a Future
as a result, Javalin switches into asynchronous mode.
Educational
Visit our educators page if you're teaching web programming and looking for a web framework which will get out of your way and let you focus on the core concepts of your curriculum.
OpenAPI
Many lightweight Java and Kotlin web frameworks don't support OpenAPI, but Javalin does (including Swagger UI and ReDoc). Learn more at the OpenAPI plugin page.
Jetty
Javalin runs on top of Jetty, one of the most used and stable web-servers on the JVM. You can configure the Jetty server fully, including SSL and HTTP3 and everything else that Jetty offers.
Declare your server and API
in the same file
- Java
- Kotlin
import io.javalin.Javalin;
import static io.javalin.apibuilder.ApiBuilder.*;
public static void main(String[] args) {
var app = Javalin.create(config -> {
config.useVirtualThreads = true;
config.http.asyncTimeout = 10_000L;
config.staticFiles.add("/public");
config.staticFiles.enableWebjars();
config.router.apiBuilder(() -> {
path("/users", () -> {
get(UserController::getAll);
post(UserController::create);
path("/{userId}", () -> {
get(UserController::getOne);
patch(UserController::update);
delete(UserController::delete);
});
ws("/events", userController::webSocketEvents);
});
});
}).start(7070);
}
import io.javalin.Javalin
import io.javalin.apibuilder.ApiBuilder.*
fun main() {
val app = Javalin.create { config ->
config.useVirtualThreads = true
config.http.asyncTimeout = 10_000L
config.staticFiles.add("/public")
config.staticFiles.enableWebjars()
config.router.apiBuilder {
path("/users") {
get(UserController::getAll)
post(UserController::create)
path("/{userId}") {
get(UserController::getOne)
patch(UserController::update)
delete(UserController::delete)
}
ws("/events", userController::webSocketEvents)
}
}
}.start(7070)
}
Creating a REST API has never been easier
An active community
Javalin 1.0 was released in 2017, and has been in steady development since.
As of August 2023, the project consists of around 8000 lines of code and 11 000 lines of tests.
It has almost two hundred contributors, more than five hundred forks, and close to seven thousand stars on GitHub.
The project has around 400 000 downloads per month, and has been released 132 times in five years
(about two times per month).