Vue Tactical Demo
Interactive Map + CoT Playground
A weekend portfolio piece built around an interactive map: click symbols in the palette and drop them on the map, paste Cursor-on-Target (CoT) XML to render a labeled marker at the parsed coordinates, and toggle between APP-6D and MIL-STD-2525C symbology standards with live re-rendering of palette and placed markers. The README covers architecture decisions, the boundary-translation pattern, and explicit scope boundaries.
Development duration
Weekend project, 2026
Role
Sole Developer
Tools
Vue 3.5, TypeScript, MapLibre GL, SCSS, Vitest, Vite
Type
Portfolio piece
2
npm packages
~20
Unit tests
Vue 3.5
TypeScript strict
MapLibre
WebGL, no API key

Why I built this:
I had never built anything with maps, and I was curious how map-based interfaces actually work under the hood. Rather than learn that in the abstract, I picked a domain that would force me to learn it properly, one I had no prior background in, which was exactly the point. I wanted to walk into an unfamiliar, demanding domain, learn its real vocabulary rather than fake it, and ship something that stands on its own. That curiosity turned into a weekend map app, and the map app turned into a published library.
The demo: learning the domain by building in it:
A dark MapLibre map with a scoped-down operator workstation feel, built to learn map rendering and the underlying standards at the same time. Every acronym was new to me. I had to decode a real symbology grammar (SIDC codes), a real coordinate system (MGRS), and a real interchange format (CoT XML). This is the kind of domain knowledge you cannot bluff. Technically it is Vue 3.5 (composition API, module-level composables for state, useTemplateRef, onWatcherCleanup), strict TypeScript with discriminated-union parse results, and ~20 focused unit tests. Deliberately tight scope, honest decisions about what to build versus leave out.
Symbology Palette
Interactive palette of NATO/US military symbols. Click to select, drop on the map to place a marker.
CoT XML Parsing
Paste Cursor-on-Target XML, parse the payload, and render a labeled marker at the resolved coordinates.
Live MGRS Readout
Cursor coordinates rendered live in MGRS (Military Grid Reference System) alongside the standard lat/long readout.
APP-6D / MIL-STD-2525C Toggle
Switch between symbology standards on the fly. Palette and placed markers re-render live without reload.
The companion library: vue-cot:
Building the demo, I kept hand-rolling CoT XML parsing. That was when I realised CoT (Cursor on Target) is a serious thing, the lingua franca of the ATAK / WinTAK / TAK Server ecosystem, and there was no proper Vue 3 library for it. So I went deep and built one: parser, serialiser, typed models, WebSocket lifecycle, a Pinia entity store, three custom Pinia plugins. Shipped as a real package: dual ESM + CJS output with types (tsup), strict TypeScript, tests, and published to npm as vue-cot@0.1.1.
vue-cot →Closing the loop:
Once vue-cot was on npm, I refactored this demo to consume it, replacing its inline DOMParser parsing with a call to my published library. This is the real test of a library: does it work in an actual application, not just its own demo? Dogfooding it that way immediately paid off. Using the library in a real app surfaced a genuine gap: parseCoT did not validate a missing uid or type. It silently produced the string "undefined" instead of failing. So I patched the library (parseCoT now throws on missing uid/type, shipped as vue-cot@0.1.1) and simplified the app against the patch, deleting a defensive workaround that was no longer needed. That full cycle: real app finds a gap → library patch → app simplifies against it. It's the thing I'd want to talk about in an interview.
What this demonstrates
- ▸Shipping real software: a package on npm (installable, versioned, typed) and a deployed app that depends on it, not tutorials or sandboxes.
- ▸Learning a hard, unfamiliar domain fast: APP-6D / MIL-STD-2525C symbology, MGRS, and the CoT ecosystem, learned from zero and used correctly.
- ▸Depth on the things that matter for real-time frontends: WebSocket lifecycle, reactive performance at scale (shallowRef + triggerRef, rAF batching), and Pinia beyond the basics (composition, plugins, module augmentation).
- ▸Engineering maturity: strict TypeScript, unit tests, dual-format library publishing, semantic versioning, and library maintenance driven by a real consumer.