Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions .agents/skills/rstack-cli-best-practices/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
---
name: rstack-cli-best-practices
description: Guidance on using Rstack CLI, including `rs` commands, the `rstack.config.ts` file, and import paths from the `rstack` package. Use for Rstack CLI-related tasks.
---

# Rstack CLI Best Practices

Rstack CLI is the `rstack` package, exposed through the `rs` binaries. It provides one CLI, one config file, and a consistent workflow for the Rstack JavaScript toolchain.

It covers web app, library, docs, test, lint, and staged-file workflows.

## Commands

Use `rs -h` for top-level help, and `rs <command> -h` for command help where supported.

| Command | Purpose | Underlying tool | Config |
| ------------ | -------------------------------- | --------------- | --------------- |
| `rs dev` | Run the app dev server | Rsbuild | `define.app` |
| `rs build` | Build the app for production | Rsbuild | `define.app` |
| `rs preview` | Preview the app production build | Rsbuild | `define.app` |
| `rs lib` | Build a library | Rslib | `define.lib` |
| `rs doc` | Serve or build docs | Rspress | `define.doc` |
| `rs test` | Run tests | Rstest | `define.test` |
| `rs lint` | Lint code | Rslint | `define.lint` |
| `rs staged` | Run tasks on staged Git files | lint-staged | `define.staged` |

Key behavior:

- `rs test` extends `define.app` through `@rstest/adapter-rsbuild` and `define.lib` through `@rstest/adapter-rslib` unless `define.test` already sets `extends`.
- `rs doc` requires the optional `@rspress/core` dependency.

## rstack.config.ts

Rstack CLI loads `rstack.config.{ts,js,mts,mjs}` by default.

Register config with `define.*`:

```ts
import { define } from 'rstack';

define.app({
// Rsbuild config for `rs dev`, `rs build`, and `rs preview`
});

define.test({
// Rstest config for `rs test`
});
```

- `define.app(config)`: Rsbuild config for `rs dev`, `rs build`, and `rs preview`. Docs: https://rsbuild.rs/config/
- `define.lib(config)`: Rslib config for `rs lib`; Docs: https://rslib.rs/config/
- `define.doc(config)`: Rspress config for `rs doc`; Docs: https://rspress.rs/api/config/config-basic
- `define.test(config)`: Rstest config for `rs test`; Docs: https://rstest.rs/config/
- `define.lint(config)`: Rslint config for `rs lint`; Docs: https://rslint.rs/config/
- `define.staged(config)`: lint-staged config for `rs staged`; accepts `Record<string, string | string[]>`.

### Lazy Configuration

Prefer async functions with dynamic imports for dependencies. Avoid top-level sync imports of heavy dependencies in `rstack.config.ts`.

```ts
import { define } from 'rstack';

define.app(async () => {
const { pluginReact } = await import('@rsbuild/plugin-react');
return {
plugins: [pluginReact()],
};
});
```

## Import Paths

Prefer Rstack-exported paths:

| Instead of | Prefer |
| ------------------------- | ------------------------ |
| `@rstest/core` | `rstack/test` |
| `@rslint/core` | `rstack/lint` |
| `@rsbuild/core/types` | `rstack/types` |
| `@rslib/core/types` | `rstack/types` |
| `@rstest/core/globals` | `rstack/test/globals` |
| `@rstest/core/importMeta` | `rstack/test/importMeta` |