Fork me on GitHub

Javalin 2 to 3 migration guide


One of the biggest new things in Javalin 3 is the configuration setup. Server config has been moved away from Javalin and into a JavalinConfig class, which is available inside Javalin.create():

Javalin.create(config -> {
    config.autogenerateEtags = true/false
    config.dynamicGzip = true/false
    config.enforceSsl = true/false
    config.requestCacheSize = sizeInBytes
    config.sessionHandler { ... }
    config.server { ... }
    config.accessManager { ... }

A full list of the config options can be found in the docs.


WebSockets used to have 5 separate interfaces with different signatures. To make the WebSocket API more like the HTTP API, we’ve introduced WsContext in Javalin 3. Each WebSocket event now takes a WsContext (ctx), which also has access to the underlying Context which was used to upgrade from HTTP to WebSocket. We’ve also added wsBefore, wsAfter, and wsException, and made the AccessManager aware of WebSocket upgrade requests.

You can read more about the new WebSocket API in the docs.


Events have been changed from Enum to Config object:

Javalin app = Javalin.create()
    .event(JavalinEvent.SERVER_STARTING, () -> { ... })
    .event(JavalinEvent.SERVER_STARTED, () -> { ... })
    .event(JavalinEvent.SERVER_START_FAILED, () -> { ... })
Javalin app = Javalin.create().events(event -> {
    event.serverStarting(() -> { ... });
    event.serverStarted(() -> { ... });
    event.serverStartFailed(() -> { ... });

Package structure

Javalin 3 has some changes to the package structure. The only class that’s still on root (io.javalin) is Javalin. Most of what used to be on the root has been moved into io.javalin.http (this includes pacakges such as staticfiles and serversentevents) Everything related to WebSockets has been moved into io.javalin.websocket. The package has been moved into Plugins have been moved into io.javalin.plugin.

Like Javalin?
Star us 😊