$npx -y skills add remotion-dev/remotion --skill add-cli-optionAdd a new Remotion CLI or config option by creating an AnyRemotionOption, registering CLI parsing, wiring config setters, and updating documentation. Use when adding or converting command-line flags or Remotion options.
| 1 | # Add a new CLI option |
| 2 | |
| 3 | How to convert a hardcoded CLI flag into a proper `AnyRemotionOption`, or add a brand new one. |
| 4 | |
| 5 | ## 1. Create the option definition |
| 6 | |
| 7 | Create `packages/renderer/src/options/<name>.tsx`: |
| 8 | |
| 9 | ```tsx |
| 10 | import type {AnyRemotionOption} from './option'; |
| 11 | |
| 12 | let myValue = false; // module-level default state |
| 13 | |
| 14 | const cliFlag = 'my-flag' as const; |
| 15 | |
| 16 | export const myFlagOption = { |
| 17 | name: 'Human-readable Name', |
| 18 | cliFlag, |
| 19 | description: () => <>Description shown in docs.</>, |
| 20 | ssrName: null, // or 'myFlag' if used in SSR APIs |
| 21 | docLink: 'https://www.remotion.dev/docs/config#setmyflagenabled', |
| 22 | type: false as boolean, // default value, also sets the TypeScript type |
| 23 | getValue: ({commandLine}) => { |
| 24 | if (commandLine[cliFlag] !== undefined) { |
| 25 | return {value: commandLine[cliFlag] as boolean, source: 'cli'}; |
| 26 | } |
| 27 | return {value: myValue, source: 'config'}; |
| 28 | }, |
| 29 | setConfig(value) { |
| 30 | myValue = value; |
| 31 | }, |
| 32 | } satisfies AnyRemotionOption<boolean>; |
| 33 | ``` |
| 34 | |
| 35 | The type in `AnyRemotionOption<T>` and `type: <default> as T` determines the option's value type. Use `boolean`, `string | null`, `number | null`, etc. |
| 36 | |
| 37 | For negating flags (like `--disable-ask-ai` → `askAIEnabled = false`), handle the inversion in `getValue`. |
| 38 | |
| 39 | ## 2. Register in options index |
| 40 | |
| 41 | **`packages/renderer/src/options/index.tsx`**: |
| 42 | |
| 43 | - Add the import (keep alphabetical within the import block) |
| 44 | - Add the option to the `allOptions` object |
| 45 | |
| 46 | This makes it available as `BrowserSafeApis.options.myFlagOption` throughout the codebase. |
| 47 | |
| 48 | ## 3. Update CLI parsed flags |
| 49 | |
| 50 | **`packages/cli/src/parsed-cli.ts`**: |
| 51 | |
| 52 | - For boolean flags, add `BrowserSafeApis.options.myFlagOption.cliFlag` to the `BooleanFlags` array |
| 53 | - For non-boolean flags, no entry needed here (minimist handles them as strings/numbers automatically) |
| 54 | |
| 55 | **`packages/cli/src/parse-command-line.ts`**: |
| 56 | |
| 57 | - Add to the destructured `BrowserSafeApis.options` |
| 58 | - In the `CommandLineOptions` type, add: `[myFlagOption.cliFlag]: TypeOfOption<typeof myFlagOption>;` |
| 59 | |
| 60 | ## 4. Use the option where needed |
| 61 | |
| 62 | Instead of reading `parsedCli['my-flag']` directly, resolve via: |
| 63 | |
| 64 | ```ts |
| 65 | const myFlag = myFlagOption.getValue({commandLine: parsedCli}).value; |
| 66 | ``` |
| 67 | |
| 68 | For Studio options, this is typically in `packages/cli/src/studio.ts`. For render options, in the relevant render command file. |
| 69 | |
| 70 | If the option is consumed by Studio, read [`../studio-config-option-lifecycle/SKILL.md`](../studio-config-option-lifecycle/SKILL.md) completely before wiring it. Classify the option as startup-fixed or reloadable across all Studio consumers; mixed behavior is not allowed. If any consumer requires startup-fixed behavior, pass the startup snapshot to every consumer. Add lifecycle tests that prove the classification. |
| 71 | |
| 72 | ## 5. Add to Config |
| 73 | |
| 74 | **`packages/cli/src/config/index.ts`**: |
| 75 | |
| 76 | - Add to the destructured `BrowserSafeApis.options` |
| 77 | - Add the setter signature to the `FlatConfig` type (either in the `RemotionConfigObject` global interface or the `FlatConfig` intersection) |
| 78 | - Add the implementation to the `Config` object: `setMyFlagEnabled: myFlagOption.setConfig` |
| 79 | |
| 80 | ## 6. Update docs — IMPORTANT, do not skip this step |
| 81 | |
| 82 | **This step is mandatory.** Every new option must have its docs updated to use `<Options id="..." />` so the description is pulled from the option definition automatically (single source of truth). If converting an existing hardcoded flag, replace any hand-written description with the `<Options>` component. |
| 83 | |
| 84 | **CLI command pages** (check all that apply — `cli/render.mdx`, `lambda/cli/render.mdx`, `cloudrun/cli/render.mdx`, `cli/benchmark.mdx`): |
| 85 | |
| 86 | - Add or update the `### \`--my-flag\`` section |
| 87 | - Use `<Options id="my-flag" />` as the description body (no import needed — it's globally available) |
| 88 | - The `id` must match the option's `cliFlag` / `id` value |
| 89 | |
| 90 | **`packages/docs/docs/config.mdx`**: |
| 91 | |
| 92 | - Add or update the `## \`setMyFlagEnabled()\`` section with: |
| 93 | - `<Options id="my-flag" />` for the description |
| 94 | - A twoslash config example |
| 95 | - A note that the CLI flag takes precedence |
| 96 | |
| 97 | Follow the pattern of nearby entries (e.g., `setAskAIEnabled`, `setEnableCrossSiteIsolation`). |
| 98 | |
| 99 | ## 7. Build and verify |
| 100 | |
| 101 | ```sh |
| 102 | cd packages/renderer && bun run make |
| 103 | cd packages/cli && bun run make |
| 104 | ``` |
| 105 | |
| 106 | ## Reference files |
| 107 | |
| 108 | - Option type definition: `packages/renderer/src/options/option.ts` |
| 109 | - Good example to copy: `packages/renderer/src/options/ask-ai.tsx` (boolean, studio-only) |
| 110 | - Options index: `packages/renderer/src/options/index.tsx` |
| 111 | - CLI flag registration: `packages/cli/src/parsed-cli.ts` |
| 112 | - CLI type definitions: `packages/cli/src/parse-command-line.ts` |
| 113 | - Config registration: `packages/cli/src/config/index.ts` |