GDS

Interactive maps over transport network data—layers, road-linked features, and tooling operators expect from a real map product. The frontend is split into publishable packages: Map Core (shared engine) and Map Kit (GDS-specific wiring on top).

Role
Frontend Architect
Stack
React, TypeScript, Tailwind, MapLibre GL, GraphQL, MobX
Timeline
2025–Present
Domain
Geospatial Data Platform

Intro

GDS was a geospatial frontend platform initiative focused on reusable mapping capabilities for transport applications across Queensland Government systems.

I led the frontend architecture and implementation of Map Core and Map Kit, defining reusable map interactions, shared contracts, operational tooling, and mapping foundations using React, TypeScript, MapLibre, and GraphQL/AppSync.

The Problem

Different transport products needed mapping features at the same time—exploring lanes, links, assets, and contextual metadata on a map. Without a shared foundation, implementations risked becoming fragmented across teams, workflows, datasets, and UI patterns.

Each team could wire its own MapLibre setup and layer model, but that approach does not age well as backends and contracts drift. The work was to ship a solid GDS experience while giving other teams a reusable path forward.

Platform Direction

I structured the frontend around three layers with clear responsibilities:

  • Map Core — reusable map foundation: rendering, view state, and shared interaction behaviour without GDS-specific business logic
  • Map Kit — GDS-specific integration layer: GraphQL clients, auth, transport-network workflows, and product-facing defaults built on Map Core
  • Product applications — consumers of the shared capability; the GDS web app imports Map Kit, while other teams can take Map Core alone when they only need the engine

That split kept the engine portable. Reuse stays importable—not copy-paste with extra steps.

Map Core

I designed Map Core as a reusable frontend mapping runtime focused on shared map interactions, rendering behaviour, geometry handling, and extension patterns.

Map Core established the foundational map contract used by consuming applications, allowing teams to configure and extend map behaviour through structured datasets, layers, entities, feature states, and interaction models rather than tightly coupled implementations.

  • Map contracts and extension patterns
  • Layers, markers, and geometry rendering
  • Feature states, interaction models, and selection flows
  • Navigation and clustering

Designed to minimise coupling to specific basemap providers and mapping services. Product workflows and GDS operational concerns stay outside this layer.

Map Kit

I built Map Kit as a GDS-focused integration layer on top of Map Core—an installable package that packaged GDS operational integrations and transport-specific behaviours for consuming products.

While Map Core provided the reusable mapping runtime, Map Kit brought together GDS operational behaviours, GraphQL integrations, transport datasets, road-network-focused map configuration, and basemap conventions into a single integration surface.

  • Consumed GDS GraphQL operations using consumer-provided tokens
  • Integrated transport datasets and road-network-focused interactions
  • Applied basemap conventions and configuration tailored for GDS workflows
  • Kept GDS-specific operational concerns out of Map Core

Consumer applications could integrate directly with Map Core for custom implementations, or use Map Kit for tighter integration with GDS operational datasets and workflows.

Data Contracts & APIs

I defined shared frontend contracts for map entities and datasets so interaction code is not coupled to raw server payloads. Map Core and Map Kit both speak the same interface; only Map Kit knows how GDS fetches and normalises data underneath.

  • Stable shapes for road assets, network links, and other transport geometries with GeoJSON geometry support
  • Lightweight metadata for map rendering and selection; optional richer detail payloads when a feature is inspected
  • Entity relationships where the UI needs them—without forcing every consumer to understand the full backend schema

Engineering Foundations

Reusable map platforms fail quietly when adoption depends on reading the entire codebase. I established foundations aimed at future teams:

  • Storybook documentation with working examples and component APIs for Map Core and Map Kit
  • Playwright E2E strategy for stateful map flows that survive refactors
  • Reusable UI patterns for layers, selection, and inspection built on shared contracts
  • Integration guidance and operational documentation so consuming teams can install, import, and follow established patterns

Architecture Decisions

  • MapLibre GL as the agreed map runtime—standardising on one renderer rather than maintaining parallel integration paths
  • Provider flexibility: Map Core stays independent of commercial SDK wrappers; basemap direction included MapTiler exploration without baking vendor-specific code into product features
  • Separate Map Core and Map Kit packages so GDS GraphQL, auth, and workflows do not leak into the engine
  • Performance and interaction scalability—careful about what renders, what simplifies, and what defers as transport datasets grow
  • Balancing abstraction with practical delivery: explicit contracts over clever indirection, with room to extend without forking the engine

Frontend architecture

The diagram is the mental model we kept returning to: apps sit on Map Kit, Map Kit sits on Map Core, shared contracts and design-system pieces wrap the edges. MobX and Playwright sit alongside—not because they are exciting, but because stateful map apps need predictable stores and regression tests that survive refactors.

GDS frontend architecture stack: applications including GDS Web App and consumer apps on Map Kit, Map Core map engine, unified data and APIs, and supporting frontend systems (design system, Storybook, MobX, Playwright).
How the GDS web app and other consumers sit on Map Kit and Map Core, with shared contracts and supporting frontend tooling around them.

Operational Considerations

Platform code only works when ownership boundaries stay explicit. Map Core owns rendering and interaction; Map Kit owns GDS integration; product applications own screen-level workflows.

  • Consuming teams integrate through published packages and documented patterns—not by extending internals or duplicating half the engine in app code
  • Long-term maintainability means resisting over-abstraction: the platform stays useful without becoming so generic it stops solving real mapping problems
  • Auth and tokens cross package boundaries deliberately—Map Kit talks to upstream services; Map Core does not quietly bake in GDS credentials
  • Guardrails and defaults, not a monolithic map component: enough consistency across experiences without freezing every product into the same UX

Lessons & Reflections

  • Platform work needs clear boundaries. The hardest design problem was threading shared interaction and rendering without trapping every future product requirement inside the engine package.
  • Reusable systems must stay practical. Abstractions should be earned—explicit contracts mattered more than clever indirection when backends iterate.
  • Operational documentation is part of the product. Map-heavy UIs are easy to get subtly wrong; working examples beat archaeology.
  • Mapping platforms need both technical flexibility and product empathy—enough structure to keep experiences consistent, enough extension points that new datasets and consumers do not require a rewrite.

Technology

Frontend

React, TypeScript, Vite

Mapping

MapLibre, MapTiler

State & Data

MobX, GraphQL/AppSync

UI

Tailwind, shadcn/Radix

Testing

Vitest, Testing Library, Playwright, Storybook

Tooling

pnpm workspace