Skip to content

« all projects

anchor · design system

2018-2022 · proprietary · enterprise design system · vue 2

Anchor was the design system that came before Meridian. Three internal packages: a main component package, a shared core runtime, and a second-generation UI library. Roughly 86 Vue 2 components compiled to native custom elements via vue-custom-element, lazy-mounted by a document-wide MutationObserver, and styled with a Sass-driven token system. The codebase where the framework-agnostic ideas were incubated under real enterprise constraints.

Architectural overview of the component library »


what it was

Three packages, scoped together under a private internal npm registry, consumed by every front-end app inside the enterprise:

main components
Roughly 86 Vue components covering forms, charts, modals, navigation, video, and content layouts. Storybook docs. The compilation entrypoints that emit a single browser bundle of custom elements.
core runtime
Shared runtime: Sass tokens and breakpoints, an event bus, Vue filters, mixins, plugins, and the custom directives the components built on top of (intersection, viewport bounds, drawer behavior, anchor offsets, target binding).
second-generation ui
A second library with broader coverage and a “hero sandbox” playground for end-to-end scenarios that standard Storybook stories couldn’t cover.

the singleton runtime

Every component shared a single runtime, owned by a singleton class installed as a Vue plugin. The pattern: a small set of utility plugins (viewport, key-code aliases, focus management), a shared event bus, a registered set of Vue filters, and a quiet version banner at boot. Same architectural posture I would later port forward to Meridian, different framework era.


lazy hydration via MutationObserver

86 components is too many to ship upfront. The classic answer was code-splitting; the harder problem was deciding which bundles to load on which page when adopters didn’t know what their CMS templates were going to include.

The solution: one MutationObserver watching the whole document. When any custom element with the system’s tag prefix appears in the DOM, the matching component chunk is dynamic-imported and registered on the fly. Pages that include the navbar but not the chart pay for only the navbar. Pages that conditionally render the chart pay for it only if the chart is actually rendered. Decoupled from the host framework’s scheduler.


the directives

Some of the most-reused primitives in Anchor weren’t components, they were custom Vue directives. Two notable examples:

v-intersect wraps a single shared IntersectionObserver with a WeakMap for per-element callbacks. Lazy-load images, animation triggers, infinite-scroll feeds, all built on this one primitive.

v-bounds toggles class names based on which viewport edges the element is currently touching. Used by sticky-state components, sidebar positioning, in-page navigation indicators. Cheaper and more declarative than per-component scroll listeners.


enterprise constraints that shaped the design


what carried forward

The most direct lineage from Anchor to Meridian:


stack

Frontend
Vue 2.7, custom elements via vue-custom-element
Build
Vue CLI, Webpack, Babel, PostCSS, Sass
Distribution
Private internal npm registry, three published packages
Documentation
Storybook + custom hero-sandbox playground
Testing
Jest unit tests + TestCafe visual-regression baseline
Monorepo
Yarn workspaces across the internal scope

More: component-library overview »
Related: Meridian (the successor) · Skeletor (the agency-era precursor) · Building the design system