# Package Manager Tabs

Convert package-manager commands into synced MDX tabs.

import { Callout, Steps } from '@prosefly/astro-components';

Use `remarkPackageManagerTabs` when authors should write one familiar command
and let the docs render equivalent commands for other package managers.

<Callout type="tip" title="Using Lotus">
  [Lotus](https://astro-theme-lotus.prosefly.dev/) enables package manager tabs
  automatically. If your site uses
  [`@prosefly/astro-theme-lotus`](https://astro-theme-lotus.prosefly.dev/), do
  not add this plugin yourself.
</Callout>

## What Authors Write

Write a supported command in a shell code block:

```sh
npm install @prosefly/astro-components
```

The transform renders tabs for `pnpm`, `npm`, `yarn`, and `bun`. The generated
commands keep the same package names and normalize install syntax for each
tool.

## Supported Node Commands

- `npm install`
- `npm install <packages>`
- `npm i <packages>`
- `npm add <packages>`
- `npm run <script>`
- `npm create <initializer>`
- `npx <command>`
- `npm dlx <command>`

Install commands preserve package names and normalize dev-dependency flags for
each package manager. For example, `npm install --save-dev typescript` becomes
the matching `pnpm add -D`, `yarn add -D`, and `bun add -d` command.

Examples:

```sh
npm run build
```

```sh
npx astro add mdx
```

## Supported Python Commands

Python install commands render as `pip`, `uv`, `poetry`, and `pdm` tabs.

```sh
pip install prosefly
```

Supported forms include:

- `pip install <packages>`
- `python -m pip install <packages>`
- `python3 -m pip install <packages>`
- `uv pip install <packages>`
- `uv add <packages>`
- `poetry add <packages>`
- `pdm add <packages>`

## Standalone Astro Setup

If you are not using [Lotus](https://astro-theme-lotus.prosefly.dev/), add the
remark plugin in `astro.config.ts`.

```ts title="astro.config.ts"
import { defineConfig } from 'astro/config';
import { remarkPackageManagerTabs } from '@prosefly/astro-components/markdown';

export default defineConfig({
  markdown: {
    remarkPlugins: [remarkPackageManagerTabs],
  },
});
```

The plugin injects the required `Tabs` and `TabItem` imports when it transforms a
code block, so authors do not need to import those components manually.

## Authoring Rules

<Steps>

1. **Use a shell code fence.**

   The plugin transforms `sh`, `shell`, `bash`, `zsh`, `terminal`, and
   `console` blocks. It also handles code fences without a language.

2. **Keep prompts simple.**

   Lines may start with `$ `, and the prompt is preserved in each generated
   command. Other prompt formats remain normal code blocks.

3. **Keep each transformed block consistent.**

   A block can contain multiple commands, but they must belong to the same
   package-manager family. Do not mix Node and Python commands in the same code
   block.

4. **Leave custom commands alone.**

   Unsupported commands remain normal code blocks. Use manual `Tabs` when the
   alternatives need custom wording.

</Steps>

<Callout type="warning" title="Avoid double configuration">
  [Lotus](https://astro-theme-lotus.prosefly.dev/) already configures this
  plugin. Adding it again can duplicate imports or produce nested tab output.
</Callout>
