Getting Started · Lesson 4 of 95
Creating a Project with Spring Initializr
Create your first Spring Boot project with Spring Initializr: what every form field means, adding Spring Web, running it, and generating it with curl.
When you move into a new flat, you do not build the furniture from raw wood. You pick a ready kit, check that the pieces match, and assemble it in an evening. Spring Initializr is that kit shop for Spring Boot. You tell it what you want, and it hands you a ready project with the right folders, a build file with matching versions, and a main class that already runs.
In this guide you will fill in the Initializr form, understand every field, open the project in your IDE, add your first endpoint and run it. You will also learn to create a project from the terminal with a single command.
What is Spring Initializr?
It is also built into IntelliJ IDEA, VS Code (through the Spring Boot extensions) and Eclipse's Spring Tools, so you can use the same form without leaving your editor. Behind all of them is the same service, so the projects are identical.
Why is it used?
You could create the folders and pom.xml by hand, but that is slow and easy to get wrong. Initializr gives you:
- A correct build file. The Spring Boot parent and starters with versions that work together.
- The standard folder layout. Every Spring Boot developer knows where to find things in it.
- A main class and a test. The app starts and the test passes before you write any code.
- The Maven Wrapper.
mvnwlets anyone build the project without installing Maven.
Most real teams start new services this way, so it is worth learning well.
How it works
Here is the path from an empty browser tab to a running app.
textOpen start.spring.io | v Fill the form + add deps | v Click GENERATE (ZIP file) | v Unzip and open in your IDE | v IDE downloads libraries | v Run the main class
The only slow step is the first download of libraries, which can take a minute or two. After that they are cached on your computer, so the next project opens much faster.
Real-Life Example
Ordering at a sandwich counter works the same way. You choose the bread (Maven or Gradle), the size (Java version), and the fillings (dependencies such as Spring Web). The counter assembles it with ingredients that go together. You do not bake the bread yourself, but you still decide exactly what goes in.
Filling the Form
Here are the main fields on the form and what to choose for this course. Leave Description as it is, and if you see a Configuration option, keep Properties.
| Field | What it means | Choose |
|---|---|---|
| Project | The build tool | Maven (the default is Gradle, so change it) |
| Language | Programming language | Java |
| Spring Boot | Framework version | Latest plain number, such as 4.1.1 |
| Group | Your organisation, reversed domain | com.citylibrary |
| Artifact | Project name, becomes the JAR name | catalog |
| Name | Display name, used for the main class | catalog |
| Package name | Where your code lives | com.citylibrary.catalog |
| Packaging | How the app is bundled | Jar |
| Java | Java version | 21 |
Next, click ADD DEPENDENCIES and search for Spring Web. It adds the spring-boot-starter-webmvc starter for REST APIs with an embedded Tomcat server. Then click GENERATE to download catalog.zip.
What Is Inside the ZIP
Unzip it and you will find these main files. The next topic explains each one in detail, so for now just get to know their names.
textcatalog/ ├─ pom.xml ├─ mvnw, mvnw.cmd, .mvn/ ├─ HELP.md ├─ src/main/java/.../catalog/ │ └─ CatalogApplication.java ├─ src/main/resources/ │ ├─ application.properties │ ├─ static/ │ └─ templates/ └─ src/test/java/.../catalog/ └─ CatalogApplicationTests.java
pom.xmlis the Maven build file with your chosen starters.mvnw,mvnw.cmdand the.mvnfolder are the Maven Wrapper.HELP.mdholds links to guides for the dependencies you picked.application.propertiesis where your settings go. It already setsspring.application.nametocatalog.staticandtemplatesare empty folders for web pages, which REST APIs often do not use.CatalogApplicationTestsstarts the whole app once. If it passes, your setup is healthy.
Try ./mvnw test straight after unzipping. You should see Tests run: 1, Failures: 0 and BUILD SUCCESS, which proves Java, Maven and the project all work together.
Code Example
After unzipping, Initializr has created this main class for you:
File: CatalogApplication.java in package com.citylibrary.catalog
javapackage com.citylibrary.catalog; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class CatalogApplication { public static void main(String[] args) { SpringApplication.run(CatalogApplication.class, args); } }
Let's add an endpoint that lists books. Create a new class in the same package:
File: BookController.java in package com.citylibrary.catalog
javapackage com.citylibrary.catalog; import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class BookController { record Book(String title, String author, boolean available) {} @GetMapping("/books") public List<Book> books() { return List.of( new Book("The Clockmaker's Daughter", "R. Mehta", true), new Book("Rivers of Code", "A. Fernandes", false)); } }
Run it from the project folder (on Windows use mvnw.cmd), then call the endpoint:
bash./mvnw spring-boot:run curl http://localhost:8080/books
Output:
json[ { "title": "The Clockmaker's Daughter", "author": "R. Mehta", "available": true }, { "title": "Rivers of Code", "author": "A. Fernandes", "available": false } ]
curl prints the JSON on one line; it is spaced out here so it is easy to read.
Code Explained
- Initializr named the main class from the Name field:
catalogbecameCatalogApplication. - The package
com.citylibrary.catalogis Group plus Artifact. Your new classes must live in this package or below it, so component scan finds them. BookControlleris a normal class you added. Spring found it at startup because of@SpringBootApplicationon the main class../mvnw spring-boot:runused the Maven Wrapper, so Maven did not need to be installed.
Creating a Project From the Terminal
Initializr also has an API. This one command creates the same project without opening a browser:
bashcurl https://start.spring.io/starter.zip \ -d type=maven-project \ -d javaVersion=21 \ -d groupId=com.citylibrary \ -d artifactId=catalog \ -d dependencies=web \ -o catalog.zip
Two things are worth knowing. If you leave out type=maven-project, you get a Gradle project, because Gradle is the default. And if you leave out the Spring Boot version, you get the current default version.
Common Mistakes
- Forgetting Spring Web. Without it there is no web server, so the app starts and then stops straight away. Add the dependency and generate again, or add the starter to
pom.xml. - Leaving Project on Gradle. The Maven steps in this course will not match. Switch Project to Maven before you generate.
- Moving the main class. If you move
CatalogApplicationinto a sub-package, classes above it are no longer scanned.
Interview Questions
What is Spring Initializr?
Ans:A web tool and API that generates a ready Spring Boot project, with the build file, folder layout, main class, a test and the build tool wrapper.
How are the main class and package names decided?
Ans:The package comes from Group plus Artifact, and the main class from the Name field with Application added.
Can you generate a project without a browser?
Ans:Yes. Call the /starter.zip address on start.spring.io with curl and pass options such as type, javaVersion, groupId, artifactId and dependencies.
Key Points to Remember
- Spring Initializr at start.spring.io generates a complete Spring Boot project as a ZIP.
- Choose Maven, Java, a plain Spring Boot version, Jar packaging and Java 21 for this course.
- Group plus Artifact makes the base package; keep your classes inside it.
- Add Spring Web to build REST APIs with an embedded Tomcat server.
- The same generator works from IntelliJ IDEA, VS Code, Eclipse or curl.
Frequently Asked Questions
Is Spring Initializr free?
Yes. start.spring.io is free and run by the Spring team. You do not need an account.
Should I choose Maven or Gradle?
Both are good. This course uses Maven because its XML build file is easy to read for beginners, and most tutorials and company projects you will meet use it.
Can I add more dependencies later?
Yes. Add the starter to pom.xml at any time. You can also open Initializr again, click EXPLORE to see the generated pom.xml, and copy just the lines you need.
Why does my project have a test class already?
Initializr adds a small test that starts the whole app. If it passes, your project is set up correctly.
Related Topics
- Spring Boot Project Structure: what every generated folder and file is for.
- Maven pom.xml Explained: the build file Initializr wrote for you.
- Spring Boot Starters: what Spring Web and other dependencies bring in.
- Running a Spring Boot Application: more ways to start your app.
Practice Problems
Try each problem on your own first. Generate the projects with Initializr (the website or curl), then add the code.
Easy: Sunrise Clinic Status Endpoint
Sunrise Clinic wants a service called appointments. Generate a Maven project with Group com.sunriseclinic, Artifact appointments, Java 21 and Spring Web. Then add GET /status that returns this plain text: Sunrise Clinic appointments service is running.
Show answerHide answer
@RestController next to the main class, and return a String from a @GetMapping("/status") method.bashcurl https://start.spring.io/starter.zip \ -d type=maven-project -d javaVersion=21 \ -d groupId=com.sunriseclinic -d artifactId=appointments \ -d dependencies=web -o appointments.zip
File: AppointmentsApplication.java in package com.sunriseclinic.appointments
javapackage com.sunriseclinic.appointments; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class AppointmentsApplication { public static void main(String[] args) { SpringApplication.run(AppointmentsApplication.class, args); } }
File: StatusController.java in package com.sunriseclinic.appointments
javapackage com.sunriseclinic.appointments; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class StatusController { @GetMapping("/status") public String status() { return "Sunrise Clinic appointments service is running"; } }
Run ./mvnw spring-boot:run; then curl http://localhost:8080/status prints the status line.
Medium: ShopKart Products and Orders
Generate a project with Group com.shopkart and Artifact store (Spring Web, Java 21). Keep each feature in its own sub-package:
com.shopkart.store.productshasGET /products, returning the product names Wireless Mouse, USB-C Cable and Laptop Stand as a JSON array.com.shopkart.store.ordershasGET /orders/count, returning the number3.
Show answerHide answer
File: StoreApplication.java in package com.shopkart.store
javapackage com.shopkart.store; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class StoreApplication { public static void main(String[] args) { SpringApplication.run(StoreApplication.class, args); } }
File: ProductController.java in package com.shopkart.store.products
javapackage com.shopkart.store.products; import java.util.List; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class ProductController { @GetMapping("/products") public List<String> products() { return List.of("Wireless Mouse", "USB-C Cable", "Laptop Stand"); } }
File: OrderController.java in package com.shopkart.store.orders
javapackage com.shopkart.store.orders; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class OrderController { @GetMapping("/orders/count") public int orderCount() { return 3; } }
Calling /products prints the three names as a JSON array, and /orders/count prints 3.