← All articles
CICD Developer Portals and Documentation Platforms: IDPs ... 2026-02-09 · 9 min read · developer-portal · backstage · documentation

Developer Portals and Documentation Platforms: IDPs vs Good Docs

CICD 2026-02-09 · 9 min read developer-portal backstage documentation docusaurus mintlify developer-experience platform-engineering

Developer Portals and Documentation Platforms: IDPs vs Good Docs

There is a pattern that repeats across growing engineering organizations. Developers cannot find documentation. They do not know which team owns a service. They cannot figure out how to deploy something. The instinct is to buy or build a developer portal. But the root problem is usually one of two things: either you genuinely need a service catalog and self-service platform, or you just need documentation that does not suck.

These are different problems with different solutions. An Internal Developer Portal (IDP) like Backstage is a service catalog, scaffolding system, and plugin ecosystem rolled into one. A documentation platform like Docusaurus is a static site generator optimized for technical writing. Confusing the two leads to either over-engineering (building a portal when you need docs) or under-engineering (writing docs when you need a catalog).

This guide covers both categories honestly.

Internal Developer Portals

Internal developer portals centralize information about your services, infrastructure, teams, and processes. The good ones also let developers self-serve -- creating new services, provisioning infrastructure, running workflows -- without filing tickets.

Backstage (Spotify)

Backstage is the open-source developer portal that Spotify built and donated to the CNCF. It has become the default choice for companies building an IDP, partly because of its feature set and partly because there is no real open-source alternative at its scale.

Core Concepts:

# catalog-info.yaml -- lives in each repo
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
  name: user-service
  description: Handles user authentication and profile management
  annotations:
    github.com/project-slug: myorg/user-service
    backstage.io/techdocs-ref: dir:.
    pagerduty.com/service-id: P1234XY
  tags:
    - typescript
    - grpc
spec:
  type: service
  lifecycle: production
  owner: team-platform
  system: user-management
  providesApis:
    - user-api
  consumesApis:
    - notification-api
  dependsOn:
    - resource:user-database

Software Templates (scaffolding):

# template.yaml
apiVersion: scaffolder.backstage.io/v1beta3
kind: Template
metadata:
  name: typescript-service
  title: TypeScript Microservice
  description: Creates a new TypeScript service with CI/CD, monitoring, and database
spec:
  owner: team-platform
  type: service
  parameters:
    - title: Service Details
      required: [name, owner]
      properties:
        name:
          title: Service Name
          type: string
          pattern: '^[a-z][a-z0-9-]*$'
        owner:
          title: Owner Team
          type: string
          ui:field: OwnerPicker
        database:
          title: Database Type
          type: string
          enum: [postgres, mysql, none]
          default: postgres
  steps:
    - id: fetch
      name: Fetch Template
      action: fetch:template
      input:
        url: ./skeleton
        values:
          name: ${{ parameters.name }}
          owner: ${{ parameters.owner }}
    - id: publish
      name: Create Repository
      action: publish:github
      input:
        repoUrl: github.com?owner=myorg&repo=${{ parameters.name }}
    - id: register
      name: Register in Catalog
      action: catalog:register
      input:
        repoContentsUrl: ${{ steps.publish.output.repoContentsUrl }}
        catalogInfoPath: /catalog-info.yaml

Honest Assessment:

Backstage is powerful but expensive to operate. It requires dedicated engineering effort -- someone needs to maintain the Backstage instance, build plugins, keep catalog data current, and manage the infrastructure. Spotify has a team of 40+ people working on their internal Backstage instance. You will not need that many, but "deploy Backstage and forget about it" is not realistic.

The plugin ecosystem is broad but uneven. Some plugins are well-maintained (GitHub, PagerDuty, Kubernetes), others are abandoned community contributions. Expect to write custom plugins.

Best for: Companies with 100+ developers, multiple teams, and the engineering capacity to maintain a platform.

Port

Port is a SaaS developer portal that positions itself as "Backstage without the maintenance." You define your data model, ingest data from your existing tools, and get a portal with self-service actions.

# Port blueprint (defines a service entity)
{
  "identifier": "microservice",
  "title": "Microservice",
  "schema": {
    "properties": {
      "language": { "type": "string", "enum": ["TypeScript", "Go", "Python"] },
      "tier": { "type": "string", "enum": ["critical", "standard", "internal"] },
      "on_call": { "type": "string" },
      "grafana_url": { "type": "string", "format": "url" },
      "last_deploy": { "type": "string", "format": "date-time" }
    }
  },
  "relations": {
    "team": { "target": "team", "required": true },
    "api": { "target": "api", "many": true }
  }
}

Port's advantage is speed to value. You can have a working portal in days, not months. The trade-off is flexibility -- you are working within Port's framework rather than building your own.

Best for: Companies that want a portal but do not want to maintain Backstage. 50-500 developers.

Cortex and OpsLevel

Cortex and OpsLevel are SaaS portals that emphasize service maturity and engineering standards. They automatically score services based on criteria you define -- Does it have CI/CD? Is it using the approved database? Does it have documentation?

# Cortex scorecard example
scorecards:
  - name: Production Readiness
    rules:
      - title: Has CI/CD pipeline
        expression: github.workflows.length > 0
        weight: 20
      - title: Has on-call rotation
        expression: pagerduty.service != null
        weight: 25
      - title: Has README
        expression: github.files.includes("README.md")
        weight: 10
      - title: Test coverage > 80%
        expression: sonarqube.coverage > 80
        weight: 25
      - title: No critical vulnerabilities
        expression: snyk.critical == 0
        weight: 20

These scorecards are genuinely useful for engineering leadership. They give visibility into which services meet standards and which do not, without requiring manual audits.

Best for: Engineering orgs focused on reliability, compliance, or standardization. Particularly useful if you need to demonstrate compliance (SOC2, etc.).

When You Need an IDP

You need an internal developer portal when:

  1. Developers cannot find who owns a service. If answering "who owns this?" requires Slack archaeology, you need a catalog.
  2. Service creation involves filing tickets. If spinning up a new service takes days of manual setup, you need self-service scaffolding.
  3. You have more than 50 services. Below this threshold, a spreadsheet or wiki page works fine.
  4. You are doing platform engineering. If you have a platform team building golden paths, an IDP is where those paths live.

You do not need an IDP when:

  1. You have fewer than 30 developers. Everyone already knows who owns what.
  2. Your problem is documentation, not discovery. An IDP will not fix bad docs -- it will just give you a new place to put bad docs.
  3. Nobody will maintain it. An unmaintained developer portal with stale data is worse than no portal at all.

Documentation Platforms

If your actual problem is "developers cannot find how to do things," you need better documentation, not a portal. Here are the tools worth considering.

Docusaurus

Docusaurus (by Meta) is the most popular open-source documentation framework. It generates a static site from Markdown/MDX files with versioning, search, i18n, and a plugin system.

npx create-docusaurus@latest my-docs classic --typescript
docs/
├── intro.md
├── getting-started/
│   ├── installation.md
│   └── configuration.md
├── guides/
│   ├── authentication.md
│   └── deployment.md
└── api/
    └── reference.md
// docusaurus.config.js
const config = {
  title: 'My Platform Docs',
  url: 'https://docs.example.com',
  baseUrl: '/',
  organizationName: 'myorg',
  projectName: 'docs',
  presets: [
    [
      'classic',
      {
        docs: {
          sidebarPath: './sidebars.js',
          editUrl: 'https://github.com/myorg/docs/edit/main/',
          showLastUpdateTime: true,
          showLastUpdateAuthor: true,
          versions: {
            current: { label: 'v3.x', path: 'next' },
          },
        },
        blog: {
          showReadingTime: true,
          blogTitle: 'Engineering Blog',
        },
      },
    ],
  ],
  themes: [
    [
      require.resolve('@easyops-cn/docusaurus-search-local'),
      { hashed: true },
    ],
  ],
};

Pros: Battle-tested, excellent versioning for API docs, strong community, self-hosted. MDX support means you can embed interactive components in docs.

Cons: React-based, which means build times get slow with 1,000+ pages. The default theme looks like every other Docusaurus site. Customization beyond the basics requires understanding the React internals.

Nextra

Nextra is a Next.js-based documentation framework. It is lighter than Docusaurus and feels more natural if your team already uses Next.js.

npx create-next-app my-docs --example https://github.com/shuding/nextra-docs-template
pages/
├── _meta.json          # Sidebar configuration
├── index.mdx
├── getting-started.mdx
└── guides/
    ├── _meta.json
    ├── auth.mdx
    └── deploy.mdx
// pages/_meta.json
{
  "index": "Introduction",
  "getting-started": "Getting Started",
  "guides": "Guides",
  "api": "API Reference"
}
---
title: Authentication Guide
---

import { Callout, Tabs, Tab } from 'nextra/components'

# Authentication

<Callout type="warning">
  Always use HTTPS in production. HTTP auth tokens can be intercepted.
</Callout>

<Tabs items={['JWT', 'Session', 'OAuth']}>
  <Tab>
    ```typescript
    const token = jwt.sign({ userId }, process.env.JWT_SECRET, {
      expiresIn: '24h',
    });
    ```
  </Tab>
  <Tab>
    Session-based auth stores state server-side...
  </Tab>
</Tabs>

Pros: Fast, built on Next.js (ISR, API routes, React Server Components), clean default theme, great MDX support. Lighter than Docusaurus.

Cons: Smaller community, fewer plugins, no built-in versioning. If you need doc versioning, you will build it yourself.

Mintlify

Mintlify is a SaaS documentation platform that generates beautiful docs from Markdown files in your repo. You push to git, Mintlify builds and hosts.

# mint.json
{
  "name": "My API",
  "logo": { "dark": "/logo/dark.svg", "light": "/logo/light.svg" },
  "favicon": "/favicon.svg",
  "colors": { "primary": "#0D6EFD", "light": "#4A9EFF", "dark": "#0050C8" },
  "navigation": [
    {
      "group": "Getting Started",
      "pages": ["introduction", "quickstart", "authentication"]
    },
    {
      "group": "API Reference",
      "pages": [
        "api-reference/users/list",
        "api-reference/users/create",
        "api-reference/users/get"
      ]
    }
  ],
  "api": {
    "baseUrl": "https://api.example.com",
    "auth": { "method": "bearer" }
  },
  "openapi": "openapi.yaml"
}

Mintlify auto-generates interactive API reference pages from your OpenAPI spec, complete with "Try It" buttons. The output looks polished -- noticeably better than default Docusaurus or Nextra.

Pros: Beautiful out of the box, interactive API playground, built-in analytics, auto-generated API docs from OpenAPI specs.

Cons: SaaS-only (no self-hosting), pricing scales with pages and features. You are dependent on Mintlify staying in business. Limited customization compared to building your own with Docusaurus.

ReadMe

ReadMe is a full-featured API documentation platform. It does more than static docs -- it captures API usage metrics, shows personalized code samples (using the reader's actual API key), and provides interactive "Try It" consoles.

# .readme.yml
version: 2
apis:
  - id: main-api
    source: openapi.yaml
    slugPrefix: api

Pros: Personalized docs (users see their own API keys in examples), API metrics dashboard, excellent interactive experience. If your product is an API, ReadMe makes your docs part of the developer experience.

Cons: Expensive. Pricing starts reasonable but scales up quickly. The editing experience is browser-based, not files-in-git. Vendor lock-in is significant -- migrating off ReadMe means rebuilding your docs from scratch.

Comparison Summary

Feature Docusaurus Nextra Mintlify ReadMe
Hosting Self-hosted Self-hosted SaaS SaaS
Source format Markdown/MDX MDX Markdown Web editor + OpenAPI
Versioning Built-in Manual Planned Built-in
API playground Plugin needed No Built-in Built-in
Search Plugin (Algolia/local) Built-in Built-in Built-in
Price Free Free $150+/mo (teams) $99+/mo
Best for Large doc sites Next.js teams API docs API-first products

IDP vs Docs: Making the Decision

Here is a decision tree:

"Developers cannot find documentation" --> Fix your docs. Use Docusaurus or Nextra. Reorganize content. Add search. This is a content problem, not a tooling problem.

"Developers do not know who owns what" --> Start with a service catalog. Backstage's catalog or Port can solve this without building a full IDP.

"Creating a new service takes too long" --> You need scaffolding/self-service. This is IDP territory -- Backstage templates, Port self-service actions, or even just good CLI tools.

"We need to track engineering standards" --> Cortex or OpsLevel scorecards. Or Backstage with the Tech Insights plugin.

"We need all of the above" --> You probably need an IDP. But start with the catalog and add capabilities incrementally. Do not try to ship everything at once.

The Hybrid Approach

Many successful organizations use both. The IDP handles service discovery, scaffolding, and operational concerns. The docs platform handles guides, tutorials, and API references. The IDP links out to the docs.

# catalog-info.yaml -- linking to external docs
metadata:
  annotations:
    backstage.io/techdocs-ref: dir:.
  links:
    - url: https://docs.example.com/guides/user-service
      title: User Service Guide
    - url: https://api.example.com/docs
      title: API Reference

Bottom Line

For documentation: Start with Docusaurus if you want maximum control and a battle-tested platform. Use Nextra if you are a Next.js shop and want something lighter. Use Mintlify if you want beautiful API docs without building anything. Use ReadMe only if your product is an API and you want personalized, metrics-driven docs.

For developer portals: Use Backstage if you have the engineering capacity to maintain it (realistically, at least one dedicated engineer). Use Port if you want the same capabilities without the maintenance. Use Cortex or OpsLevel if your primary concern is engineering standards and service maturity.

The most common mistake is building a developer portal when the real problem is documentation. A portal does not help if the information it links to does not exist or is outdated. Fix your docs first, then consider whether you need a catalog, scaffolding, or self-service capabilities on top.

Start with the smallest tool that solves your actual problem. You can always add more tooling later, but removing an underused portal that took six months to build is painful.