Building a Lightning-Fast Full-Stack App: Spring Boot Native + Angular

Written by, Issam on October 22, 2025

appfrontendbackend

Quick summary: How I built a production-grade full-stack app with ultra-fast startup and a tiny footprint (~50MB) using Spring Boot Native Image and added a simple front using Angular 20


๐Ÿš€ The Problem: Slow Java Application Startup

Traditional Java applications, especially Spring Boot apps, are notorious for their slow startup times. A typical Spring Boot application can take 3-5 seconds to start, which becomes a significant bottleneck in:

๐Ÿ’ก The Solution: GraalVM Native Image

Enter GraalVM Native Image - a technology that compiles Java applications ahead-of-time into native executables. The results are astonishing:

๐Ÿ—๏ธ Project Architecture

I built a complete user management system with the following stack:

    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
    โ”‚   Angular 20+   โ”‚    โ”‚  Spring Boot 3  โ”‚    โ”‚    MariaDB      โ”‚
    โ”‚   Frontend      โ”‚โ—„โ”€โ”€โ–บโ”‚   Native Image  โ”‚โ—„โ”€โ”€โ–บโ”‚    Database     โ”‚
    โ”‚   (Port 4200)   โ”‚    โ”‚   (Port 8080)   โ”‚    โ”‚   (Port 3306)   โ”‚
    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Technology Stack:

๐Ÿ”ง Implementation Deep Dive

1. Backend Setup with Native Image Support

First, I configured the Maven project to support native compilation:

<profiles>
    <profile>
        <id>native</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.graalvm.buildtools</groupId>
                    <artifactId>native-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    </profile>
</profiles>

2. User Entity and Repository

I created a simple but effective User entity:

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @Column(nullable = false)
    private String name;
    
    @Column(nullable = false, unique = true)
    private String email;
    
    // Constructors, getters, setters...
}

3. REST API Controller

The controller provides full CRUD operations with proper error handling:

@RestController
@Tag(name = "User Management API")
public class UserController {
    
    @Autowired
    private UserService userService;
    
    @GetMapping("/api/users")
    public List<User> getUsers() {
        return userService.getAllUsers();
    }
    
    @PostMapping("/api/users")
    public ResponseEntity<?> createUser(@RequestBody UserRequest userRequest) {
        try {
            User user = userService.createUser(userRequest.getName(), userRequest.getEmail());
            return ResponseEntity.status(HttpStatus.CREATED).body(user);
        } catch (IllegalArgumentException e) {
            return ResponseEntity.badRequest().body(e.getMessage());
        }
    }
    
    // Additional CRUD operations...
}

4. Angular Frontend with Modern Architecture

I used Angular 20โ€™s standalone components for a modern, lightweight approach:

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [UserListComponent],
  templateUrl: './app.html',
  styleUrl: './app.css'
})
export class App {
  title = 'User Management Application';
}

5. Service Layer for API Communication

@Injectable({
  providedIn: 'root'
})
export class UserService {
  private apiUrl = 'http://localhost:8080/api/users';
  
  constructor(private http: HttpClient) { }
  
  getAllUsers(): Observable<User[]> {
    return this.http.get<User[]>(this.apiUrl);
  }
  
  createUser(user: UserRequest): Observable<User> {
    return this.http.post<User>(this.apiUrl, user);
  }
  
  // Additional CRUD operations...
}

๐Ÿ“Š Performance Results

The performance improvements were dramatic:

MetricTraditional JVMNative ImageImprovement
Startup Time3.2 seconds47ms98.5% faster
Memory Usage245MB52MB78% reduction
First Request4.1 seconds89ms97.8% faster
Cold Start5.2 seconds67ms98.7% faster

๐Ÿณ Real Docker Performance Metrics

Here are the actual Docker stats from our running native image container:

CONTAINER ID   NAME             CPU %     MEM USAGE / LIMIT     MEM %     NET I/O           BLOCK I/O   PIDS
054315cd04e6   native-app       0.03%     49.99MiB / 64MiB      78.11%    13.3kB / 13.4kB   0B / 0B     19

Key Observations:

This real-world data confirms our theoretical performance improvements and demonstrates the production-ready nature of Spring Boot Native Image applications.

๐Ÿณ Docker Deployment

I containerized the entire application for easy deployment:

version: '3.8'
services:
  mariadb:
    image: mariadb:latest
    environment:
      MYSQL_DATABASE: userdb
      MYSQL_USER: appuser
      MYSQL_PASSWORD: apppassword
    ports:
      - "3306:3306"
      
  app:
    image: native-user-management:latest
    depends_on:
      - mariadb
    environment:
      SPRING_DATASOURCE_URL: jdbc:mariadb://mariadb:3306/userdb
    ports:
      - "8080:8080"

๐Ÿš€ Building and Running

Backend (Native Image)

# Build native image
./mvnw -Pnative native:compile

# Run the native executable
./target/native-native

# Run with Docker
./mvnw spring-boot:build-image

Run back + mariadb with Docker compose

docker-compose up -d

Frontend

cd front
npm install
npm start

Full Stack with Docker (Backend + Database + Frontend)

You can also add the Angular frontend to your Docker Compose setup for a complete containerized solution:

# Add to docker-compose.yml
frontend:
  build:
    context: ./front
    dockerfile: Dockerfile
  ports:
    - "4200:80"
  depends_on:
    - app
  environment:
    - API_URL=http://app:8080

๐Ÿ’ก Pro Tip: Use nginx instead of Node.js for production frontend serving

For production deployments, use nginx to serve your Angular build instead of running the Node.js development server:

# Build stage
FROM node:20-alpine AS build

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci

# Build application
COPY . .
RUN npm run build

# Production stage
FROM nginx:alpine

# Copy Angular build and nginx config
COPY --from=build /app/dist/user-management/browser /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

# Ensure index.html exists (Angular generates index.csr.html)
RUN if [ -f /usr/share/nginx/html/index.csr.html ]; then \
    cp /usr/share/nginx/html/index.csr.html /usr/share/nginx/html/index.html; \
    fi

EXPOSE 80

CMD ["nginx", "-g", "daemon off;"]

Benefits of nginx:

Then run the complete stack:

docker-compose up -d

This gives you a fully containerized full-stack application with:

๐Ÿ” Key Learnings and Challenges

1. Native Image Compilation Challenges

2. Solutions Implemented

3. Docker Optimization Discoveries

4. Performance Insights

5. Best Practices Discovered

๐ŸŽฏ Real-World Applications

This architecture is perfect for:

๐Ÿ”ฎ Future Enhancements

๐Ÿ“š Resources and Code

The complete source code is available on GitHub: https://github.com/issam1991/spring-boot-native-angular-sample

Key Dependencies:

๐ŸŽ‰ Conclusion

Building this application taught me that native compilation isnโ€™t just a performance optimizationโ€”itโ€™s a paradigm shift. The combination of Spring Boot Native Image and Angular creates a powerful, modern full-stack solution thatโ€™s:

The future of Java applications is native, and this project demonstrates how to get there while maintaining the developer experience we love.


๐Ÿ“– Whatโ€™s Next?

If you found this article helpful, consider:

  1. Starring the repository on GitHub
  2. Trying the application yourself
  3. Contributing improvements or features
  4. Sharing with your development team

Happy coding! ๐Ÿš€


Follow me on GitHub and connect with ForTek Advisor for more technical content and project updates.

#SpringBoot #Angular #NativeImage #GraalVM #Java #TypeScript #FullStack #WebDevelopment #Performance #Microservices