Skip to content
Dzunnurain A. Azhar← All work
02Banking · L&D

Learning Management System

An enterprise learning platform for employee training and certification — and a deliberate second attempt at the micro-frontend problem, with the previous platform's lessons applied.

Client
Enterprise internal
Year
2024—2026
Role
Frontend Engineer
Team
Single platform team
Vue 3TypeScriptViteModule FederationKeycloakSentry

Context

Two audiences share one product. Administrators build curricula, approve enrolments and issue certificates. Learners consume material and track progress. The two groups have almost nothing in common in their day-to-day use.

Having already split a platform eight ways, the question here was not whether to use micro-frontends but how few boundaries the product could get away with.

Constraints

Two distinct audiences
Admin and learner journeys diverge almost completely — a natural seam that follows users rather than departments.
Type safety across boundaries
TypeScript strict mode was non-negotiable, including across federated module boundaries.
Production observability
Support needed to reproduce what a specific user saw, and errors needed to surface without waiting for a ticket.
Design consistency
One visual system across every module, owned in one place.

Architecture

Four Vue 3 + TypeScript applications wired with Vite Module Federation: a shell host, an admin portal, a learning portal, and a shared design system consumed as a remote.

Shell / host + 4 remotes

  • Admin Portal18 modules — governance side
  • Learning Portal5 modules — learner side
  • Auth & IdentityKeycloak OIDC, impersonation
  • Design System53 components, consumed by both portals

Key decisions

Decision

Module Federation instead of Single-SPA

Why

Vite-native, and types can be shared across the boundary — which Single-SPA's runtime import maps never gave us.

Trade-off

The apps are now coupled through their build tooling. Every deployable has to move to a compatible Vite version more or less together.

Decision

Four boundaries instead of eight

Why

The previous platform proved that seams drawn along the org chart create coordination overhead without delivering autonomy. Splitting by user role gave real independence.

Trade-off

Individual apps are larger, and builds take longer than the smaller micro-apps did.

Decision

Design system as a federated remote

Why

53 components stay in one place and fixes propagate immediately rather than through a release train.

Trade-off

A bad publish is instantly everyone's problem. This trades slow-and-safe for fast-and-blast-radius, and it needs real release discipline to be the right call.

Decision

Strict mode and the full lint chain from the first commit

Why

TypeScript strict, ESLint, Prettier and Husky pre-commit hooks are cheap at the start of a codebase and extremely expensive to retrofit.

Trade-off

Slower initial velocity, and some genuine friction while the team calibrated to it.

Decision

Keycloak impersonation plus Sentry

Why

Support can see exactly what a user sees, and errors arrive before the ticket does.

Trade-off

Impersonation is a powerful capability sitting inside a banking product. It needs to be audited as carefully as it is useful.

Outcome

4
Federated applications
23
Feature modules
53
Design system components
100%
TypeScript strict coverage

The measurable win over the previous platform was not raw performance — it was that fewer boundaries meant less cross-team coordination for the same amount of delivered product.

What I’d revisit

Impersonation shipped before its audit trail was as strong as it should have been. In a banking context, the ability to act as another user needs logging that is at least as rigorous as the feature itself.

A design system consumed as a live remote by four applications should have had visual regression tests from the start. Without them, the blast radius is real but invisible until something breaks.

Diagrams are drawn from scratch and module names describe the domain. No client assets, interfaces or internal naming appear here.