> Markdown version of [Native Image Compilation](https://vaadin.com/docs/next/flow/production/native). Section index: [llms.txt](https://vaadin.com/docs/next/flow/llms.txt)

# Native Image Compilation with GraalVM

For Spring Boot-based applications, Vaadin supports native image compilation with GraalVM. By compiling your application into a native image, you can benefit from much faster startup times (milliseconds) and lower memory consumption compared to running the application on the JVM.

## <a id="requirements"></a>Requirements

Before you begin, ensure you have a JDK with GraalVM support.

To check whether you have a JDK with GraalVM support, execute the `java -version` command in your terminal.

```bash
java -version
```

If the output contains the following text, you have a JDK with GraalVM support installed:

```
GraalVM
```

If not, you can install one by following the instructions in the [Install GraalVM](https://www.graalvm.org/latest/docs/getting-started/#install-graalvm) section of the GraalVM documentation or by using the [SDKMAN](https://sdkman.io/) tool.

## <a id="using-reflection-in-an-application"></a>Using Reflection in an Application

It’s a two-step process to compile a Java application to a native binary. First, there’s an ahead-of-time (AOT) stage in which the Java application is run to determine what resources it will use. The next step is the actual compilation based on what was determined in the first step. In some cases, the compiler is not able to determine in the AOT stage all of the needed classes and resources. In which case, you’ll need to provide hints of what’s needed.

For instance, `Grid` uses reflection to determine which fields a class has to create columns. This won’t work in a native image, unless you include an annotation to tell the compiler you need reflection information for the classes it uses. You can provide those details, those hints by adding a \[@RegisterReflectionForBinding]\(<https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/aot/hint/annotation/RegisterReflectionForBinding.html>) annotation.

```java
@Route("")
@RegisterReflectionForBinding({Person.class})
public class PersonView extends VerticalLayout {

    public PersonView() {
        var grid = new Grid<>(Person.class);
        grid.setItems(List.of(
            new Person("John Doe", "john@doe.com"),
            new Person("Jane Doe", "jane@doe.com")
        ));

        add(grid);
    }
}
```

With the annotation, it works as expected. Without it, you would get an empty grid in a natively compiled application. You can have the annotation either on a class or on a method, but not on the constructor.

The same attention should be kept when using POJOs with `Element` [Properties & Attributes](https://vaadin.com/docs/next/flow/component-internals/element-api/properties-attributes.md) or [JavaScript invocation](https://vaadin.com/docs/next/flow/component-internals/element-api/calling-javascript.md); every used custom class must be registered for reflection. An exception are classes used in [Remote Procedure Calls](https://vaadin.com/docs/next/flow/component-internals/client-server-rpc.md) API, that are automatically detected and registered for reflection by Vaadin, but only when used with Spring Boot or Quarkus.

For **Quarkus** applications, classes can be registered for reflection by using the `@RegisterForReflection` annotation, either on the class itself or on a separated class using the `targets` attribute. For more information see the [Quarkus documentation](https://quarkus.io/guides/writing-native-applications-tips#registerForReflection)

```java
@RegisterForReflection
public class Person {
}

// Useful when the class is in a third-party jar
@RegisterForReflection(targets={Person.class})
public class MyReflectionConfiguration {
}
```

Another use case that requires manual registration of reflection hints is the usage of `rerouteToError()` method in `BeforeEvent`. The framework automatically registers hints for exceptions handled by `HasErrorParameter<T extends Exception>` implementors, but it does not detect direct usage with `rerouteToError()`. Exception used with that method must be manually registered as explained above.

## <a id="compilation"></a>Compilation

Compile your Vaadin application into a native image using Maven by executing the following command in the project root directory:

```bash
mvn -Pnative native:compile
```

This command compiles the application with the native profile enabled. The native profile instructs Maven to use the GraalVM native image compiler for the compilation process.

Now run the application. The compilation creates the native image in the target directory. To run it, execute the following command:

```bash
./target/<app-name>
```

Your Vaadin application is now running as a native image, benefiting from faster startup times and lower memory consumption.

## <a id="more-resources"></a>More Resources

For more information on native image compilation and instructions on creating Docker images using build packs, see the [Spring Boot Reference Guide](https://docs.spring.io/spring-boot/docs/current/reference/html/native-image.html).
