How to Build Your First Micronaut Application
Easy Guide for Beginners to Launch a Micronaut Project

Pre-requisites :
Before starting, make sure you have the following :
Java JDK 17 or later
Gradle 7.6 or later
Kotlin 1.9 or later
Micronaut 4.x
IntelliJ IDEA (recommended IDE)
macOS, Windows, or Linux
If you already have these installed, you can skip the next section. If not, we’ll set them up together.
Install These Tools :
Homebrew (macOS only)
Homebrew is a package manager for macOS that makes installing software a breeze and keeps it up-to-date.To install Homebrew, open the Terminal, then run the installation command found on the official Homebrew website.
- After the installation is complete, you can verify it by typing
brew --versionin the Terminal. If Homebrew is installed correctly, this command will display the installed version of Homebrew.
- After the installation is complete, you can verify it by typing
Java (JDK 17+)
Java is the core language runtime. For Micronaut, we need Java Development Kit (JDK), which includes the compiler (
javac) and runtime environment.Check if Java is installed:
java --versionIf not installed, follow your OS-specific instructions:
macOS:
brew install openjdk@17Linux (Ubuntu/Debian):
sudo apt update sudo apt install openjdk-17-jdkWindows:
Download and install from Oracle JDK, then verify withjava --version.
Gradle
Gradle is a build tool that automates compiling your code, downloading dependencies, and packaging your app.
Check if Gradle is installed:
gradle --versionInstall if needed:
macOS:
brew install gradleLinux:
sudo apt install gradleWindows:
Download from Gradle releases and follow setup instructions.
3. Micronaut CLI (optional but convenient)
The Micronaut CLI lets you quickly generate new projects and manage them from the terminal. It’s optional because you can always use Micronaut Launch instead. Follow the official Micronaut CLI installation guide. And check using mn —version
Java vs JavaScript — Quick Parallels
As someone who has mostly worked with JavaScript libraries and frameworks, I found it easier to grasp Java and Micronaut concepts by relating them to what I already knew. If you’re coming from a similar background, this analogy might help you too.
| JavaScript World | Java / Micronaut World | What it does |
| TypeScript → compiles to JS | Kotlin → compiles to JVM bytecode | Both need compilation before running |
| Node.js | Java Runtime (OpenJDK) | Runs the compiled code |
| Express.js | Micronaut | Backend framework (routing, DI, config) |
| npm / yarn | Gradle | Manages dependencies & versions |
| Vite / Webpack | Gradle (again) | Builds & packages your app |
| Final Output: JS bundle | Final Output: JAR file | The deployable app |
Create a Micronaut Application :
You can create an app in two ways:
1. Using Micronaut CLI
mn create-app --build=gradle_kotlin --jdk=17 --lang=kotlin --test=junit com.testing
Similar to npx create-react-app or npx create vite@latest myapp.
2. Using Micronaut Launch - Easier to customize
Visit Micronaut Launch and select:
Application Type → Micronaut Application
Micronaut Version → 4.9.3
Java Version → 17
Language → Kotlin
Name → testing
Build Tool → Gradle Kotlin
Base Package →
com.testing(you can have your custom package name)Test Framework → JUnit
Click Generate Project : You will be prompted with two options
Download
.zipfileCommands → Copy and paste any one of the commands in the terminal. Using the Micronaut CLI or Using cURL.
Run the Project :
Unzip the archive.
Go into the project:
cd testingLaunch the app:
./gradlew run
You Might See a 404 Error. Why?
The default
Application.ktonly starts the Micronaut framework.It does not define routes (like
/or/hello).So if you visit http://localhost:8080, Micronaut looks for a controller but finds none →
404.Application.ktis just for starting the app.You must define controllers separately.
By default Netty server runs on port
8080. You may override it to force the server to run on a specific port by setting the following property in yourapplication.yml. You can also set the value of this property to-1to run the server on a randomly generated port.
micronaut:
server:
port: 8081
Create Your First Controller
Create a file HelloController.kt under /src/main/kotlin/com/testing :
package com.testing
import io.micronaut.http.MediaType
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.Produces
@Controller("/")
class HelloController {
@Get("/")
@Produces(MediaType.TEXT_PLAIN)
fun hello(): String {
return "Hello World from Micronaut!"
}
}
Explanation
@Controller("/")→ Base URL (default =http://localhost:8080/)@Get("/hello")→ Route endpoint. Visitinghttp://localhost:8080/hellorunsfun hello(): String→ Return type@Produces(MediaType.TEXT_PLAIN)→ Sets Content-Type totext/plain(instead of JSON).
How Things Are Nested
HelloController→ class, marked with@Controller("/").- Means: this class contains endpoints starting with
/.
- Means: this class contains endpoints starting with
Inside the class → define functions.
- Each function maps to a route (
@Get,@Post, etc).
- Each function maps to a route (
fun hello()→ function handling GET request.
Final Step
In project directory, run:
Start app:
./gradlew runBuild app:
./gradlew buildNow open http://localhost:8080 and you’ll see:

Experiments to Try
1. Change the Response Type
Remove:
import io.micronaut.http.annotation.Produces @Produces(MediaType.TEXT_PLAIN)Run the app again. You’ll see Micronaut defaults to
application/json.Since you’re returning a
String, it makes more sense to explicitly specifytext/plain.
2. Play with Routes
Try different combinations of @Controller and @Get to see how routes resolve:
@Controller("/") + @Get("/")
@Controller("/hello") + @Get("/")
@Controller("/hello") + @Get("/hello")
@Controller("/") + @Get("/hello")
This will give you an intuitive sense of how Micronaut combines controller-level and method-level routes.
Kudos! 🙌🏼
We’ve built our first Micronaut app successfully and explored routes, controllers, and HTTP methods. Keep experimenting and you’ll quickly get comfortable.
See you in my next learning adventure! 🚀

