Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Project and first server

Javalin has no project generator: it is a single library, and the project is an ordinary Maven project with a few dependencies. We create it by hand: folders, a pom.xml file and a Main class. It takes a couple of minutes, and the project contains nothing extra.

Project folders

Create a blog folder with this structure:

blog/
├── pom.xml
└── src/
    └── main/
        └── java/com/example/blog/
            └── Main.java

Later we add src/main/resources for files and src/test/java for tests.

pom.xml

The pom.xml file lives in the root of the blog folder:

<!-- pom.xml -->
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
 
    <groupId>com.example</groupId>
    <artifactId>blog</artifactId>
    <version>1.0.0</version>
 
    <properties>
        <maven.compiler.release>25</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <javalin.version>7.2.3</javalin.version>
    </properties>
 
    <dependencies>
        <dependency>
            <groupId>io.javalin</groupId>
            <artifactId>javalin</artifactId>
            <version>${javalin.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.18</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>2.22.1</version>
        </dependency>
    </dependencies>
 
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.14.1</version>
            </plugin>
            <plugin>
                <groupId>org.codehaus.mojo</groupId>
                <artifactId>exec-maven-plugin</artifactId>
                <version>3.6.4</version>
                <configuration>
                    <mainClass>com.example.blog.Main</mainClass>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
DependencyWhy
javalinThe framework itself and the embedded Jetty
slf4j-simplePrints logs to the console
jackson-databindTurns objects into JSON and back

The exec-maven-plugin plugin runs the Main class with a Maven command.

The first server

Create the Main.java file:

// src/main/java/com/example/blog/Main.java
package com.example.blog;
 
import io.javalin.Javalin;
 
public class Main {
    public static void main(String[] args) {
        Javalin app = Javalin.create(config -> {
            config.routes.get("/", ctx -> ctx.result("Hello, Javalin!"));
        });
        app.start(8080);
    }
}

Javalin.create takes a lambda with the configuration. Inside it, config.routes.get declares a route: answer GET / with a string. The start(8080) method starts the server on port 8080.

Running

In the blog folder run:

mvn compile exec:java

Maven downloads the dependencies, compiles the code and starts the server. The end of the log (shortened):

[com.example.blog.Main.main()] INFO io.javalin.Javalin - Starting Javalin ...
[com.example.blog.Main.main()] INFO org.eclipse.jetty.server.Server - jetty-12.1.12; ...
[com.example.blog.Main.main()] INFO io.javalin.Javalin - Javalin started in 573ms \o/
[com.example.blog.Main.main()] INFO io.javalin.Javalin - Listening on http://localhost:8080/
[com.example.blog.Main.main()] INFO io.javalin.Javalin - You are running Javalin 7.2.3 (released August 11, 2026).

Open http://localhost:8080 in a browser or call the server from a second terminal:

curl http://localhost:8080
Hello, Javalin!

The server runs until you press Ctrl+C. After every code change, stop it and run the command again.

Common mistake

If you forget the slf4j-simple dependency, the server starts but prints no logs, and at the beginning of the output Javalin prints a hint:

#########################################################################
Javalin: It looks like you don't have a logger in your project.
The easiest way to fix this is to add 'slf4j-simple':
...
#########################################################################
SLF4J(W): No SLF4J providers were found.
SLF4J(W): Defaulting to no-operation (NOP) logger implementation

Without logs you see neither the server address nor errors in handlers. Add the dependency from the table above.

Thanks for reading!

Donate to the site — we work hard for you.