npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@porscheofficial/porschedigital-technology-radar

v1.2.6

Published

Static site generator for building and publishing your own Technology Radar.

Readme

Porsche Digital Technology Radar

GitHub Pages Deploy npm version npm downloads TypeScript Next.js OpenSSF Scorecard CodeQL Conventional Commits License

A static site generator for building and publishing your own Technology Radar.

🔗 Live Showcase

Screenshot of the Technology Radar

Table of Contents

📖 About

This project is maintained by Porsche Digital and is based on the open-source AOE Technology Radar. The codebase has been substantially rewritten and extended — it is not a drop-in replacement.

[!NOTE] Your existing radar items (Markdown files) can be reused as-is, but the configuration needs to be updated to match the new schema.

💡 Why a Technology Radar?

A Technology Radar makes technology decisions visible across your organization. It gives CTOs, architects, and tech leads a shared vocabulary for evaluating, adopting, and retiring technologies — and keeps engineering teams aligned on what to invest in.

✨ Features

  • Visual technology landscape — See your entire technology portfolio at a glance, organized by quadrant and maturity ring
  • Track decisions over time — Full revision history per technology and a trajectory view across releases, so you can see how assessments evolved
  • Team visibility — Understand which teams use which technologies, enabling informed staffing and knowledge-sharing decisions
  • Searchable and filterable — Find technologies instantly by name, tag, team, or status with real-time highlighting across the radar. Supports configurable multi-select or single-select filtering with shareable filter URLs
  • Your branding, your rules — Fully customizable colors, logos, quadrants, rings, and labels via a single config.json
  • Zero infrastructure — Static site that deploys to GitHub Pages, Netlify, or any hosting. No servers, no databases, no runtime dependencies
  • Content as code — Technologies are plain Markdown files in Git. Review changes in PRs, track history with commits, collaborate with your existing workflow

📸 Screenshots

Quadrant Detail

Drill into a single quadrant with a zoomed mini-radar and a grouped technology list.

Quadrant detail page

Technology Detail

Each technology has its own page with ring status, description, tags, teams, and full revision history.

Technology detail page

History & Changelog

Track how technology assessments evolved across releases with the trajectory matrix.

History page

Mobile

Fully responsive — works on phones and tablets out of the box.

🚀 Quick Start

[!IMPORTANT] Prerequisites: Node.js 22+

1. Create a new project

mkdir my-technology-radar && cd my-technology-radar
npm init -y

2. Install the radar as a dependency

npm install @porscheofficial/porschedigital-technology-radar

3. Initialize the project

Scaffolds starter files (radar/, config.json, about.md, public/, custom.scss, .gitignore) into your directory:

npx techradar init

4. Customize

Edit the scaffolded files to match your organization:

  • config.json — branding, quadrants, rings, colors (see Configuration)
  • radar/ — your technology items as Markdown (see Radar Items)
  • about.md — content for the help & about page
  • public/ — favicon, images, background image
  • custom.scss — optional style overrides

5. Run

npx techradar dev     # Start dev server with file watching
npx techradar build   # Build static site → build/
npx techradar serve   # Start dev server without file watching

6. Deploy

After npx techradar build, the static site is in build/. Deploy it to GitHub Pages, Vercel, Netlify, or any static hosting provider.

📁 Project Structure (consumer)

my-technology-radar/
├── config.json          # Your configuration overrides
├── about.md             # Content for the help & about page
├── custom.scss          # Optional style overrides
├── public/
│   ├── favicon.ico      # Your favicon
│   └── images/          # Images referenced in radar items
├── radar/
│   ├── 2024-06-01/
│   │   ├── react.md
│   │   └── kubernetes.md
│   └── 2025-01-15/
│       ├── react.md     # Updated entry overwrites previous
│       └── deno.md
├── build/               # Generated static site (after build)
├── .techradar/          # Shadow build dir (auto-generated)
└── .gitignore           # Auto-generated with .techradar/, build/, node_modules/

The CLI automatically creates a .gitignore (or extends your existing one) with the entries needed to keep generated directories out of version control.

[!TIP] Only config.json, about.md, custom.scss, public/, and radar/ need your attention. Everything else is managed by the CLI.

⚙️ Configuration

All configuration lives in data/config.json. Any key you omit falls back to the defaults in data/config.default.json. You only need to set what you want to change.

| Key | Description | Default | | ------------------- | -------------------------------------------------------------------------------------------------- | ------- | | basePath | URL path prefix. Set to / for root hosting, or /techradar for a sub-path. | / | | baseUrl | Full origin (scheme + host) where the radar is hosted, e.g. https://opensource.porsche.com. Used for sitemap.xml, canonical links, and Open Graph / Twitter meta tags. The runtime env var NEXT_PUBLIC_BASE_URL overrides this when set (useful for staging deploys). The basePath is appended automatically — do not include it here. | "" | | editUrl | If set, shows an edit button on item pages. Supports {id} and {release} placeholders. Example: https://github.dev/org/repo/blob/main/data/radar/{release}/{id}.md | "" | | headerLogoFile | Path to a logo image in public/ for the header. Leave empty to use the default Porsche crest. | "" | | footerLogoFile | Path to a logo image in public/ for the footer. Leave empty to use the default Porsche wordmark. | "" | | jsFile | Path in public/ or URL to a custom JavaScript file to include on every page. | "" | | backgroundImage | Path to an image in public/ shown as a subtle background overlay. Leave empty to disable. | "" | | backgroundOpacity | Opacity of the background image overlay (0 = invisible, 1 = fully visible). | 0.06 | | imprint | URL to your legal information / imprint page. | "" |

| Key | Description | Default | | ---------------- | --------------------------------------------- | ------- | | showSearch | Show the search bar in the header. | true | | showChart | Show the radar visualization on the homepage. | true | | showTagFilter | Show the tag filter below the radar. | true | | showTeamFilter | Show the team filter below the radar. | true | | showBlipChange | Show a directional arc on Changed blips indicating promotion (inward) or demotion (outward). | true | | showDemoDisclaimer | Show the demo-data disclaimer banner on the homepage. | false | | multiSelectFilters | Allow selecting multiple filters per dimension (OR semantics within, AND across). When false, each dimension allows only one active filter at a time. | true |

A map of CSS color values that theme the entire radar.

| Key | Description | Default | | ------------ | ------------------------------------ | --------- | | foreground | Primary text and UI element color | #FBFCFF | | background | Page background | #0E0E12 | | highlight | Highlighted text and active elements | #FBFCFF | | content | Secondary content text | #AFB0B3 | | text | Tertiary / muted text | #88898C | | link | Link color | #FBFCFF | | border | Border and separator color | #404044 | | tag | Tag background color | #404044 |

An array of quadrant objects (1 or more). The radar geometry adapts automatically — arc sweep is 360° / N, and labels follow the arcs. 3 to 6 is the comfortable range; beyond 6 the per-quadrant arc becomes too narrow for readable labels and the blips start to crowd. Despite the name, "quadrant" here means "any radial segment of the radar"; the term is kept for backward compatibility.

Heads up: A future major release will rename quadrants to segments (config key, frontmatter attribute, and TypeScript types) to match the actual capability. A backward-compatibility shim will accept the old name with a deprecation warning, so existing radars will keep building.

| Key | Description | | ------------- | ------------------------------------------------ | | id | Identifier used in radar Markdown files and URLs | | title | Display title of the quadrant | | description | Shown on the homepage and quadrant detail page | | color | CSS color for the quadrant arc and its blips |

An array of ring objects (typically 4), ordered from innermost to outermost.

| Key | Description | | ------------- | -------------------------------------------------------------- | | id | Identifier used in radar Markdown files | | title | Display title, shown as badge label | | description | Optional description text | | color | CSS color for the ring badge | | radius | Outer boundary of the ring as a fraction of the chart (0 to 1) | | strokeWidth | Thickness of the ring's arc border in the SVG |

Flags mark items as new, changed, or default (unchanged). Each flag has a single key:

| Key | Description | | ------- | --------------------------------------------------------------- | | title | Display label for the flag (e.g. "New", "Changed", "Unchanged") |

| Key | Description | Default | | ---------- | ------------------------------------------------------------------------ | ------- | | size | Base size of the radar chart in pixels. Increase if you have many items. | 800 | | blipSize | Radius of each blip dot in pixels | 12 |

An array of social link objects shown in the footer.

| Key | Description | | ------ | ------------------------------------------------------------------------------------------------------------------ | | href | URL to the social profile | | icon | Icon name. Available: x, linkedin, facebook, instagram, youtube, xing, pinterest, github, gitlab |

| Key | Description | Default | | ------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | | title | Radar title shown in the header and page titles | "Technology Radar" | | tagline | Shared subtitle used in the default Open Graph image | "Track what to adopt, trial, assess, and hold." | | imprint | Label for the imprint link in the footer | "Legal Information" | | footer | Text shown in the footer | "Based on the open-source Technology Radar by AOE GmbH, extensively modified by Porsche Digital." | | notUpdated | Warning shown on items not updated in the last 3 releases | "This item was not updated in last three versions of the Radar." | | hiddenFromRadar | Info shown on items hidden from the radar chart | "This technology is currently hidden from the radar chart." | | searchPlaceholder | Placeholder text in the search input | "What are you looking for?" | | metaDescription | HTML meta description for SEO | "" |


Full example

{
  "basePath": "/techradar",
  "baseUrl": "https://techradar.acme.io",
  "editUrl": "https://github.dev/acme/techradar/blob/main/radar/{release}/{id}.md",
  "headerLogoFile": "/images/acme-logo.svg",
  "footerLogoFile": "/images/acme-wordmark.svg",
  "backgroundImage": "/images/bg-pattern.png",
  "backgroundOpacity": 0.04,
  "imprint": "https://acme.io/legal",
  "toggles": {
    "showSearch": true,
    "showChart": true,
    "showTagFilter": true,
    "showTeamFilter": false,
    "showBlipChange": true,
    "multiSelectFilters": true
  },
  "colors": {
    "foreground": "#F0F0F5",
    "background": "#1A1A2E",
    "highlight": "#E94560",
    "content": "#A0A0B0",
    "text": "#707080",
    "link": "#E94560",
    "border": "#2A2A40",
    "tag": "#2A2A40"
  },
  "quadrants": [
    {
      "id": "languages-and-frameworks",
      "title": "Languages & Frameworks",
      "description": "Programming languages and application frameworks used across our stack.",
      "color": "#0F9D58"
    },
    {
      "id": "infrastructure",
      "title": "Infrastructure",
      "description": "Cloud platforms, orchestration, and infrastructure-as-code tools.",
      "color": "#4285F4"
    },
    {
      "id": "data-and-ai",
      "title": "Data & AI",
      "description": "Data pipelines, storage, analytics, and machine learning frameworks.",
      "color": "#F4B400"
    },
    {
      "id": "developer-experience",
      "title": "Developer Experience",
      "description": "Tools and practices that improve developer productivity and satisfaction.",
      "color": "#DB4437"
    }
  ],
  "rings": [
    {
      "id": "adopt",
      "title": "Adopt",
      "description": "Proven in production. Use by default for new projects.",
      "color": "#0F9D58",
      "radius": 0.5,
      "strokeWidth": 5
    },
    {
      "id": "trial",
      "title": "Trial",
      "description": "Worth pursuing. Use in non-critical projects to build experience.",
      "color": "#4285F4",
      "radius": 0.69,
      "strokeWidth": 3
    },
    {
      "id": "assess",
      "title": "Assess",
      "description": "Interesting. Explore in spikes or proof-of-concepts.",
      "color": "#F4B400",
      "radius": 0.85,
      "strokeWidth": 2
    },
    {
      "id": "hold",
      "title": "Hold",
      "description": "Do not start new work with this. Migrate away when practical.",
      "color": "#DB4437",
      "radius": 1,
      "strokeWidth": 0.75
    }
  ],
  "flags": {
    "new": { "title": "New" },
    "changed": { "title": "Changed" },
    "default": { "title": "Unchanged" }
  },
  "chart": {
    "size": 900,
    "blipSize": 14
  },
  "social": [
    { "href": "https://github.com/acme", "icon": "github" },
    { "href": "https://linkedin.com/company/acme", "icon": "linkedin" }
  ],
  "labels": {
    "title": "ACME Tech Radar",
    "tagline": "Track what to adopt, trial, assess, and hold.",
    "imprint": "Legal Notice",
    "footer": "Built with the Porsche Digital Technology Radar.",
    "notUpdated": "This item has not been reviewed in the last three releases.",
    "hiddenFromRadar": "This technology is hidden from the radar chart.",
    "searchPlaceholder": "Search technologies…",
    "metaDescription": "ACME's technology radar — tracking what we adopt, trial, assess, and hold."
  }
}

📝 Radar Items

Radar items are Markdown files organized by release date under radar/.

radar/
├── 2024-06-01/
│   ├── react.md
│   └── kubernetes.md
└── 2025-01-15/
    ├── react.md
    └── deno.md

Each file has a YAML front-matter header followed by Markdown content:

---
title: "React"
ring: adopt
quadrant: languages-and-frameworks
tags:
  - frontend
  - javascript
teams:
  - web-platform
  - mobile
links:
  - url: https://react.dev
    name: Official Docs
  - url: https://github.com/facebook/react
---

Description of the technology, why it was adopted, and any relevant context.
Supports full **Markdown** formatting.

Front-matter attributes

| Attribute | Required | Description | | ---------- | -------- | ------------------------------------------------------------------------------------------------------- | | title | Yes | Name of the technology | | ring | Yes | Ring placement. Must match one of the id values in config.rings. | | quadrant | Yes | Quadrant assignment. Must match one of the id values in config.quadrants. | | summary | No | Custom summary used for meta descriptions and link previews. Falls back to the first 160 characters of the item body. | | ogImage | No | Custom Open Graph image. Use a relative path under public/ (for example /images/react-card.png) or a full https://... URL. | | tags | No | List of tags for filtering. | | teams | No | List of teams currently using this technology. | | links | No | List of external links. Each entry has a url (required) and optional name. Shown on the detail page. | | featured | No | Set to false to hide from the radar chart while keeping the item in the overview. Defaults to true. |

Versioning

The filename (without .md) serves as the item identifier. When the same filename appears in a newer release folder, the newer entry overwrites the previous one — attributes are merged and a new history entry is created.

Images

Place images in public/images/ and reference them in Markdown:

![Architecture diagram](/images/architecture.png)

Open Graph images

The build generates rich Open Graph / Twitter Card images for link previews.

  • pnpm run build:og creates a shared default card at public/og/default.png.
  • Every item detail page also gets a deterministic 1200×630 PNG at public/og/<quadrant>/<id>.png.
  • Generation is content-hash cached, so unchanged cards are skipped on later builds.

To override the generated image for a single item, set ogImage in front-matter:

ogImage: /images/custom-card.png

Relative paths must point to an existing asset under public/. You can also use a full external URL:

ogImage: https://cdn.example.com/cards/react.png

When ogImage is omitted, the generator builds the per-item card automatically. When summary is omitted, the site derives the preview text from the rendered item body.

Cross-linking blips

Use wiki-link syntax to link between radar items. The build resolves each link to the correct URL based on the item's quadrant:

We use [[typescript]] alongside [[react]] for our frontend stack.
See also [[kubernetes|our K8s setup]] for deployment details.

| Syntax | Rendered as | | --- | --- | | [[item-id]] | Link using the item's title as label | | [[item-id\|custom label]] | Link using a custom label |

The item-id is the Markdown filename without the .md extension (e.g., typescript.mdtypescript).

Unresolved wiki-links (referencing a non-existent item) are rendered as plain text with a build warning.

[!WARNING] In strict mode (--strict), unresolved wiki-links cause the build to fail.

🛠️ Development (contributing to the generator)

To work on the radar generator itself:

git clone https://github.com/porscheofficial/porschedigital-technology-radar.git
cd porschedigital-technology-radar
pnpm install          # Also runs postinstall → build:icons
pnpm run build:data   # Parse Markdown files into data/data.json
pnpm run dev          # Start Next.js dev server

The build pipeline:

  1. build:icons — generates React icon components from SVGs in src/icons/
  2. build:data — parses radar/ Markdown files into data/data.json and data/about.json
  3. build:og — generates cached Open Graph PNGs in public/og/
  4. next build — builds the static site into out/

The pnpm run build command runs all three steps in sequence.

Pre-commit hooks

This repository runs two local pre-commit checks through Husky:

  • lint-stagedbiome check --write --no-errors-on-unmatched for staged files
  • pnpm run precommit:secrets → staged-content secret scanning via TruffleHog

The secret scan reads the staged blob content, not the working tree, so it still catches leaks correctly when you used partial staging such as git add -p.

trufflehog is optional for local development. If the binary is missing, the hook prints a warning and exits successfully so contributors in fresh environments are not blocked.

Install it locally with Homebrew:

brew install trufflehog

If you absolutely must bypass both pre-commit hooks in an emergency, Git still supports:

git commit --no-verify

That bypass is discouraged; the normal path is to fix the formatting issue or remove the secret from the staged content before committing.

Strict mode

Pass --strict to turn warnings into errors during the data build step.

Consumer projects (using the CLI):

npx techradar --strict build
npx techradar --strict dev

This repository (development):

pnpm run build:data --strict

In strict mode, the build fails on:

  • Invalid frontmatter (missing or invalid ring, quadrant, etc.)
  • Unresolved wiki-links (e.g., [[nonexistent-item]])

This is recommended for CI pipelines to catch issues before deployment.

[!TIP] Add npx techradar --strict build to your CI pipeline to catch frontmatter issues and broken wiki-links before deployment.

🎨 Custom Styling

You can add custom SCSS rules in custom.scss.

[!NOTE] The project uses CSS Modules with hashed class names. Use element or attribute selectors to target components.

/* Example: change headline fonts */
h1,
h2,
h3 {
  font-family: "Times New Roman", Times, serif;
}

Changes to custom.scss are picked up automatically in dev mode (with file watching).

📄 License

This project is open source under the Apache License 2.0.

Originally based on the AOE Technology Radar. Maintained and developed by Porsche Digital.