Workspaces

Overview

Workspaces are metadata entries that describe your monorepo's services, libraries, and other groupings. They drive home-page card sections and landing-page cards without forcing you to restructure your repo. Three top-level config fields expose them: apps, packages, and workspaces.

Key Terms

  • Workspace — a metadata entry describing a service or library (an app or package)
  • WorkspaceGroup — a named group with its own title, icon, and items: Workspace[] (the unit workspaces consumes)
  • Path — the URL path segment that links a workspace to its corresponding section
  • Discovery — glob-based content discovery scoped to a workspace's base path

How It Works

The three top-level surfaces

CiderpressConfig exposes three workspace fields:

FieldTypePurpose
appsWorkspace[]Services / runtime apps. Rendered as one home-page section labelled "Apps".
packagesWorkspace[]Libraries / publishable packages. Rendered as one home-page section.
workspacesWorkspaceGroup[]Custom named groupings — each group becomes its own home-page section.

apps and packages are flat arrays of Workspace; workspaces is an array of WorkspaceGroup, each containing its own items: Workspace[]. Use apps/packages for the common case; use workspaces when you need custom group names (e.g. "Internal Tools", "Plugins", "Adapters").

Dogfood pattern

The ciderpress repo itself uses packages (not workspaces) since every entry is a publishable package:

import { defineConfig } from 'ciderpress'

export default defineConfig({
  packages: [
    {
      title: 'ciderpress',
      icon: { id: 'simpleicons:apple', color: 'red' },
      description: 'Public wrapper package',
      tags: ['typescript', 'cli'],
      path: '/packages/ciderpress',
      include: 'docs/*.md',
    },
    {
      title: '@ciderpress/cli',
      description: 'CLI commands and Rspress integration',
      path: '/packages/cli',
      include: 'docs/*.md',
    },
  ],
})

Mixed apps + packages + custom groups

import { defineConfig } from 'ciderpress'

export default defineConfig({
  apps: [
    {
      title: 'API',
      icon: { id: 'devicon:hono', color: 'blue' },
      description: 'REST API with typed routes',
      tags: ['hono', 'typescript', 'node'],
      path: '/apps/api',
      include: 'docs/*.md',
      sort: 'alpha',
    },
  ],
  packages: [
    {
      title: 'SDK',
      description: 'TypeScript client SDK',
      tags: ['typescript', 'npm'],
      path: '/packages/sdk',
      include: 'docs/*.md',
    },
  ],
  workspaces: [
    {
      title: 'Internal Tools',
      icon: 'pixelarticons:hammer',
      items: [
        {
          title: 'release-bot',
          description: 'Slack release bot',
          path: '/internal/release-bot',
          include: 'docs/*.md',
        },
      ],
    },
  ],
})

Workspace fields

FieldTypeRequiredDescription
titlestringyesDisplay name
iconIconConfignoIcon ID string or { id, color } object
descriptionstringyesShort description for cards
tagsstring[]noTechnology tags (kebab-case)
badge{ src: string; alt: string }noDeploy badge image
pathstringyesURL path for this workspace's documentation
includestring | string[]noGlob pattern(s) for content discovery
sortSortStrategynoSort strategy for discovered pages
excludestring[]noGlob patterns to exclude from discovery
recursivebooleannoMap subdirectories to nested sidebar groups
entryFilestringnoFilename promoted to section header in recursive mode
frontmatterRecord<string, unknown>noFrontmatter injected into all discovered pages
itemsSection[]noExplicit child sections
openapiOpenAPIConfignoOpenAPI spec integration for this workspace

WorkspaceGroup fields

FieldTypeRequiredDescription
titlestringyesGroup label rendered as the home-page section header
iconIconConfignoIcon for the group header
descriptionstringnoSub-header copy under the section title
itemsWorkspace[]yesThe workspaces in this group

Path matching

Workspace items are matched to sections by path. When a section's path matches a workspace item's path, the workspace metadata is injected into that section's auto-generated landing page as a card.

The include pattern is relative to the workspace's base directory (derived from path). For example, path: "/apps/api" + include: "docs/*.md" resolves to apps/api/docs/*.md (repo-root relative).

Where they render

  • Home pageapps, packages, and each WorkspaceGroup in workspaces each become their own card section on the home page (rendered by buildWorkspaceSection). Order on the home page is appspackagesworkspaces[*].
  • Section landing pages — when a section's path matches a workspace item's path, the matched workspace metadata is rendered as a workspace-style card on that section's auto-generated landing page.

Card rendering

Cards display:

  • Icon with color styling
  • Scope label (derived from path, e.g. apps/)
  • Name and description
  • Technology tag badges
  • Optional deploy badge

See the Navigation concept for details on auto-generated landing pages and section cards.

Design Decisions

  • Metadata separate from sections — workspace metadata lives in apps/packages/workspaces rather than inline on sections. This keeps section definitions focused on information architecture while workspace metadata focuses on project identity.
  • Path-based matching — matching by URL path rather than explicit IDs keeps the two systems loosely coupled. A section works with or without workspace metadata.
  • Three surfaces, not oneapps and packages give monorepos the two most common groupings out of the box without forcing readers to learn the WorkspaceGroup shape; workspaces is the escape hatch for custom groupings.

References