# How to mirror the HPE Design System A runbook for reproducing everything in this folder: the guidance docs, the 452-icon set, the brand marks, and all 282 documentation graphics. Written to be handed to someone else and followed start to finish, by a person or by an AI coding agent. Every command below was run and verified on 2026-07-30. Nothing here needs an HPE login, a VPN, or a token. Total time: about ten minutes, most of it the clone. --- ## The problem you will hit first `https://design-system.hpe.design` looks like a normal documentation site. It is not scrapeable. It is a **Next.js static export that renders entirely in the browser**. Fetch any page and you get a 1.5 KB HTML shell with zero content: ```bash curl -s https://design-system.hpe.design/foundation/color | wc -c # 1540 ``` There is also no sitemap and no robots.txt. Both 404: ```bash curl -s -o /dev/null -w '%{http_code}\n' https://design-system.hpe.design/sitemap.xml # 404 curl -s -o /dev/null -w '%{http_code}\n' https://design-system.hpe.design/robots.txt # 404 ``` The Next.js data endpoint does not help either. The pages are `autoExport` with empty `pageProps`, so `/_next/data//.json` returns 404. The content is compiled into JavaScript chunks. **Do not try to scrape the site.** Do not reach for a headless browser. There is a much better source. ## The key insight The whole design system is **open source**: > `https://github.com/grommet/hpe-design-system` — Apache-2.0 Every page on that site is an MDX file in that repo. The icons, the graphics, and the raw design token JSON are in there too. Clone it and you have everything, in a form that greps. Find it yourself with: ```bash curl -s "https://api.github.com/search/repositories?q=hpe-design-system" \ | grep -E '"full_name"|"html_url"' ``` ## Step 1 — Clone Shallow clone. Full history is not needed and is much larger. ```bash git clone --depth 1 https://github.com/grommet/hpe-design-system.git hpeds cd hpeds git log -1 --format='%H %cI %s' # record this SHA for provenance du -sh . # ~81 MB ``` Record the commit SHA. Version numbers in the docs move; citing a SHA makes your notes checkable later. The mirror in this folder was taken at `567c4d5` (2026-07-16). Do **not** run `pnpm install`. Nothing here needs a build. ## Step 2 — Know the layout ``` hpeds/ ├── apps/ │ ├── docs/ │ │ ├── src/pages/ <- ALL documentation content, as .mdx │ │ └── public/ <- ALL graphics (282 files, 32 MB) │ └── design-tokens-manager/ ├── packages/ │ ├── hpe-design-tokens/ │ │ └── tokens/ <- raw token JSON (primitive/semantic/component) │ ├── icons-svg/src/icons/ <- 452 raw SVG icons │ ├── icons-grommet/ <- the same icons as React components │ └── codemods/ ├── knowledge/ <- their own AI agent capability bundles └── LICENSE <- Apache-2.0 ``` Content page counts, so you know when you have it all: ```bash find apps/docs/src/pages -name '*.mdx' | wc -l # 112 for d in foundation design-tokens components templates learn; do printf '%-16s %s\n' "$d" "$(find apps/docs/src/pages/$d -name '*.mdx' | wc -l)" done # foundation 20 # design-tokens 11 # components 49 (48 component pages + an all-components index) # templates 27 # learn 4 ``` Those five directories account for 111. The 112th is `whats-new.mdx` at the page root. Widening the search to `apps/docs -type f \( -name '*.mdx' -o -name '*.md' \)` returns 117, because it picks up repo READMEs outside the page tree. Use the narrower count when checking coverage. ## Step 3 — Get the full route list Useful as a checklist to confirm you covered everything. The site is a Next.js export, so its build manifest lists every route. The build ID changes on every redeploy, so extract it rather than hardcoding it. Save as `routes.sh`: ```bash #!/usr/bin/env bash # Extract every route from the HPE Design System site (Next.js static export). set -euo pipefail UA="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0 Safari/537.36" BASE="https://design-system.hpe.design" BUILD_ID=$(curl -sS -A "$UA" "$BASE/" \ | grep -oE '/_next/static/[A-Za-z0-9_-]{16,}/_buildManifest\.js' | head -1) echo "buildManifest: $BUILD_ID" >&2 curl -sS -A "$UA" "$BASE$BUILD_ID" \ | tr ',' '\n' | grep -oE '"/[^"]*"' | tr -d '"' | sort -u ``` ```bash chmod +x routes.sh && ./routes.sh | wc -l # 123 ``` ## Step 4 — Read the content The MDX files are prose plus JSX examples. Read the prose; the `` and `` tags import React components from `apps/docs/src/examples/` and can be ignored unless you need a rendered figure. Priority order, highest value first: | File | Why | | --- | --- | | `foundation/voice-and-tone.mdx` | 55 KB, the largest doc on the site. UI copy rules | | `foundation/accessibility.mdx` | 18 KB. WCAG level, responsibility split table | | `foundation/date-and-time.mdx` | 15 KB | | `foundation/typography.mdx` | Font CDN URLs, heading rules | | `foundation/color.mdx` | The eight color families and their jobs | | `foundation/our-brand.mdx` | Logo and Element placement rules | | `foundation/distinctive-brand-assets.mdx` | GreenLake badge status | | `design-tokens/overview.mdx` | The three-tier token model | | `design-tokens/versioning.mdx` | Version-to-theme map, migration paths | | `foundation/philosophy-and-principles.mdx` | The three pillars, four principles | Sort the rest by size to prioritize: ```bash wc -c apps/docs/src/pages/foundation/*.mdx apps/docs/src/pages/design-tokens/*.mdx | sort -n ``` Raw single-file access without cloning, if you only want one page: ``` https://raw.githubusercontent.com/grommet/hpe-design-system/master/apps/docs/src/pages/foundation/color.mdx ``` ## Step 5 — Resolve design tokens to real values This is the part worth automating, and the part most likely to be got wrong. **Token JSON does not contain values.** It contains references. A semantic token points at a primitive, which may point at another primitive. Reading `color.light.json` directly gives you `{base.color.grey.50}`, not `#f7f7f7`. Two more traps: 1. Semantic tokens carry a `.REST` suffix on the leaf that references often omit, so a naive lookup misses. 2. There is a `deprecated.*` namespace holding superseded values. A stale reference resolves to a visibly different color: `deprecated.base.color.green.400` is `#17eba0` where the live `base.color.green.400` is `#00e0af`. Save as `resolve-tokens.py`: ```python #!/usr/bin/env python3 """Resolve HPE design tokens to concrete values. Usage: resolve-tokens.py [filter-substring] Tokens are stored as {references}; this follows them to real hex/number values. """ import json, sys, os root = sys.argv[1] needle = sys.argv[2] if len(sys.argv) > 2 else '' T = os.path.join(root, 'packages/hpe-design-tokens/tokens') def flat(o, p=''): out = {} if isinstance(o, dict): if '$value' in o: return {p: o['$value']} for k, v in o.items(): out.update(flat(v, f'{p}.{k}' if p else k)) return out prim = flat(json.load(open(f'{T}/primitive/primitives.default.json'))) light = flat(json.load(open(f'{T}/semantic/color.light.json'))) dark = flat(json.load(open(f'{T}/semantic/color.dark.json'))) def resolve(v, tbl, depth=0): while isinstance(v, str) and v.startswith('{') and depth < 10: k = v.strip('{}') v = prim.get(k, tbl.get(k + '.REST', tbl.get(k))) depth += 1 return v for k in sorted(light): if needle and needle not in k: continue print(f'{k:52} light={str(resolve(light[k], light)):12} dark={resolve(dark.get(k), dark)}') ``` Run it: ```bash python3 resolve-tokens.py hpeds 'text.' # color.text.default.REST light=#3e4550 dark=#e6e8e9 # color.text.heading...REST light=#292d3a dark=#ffffff # color.text.critical...REST light=#cc1f1a dark=#ff7b7b python3 resolve-tokens.py hpeds 'background.' python3 resolve-tokens.py hpeds '' # everything, 108 semantic color tokens ``` ### The units gotcha Dimension primitives are stored as **unitless numbers**. `base.dimension.400` is the number `16`, not `"16px"`. Units are applied at build time by `packages/hpe-design-tokens/src/transforms/numberToDimension.ts`, and not uniformly: - `fontSize` and `lineHeight` are divided by 16 and emitted as **`rem`** - everything else (spacing, radius, padding, width, height, border width, breakpoints) is emitted as **`px`** If you report a raw number as a pixel value for a font size, you will be wrong by a factor of 16. ## Step 6 — Pull the assets ### Icons (452 SVGs, 1.9 MB) ```bash mkdir -p out/icons cp hpeds/packages/icons-svg/src/icons/*.svg out/icons/ cp hpeds/packages/icons-svg/LICENSE hpeds/packages/icons-svg/COPYRIGHT.md out/icons/ ls out/icons/*.svg | wc -l # 452 ``` Properties, verified: ```bash grep -ho 'viewBox="[^"]*"' out/icons/*.svg | sort | uniq -c | sort -rn # 448 viewBox="0 0 24 24" # 2 viewBox="0 0 24 25" (catalog.svg, chat.svg) # 1 viewBox="0 0 48 24" (element.svg) # 1 viewBox="0 0 24 26" (chat-conversation.svg) grep -l 'currentColor' out/icons/*.svg | wc -l # 451 of 452 grep -ho 'fill="#[0-9A-Fa-f]*"' out/icons/*.svg | sort | uniq -c # 1 fill="#01A982" (element.svg only) ``` **The HPE Element is `icons/element.svg`, not a logo file.** It is the one icon with a hardcoded color, because the brand green must not inherit from its container. ### Brand marks ```bash mkdir -p out/brand cp hpeds/apps/docs/public/HPE_logo_full-clr_{pos,rev}_rgb.svg out/brand/ cp hpeds/apps/docs/public/static/images/{hpe-logo,hpe-logo-invert,aruba-logo}.svg out/brand/ ``` ### All documentation graphics (282 files, 32 MB) ```bash mkdir -p out/site-images cp -r hpeds/apps/docs/public/. out/site-images/ find out/site-images -type f | wc -l # 282 ``` Two things to know before you commit 32 MB: - **About 14 MB is Unsplash stock photography** in `learnImages/grid-fundamentals-part-1/`: four JPGs between 2.5 and 4.9 MB used as filler in a Grommet grid tutorial. No HPE guidance in them. Drop that one folder and you reclaim nearly half the total. - **`logos/` holds partner logos, not HPE marks** (Apache, Dataiku, Dremio, H2O, SingleStore, StreamSets and others). Third-party trademarks, not covered by this repo's Apache-2.0 license. Do not mix them into a brand folder. ## Step 7 — Verify before you trust it Do not skip this. Several claims that look obvious are wrong. **Verify color claims programmatically** rather than reading them off a page. Every color value in this folder's docs was checked by resolving the token reference chain and diffing against the written claim. Three examples that catch people out: - **HPE green `#01a982` is `color.decorative.brand`, not the primary action color.** Primary interactive surfaces use `#068667` in light mode and `#05cc93` in dark. Calling a button "HPE green" and reaching for `#01a982` produces the wrong button. - `base.color.green.400` and `base.color.green.500` are **both** `#00e0af`. That looks like a bug in your parser. It is not; the source really has both. - `color.background.front` is `#ffffff` in light mode and `#292d3a` in dark, while `color.text.strong` is `#292d3a` in light. The same hex serves opposite roles across modes. Do not deduplicate by value. **Check the docs against themselves.** The accessibility page cites **WCAG 2.2** at the top and **WCAG 2.1** in its government-standards section. The conformance level is consistent (**A and AA required**, per: "The guidelines identified as level A and AA are the required design elements for all applications") but the version reference is not. Record the discrepancy rather than picking one silently. **Do not infer from filenames.** The repo has a `knowledge/capabilities/ alignment-audit/` entry that sounds like a product compliance audit. Reading it shows a **planned stub** scoped to auditing the design system's own docs and tokens. Only `docs-refactor` is marked active. Open the file. ## Step 8 — Currency Two traps when judging how current something is: - **The site's "What's new" page is stale.** Its most recent entry is April 2023. It is not a changelog. - Use these instead: - `packages/hpe-design-tokens/CHANGELOG.md` - GitHub releases on `grommet/hpe-design-system` - `apps/docs/src/pages/design-tokens/versioning.mdx` for the version-to-theme map As of 2026-07-30: `hpe-design-tokens` **2.2.3**, `@hpe-design/icons-grommet` **1.2.0**, `@hpe-design/icons-svg` **0.2.0**. Current theme generation is **v2-Landmark** (October 2025 onward), paired with `grommet-theme-hpe` **8.x**. ## Licensing, and the one thing to be careful about The repo is **Apache-2.0**, "Copyright 2025 Hewlett Packard Enterprise Development LP." Copying the content and assets into an internal knowledge repo is fine, with attribution. **An open-source copyright license grants no trademark rights.** The HPE logo and the Element are HPE trademarks. Their use is governed by the [HPE Terms of Use](https://www.hpe.com/us/en/about/legal/terms-of-use.html), with authoritative files and usage rules on [Brand Central](https://brandcentral.hpe.com/home) (HPE login required). Practical consequence: a vendored logo is fine for reading and internal reference, but pull the current file from Brand Central for anything that ships or reaches a customer. A vendored mark goes stale silently, and the pending HPE GreenLake rebrand is exactly the event that would make a copy wrong. Also worth flagging to whoever consumes your mirror: **Brand Central and the Design System deliberately disagree on color.** The Design System says so directly and instructs product teams to prefer its palette for app and web work. Brand Central governs logos, print, and marketing. ## Recommended output shape What this folder settled on, if it is useful as a template: ``` hpe-branding/ ├── README.md index, provenance, currency traps ├── HOWTO-mirror-the-design-system.md this file ├── 01-what-it-is.md scope, packages, authority model ├── 02-brand-foundations.md logo rules, resolved hex tables, spacing px ├── 03-design-tokens.md three tiers, version map, units ├── 04-voice-and-tone.md UI copy rules, term list ├── 05-accessibility.md conformance level, responsibility split ├── 06-components-templates.md 48 components, 27 templates ├── 07-adoption-and-compliance.md adoption paths, review checklist └── assets/ ├── icons/ 452 SVGs + LICENSE ├── brand/ 5 word-marks └── site-images/ 282 documentation graphics ``` The judgment call worth repeating: **write down the resolved values, not just links to the site.** The whole reason this is work is that the site cannot be read without a browser. A mirror that only links back to it solves nothing. ## Quick reference | Thing | Where | | --- | --- | | Docs site | `https://design-system.hpe.design` (browser only) | | Source repo | `https://github.com/grommet/hpe-design-system` (Apache-2.0) | | MDX content | `apps/docs/src/pages/**/*.mdx` | | Graphics | `apps/docs/public/` | | Raw icons | `packages/icons-svg/src/icons/` | | Token JSON | `packages/hpe-design-tokens/tokens/` | | Grommet theme | `https://github.com/grommet/grommet-theme-hpe` | | Component props | `https://v2.grommet.io/?theme=hpe` | | Icon Storybook | `https://hpe-design-icons-grommet.netlify.app/` | | Brand Central | `https://brandcentral.hpe.com/home` (HPE login) | | Slack | `#hpe-design-system` on `grommet.slack.com` and HPE enterprise Slack |