A micro frontends sample implementation of The Tractor Store built with Spring Boot + JTE, ESI, HTMX and Tailwind.
It's a reference implementation to Alexander Heerens' article Radically Simple Web Architecture and based on the Blueprint.
Live Demo: https://tractorstore.inauditech.com/
The architecture of the application is based on the Radically Simple Web Architecture article.
There are two teams that both run a Modular Monolith (Spring Boot app) containing multiple Self Contained Systems (Module). Each SCS represents an independent business domain (DDD).
Routing, Page Assembly (Server-Side Integration) and Pattern Library hosting is part of a NGINX.
Authentication is done by the 'account' domain and a JWT cookie is set on successful login. Other domains and teams can use this JWT for identification and security.
List of techniques used in this implementation.
Aspect | Solution |
---|---|
🛠️ Frameworks, Libraries | spring-boot, htmx, tailwind |
📝 Rendering | SSR templating with jte |
🐚 Application Shell | None |
🧩 Client-Side Integration | HTMX patical updates |
🧩 Server-Side Integration | ESI + Routing via nginx |
📣 Communication | Custom Events + HTMX Attributes (htmx) |
🗺️ Navigation | MPA, HTMX patical updates, Hard-Nav Between |
🔒 Authentication | user/password + JWT |
🎨 Styling | tailwind + Custom CSS |
🍱 Design System | Demo Pattern Lib pattern-lib |
🔮 Discovery | None (Hardcoded URLs for Now) |
🚚 Deployment | AWS App Runner (Docker image) |
👩💻 Local Development | docker-compose, gradle |
The original Tractor Store has three teams (Explore, Decide, Checkout) and their team boundaries can be visualized in the shop via a toggle at the bottom.
Our implementation is focused around four business domain run by two teams. This gives you an overview how the boundaries are defined:
Original Team | Domain | Team |
---|---|---|
🔴 Explore | navigation | Discover |
🟢 Decide | product | Discover |
🟣 Inspire | discovery | Discover |
🟡 Checkout | checkout | Checkout |
🔵 n.a | account | Checkout |
And this is how one domain is including another.
- 🔴
navigation
- 📄 Home
- 📄 Stores
- 🧩 Header (🔴🟢🟡🟣🔵 every page, except checkout)
- 🧩 Footer (🔴🟢🟡🟣🔵 every page)
- 🧩 Store Picker (🟡 checkout)
- 🟣
discovery
- 📄 Category
- 🧩 Recommendations (🔴 home, 🟢 product detail, 🟡 cart)
- 🧩 Store Picker (🟡 checkout)
- 🟢
product
- 📄 Product detail
- 🧩 Ratings (🟣 recommendations)
- 🟡
checkout
- 📄 Cart
- 📄 Checkout
- 📄 Thank you
- 🧩 Mini Cart (🔴 header)
- 🧩 Add To Cart Button (🟢 product details)
- 🔵
account
- 📄 Login
- 📄 Account Overview
- 🧩 Login Button (🔴 header)
This implementation is deliberately kept simple to focus on the micro frontends aspects. URLs are hardcoded, components could be more DRY and no linting, testing or type-safety is implemented. In a real-world scenario, these aspects should be addressed properly.
For the use of Tailwind v3+ each domain must create its own css files during the build and SCSs must include each other's resources.
Product data is provided by the product
domain and pull via data feed (https://tractorstore.inauditech.com/product/api/v1/feed) by other domain such as checkout
.
The demo checkout
pulls all data on startup and holds data in memory. A robust production application would run a periodic job, pull only updates and persist data.
For demo purposes the Dockerfile
will create an image containing and running the two Spring apps and the NGINX. In a real-word scenario these three would have their own pipelines, docker images and deployments.
Because the Modular Monolith is one Spring Boot app, all modules share one class namespace. That means all classes, packages and JTE templates need to have a namespace to avoid conflicts.
By default, JTE does not support multiple template directories (modules), and hab to create an own JteModuleConfiguration
to make the possible.
Clone this repository and run the following commands:
git clone https://github.com/heerens/tractor-store-htmx-tailwind
cd tractor-store-htmx-tailwind
Build the app(s):
# build the app + nginx image
docker-compose build
Start the development server:
docker-compose up
Open http://localhost:3000 in your browser to see the integrated application.
Alex is a founder, architect and full stack developer at Inaudi Tech. He has worked the last 20+ years in web application development and helped small start-ups as well as big e-commerce companies to find the right tech stack for their missions.