@gunshi/docs 0.27.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,472 @@
1
+ # Plugin System
2
+
3
+ ## What's a Plugin?
4
+
5
+ A plugin in Gunshi is a modular extension that adds functionality to your CLI application without modifying its core code.
6
+
7
+ Think of plugins as building blocks that you can snap together to create powerful command-line tools.
8
+
9
+ ### Why Use Plugins?
10
+
11
+ Plugins solve common CLI development challenges:
12
+
13
+ - **Separation of Concerns**: Plugins keep your command logic clean by handling cross-cutting functionality like logging, authentication, or database connections separately. Your commands focus on their primary task while plugins handle the supporting infrastructure.
14
+ - **Reusability**: Write functionality once, use it everywhere. A plugin created for one command can be reused across your entire CLI or even in different projects, saving development time and ensuring consistency.
15
+ - **Composability**: Plugins work together seamlessly. You can combine multiple plugins—an authentication plugin with a logging plugin and a database plugin—and they'll integrate naturally into your CLI's lifecycle.
16
+
17
+ ### How Plugins Work
18
+
19
+ Plugins integrate at specific points in your CLI's execution:
20
+
21
+ 1. **Registration**: When your CLI starts, plugins are registered and their dependencies are resolved
22
+ 2. **Setup**: Plugins initialize and configure themselves, adding any global options (like `--debug`)
23
+ 3. **Extension**: Plugins extend your command context with new functionality (like translation methods or API clients)
24
+ 4. **Decoration**: Plugins can modify how commands execute or how help text is displayed
25
+ 5. **Execution**: Your commands run with all plugin enhancements seamlessly integrated
26
+
27
+ This lifecycle integration means plugins can:
28
+
29
+ - Add global options available to all commands (like `--debug` or `--verbose`)
30
+ - Provide utilities accessible in any command (like API clients or database connections)
31
+ - Modify how your CLI displays help text or handles errors
32
+ - Intercept command execution for logging or validation
33
+
34
+ The beauty of Gunshi's plugin system is that it handles all the complexity behind the scenes.
35
+
36
+ You simply declare which plugins you want to use, and they automatically become part of your CLI's capabilities.
37
+
38
+ Now that you understand how plugins work, let's explore the plugins that come with Gunshi.
39
+
40
+ These built-in plugins provide essential CLI functionality out of the box.
41
+
42
+ ## Built-in Plugins
43
+
44
+ Gunshi provides a standard `cli()` function that comes pre-configured with two essential plugins.
45
+
46
+ These built-in plugins give your CLI the familiar behavior users expect from command-line tools.
47
+
48
+ Let's explore what each plugin provides:
49
+
50
+ ### @gunshi/plugin-global
51
+
52
+ This plugin adds `--help` and `--version` options to all your commands automatically.
53
+
54
+ When either option is used, the plugin intercepts command execution to display the appropriate information.
55
+
56
+ The following example demonstrates how the cli() function automatically includes the global plugin:
57
+
58
+ ```js
59
+ import { cli, define } from 'gunshi'
60
+
61
+ const command = define({
62
+ name: 'app',
63
+ description: 'My CLI application',
64
+ run: ctx => {
65
+ console.log('Running application')
66
+ }
67
+ })
68
+
69
+ await cli(process.argv.slice(2), command, {
70
+ name: 'my-app',
71
+ version: '1.0.0'
72
+ })
73
+ ```
74
+
75
+ Now your CLI automatically supports:
76
+
77
+ - `my-app --help` displays usage information rendered by the renderer plugin
78
+ - `my-app --version` displays the version number
79
+ - The plugin decorates command execution to handle these options before your command runs
80
+
81
+ ### @gunshi/plugin-renderer
82
+
83
+ The renderer plugin automatically formats help text, usage information, and validation errors.
84
+
85
+ It works behind the scenes to ensure consistent, readable output across your entire CLI.
86
+
87
+ ## Using Optional Plugins
88
+
89
+ Optional plugins add specialized features to your CLI.
90
+
91
+ Install them separately and configure them based on your needs.
92
+
93
+ ### Internationalization
94
+
95
+ Add multi-language support with the i18n plugin:
96
+
97
+ ::: code-group
98
+
99
+ ```sh [npm]
100
+ npm install --save @gunshi/plugin-i18n
101
+ ```
102
+
103
+ ```sh [pnpm]
104
+ pnpm add @gunshi/plugin-i18n
105
+ ```
106
+
107
+ ```sh [yarn]
108
+ yarn add @gunshi/plugin-i18n
109
+ ```
110
+
111
+ ```sh [deno]
112
+ # For Deno projects, you can add Gunshi from JSR:
113
+ deno add jsr:@gunshi/plugin-i18n
114
+ ```
115
+
116
+ ```sh [bun]
117
+ bun add @gunshi/plugin-i18n
118
+ ```
119
+
120
+ :::
121
+
122
+ Here's a simple example using the `defineI18n` helper:
123
+
124
+ ```js
125
+ import { cli } from 'gunshi'
126
+ import i18n, { defineI18n, resolveKey } from '@gunshi/plugin-i18n'
127
+
128
+ // Define resources inline for each locale
129
+ const resources = {
130
+ 'en-US': {
131
+ greeting: 'Hello, {$name}!',
132
+ farewell: 'Goodbye!'
133
+ },
134
+ 'ja-JP': {
135
+ greeting: 'こんにちは、{$name}さん!',
136
+ farewell: 'さようなら!'
137
+ },
138
+ 'es-ES': {
139
+ greeting: '¡Hola, {$name}!',
140
+ farewell: '¡Adiós!'
141
+ }
142
+ }
143
+
144
+ const command = defineI18n({
145
+ name: 'greet',
146
+ description: 'Greet someone in their language',
147
+ // Resource function returns translations for the current locale
148
+ resource: async ctx => {
149
+ const locale = ctx.extensions['g:i18n'].locale
150
+ return resources[locale] || resources['en-US']
151
+ },
152
+ args: {
153
+ name: {
154
+ type: 'string',
155
+ required: true,
156
+ description: 'Name to greet'
157
+ }
158
+ },
159
+ run: ctx => {
160
+ // Access the i18n plugin extension via its namespaced ID 'g:i18n'
161
+ // (All Gunshi plugins use the 'g:' prefix to prevent naming conflicts)
162
+ const t = ctx.extensions['g:i18n'].translate
163
+ console.log(t(resolveKey('greeting', ctx), { name: ctx.values.name }))
164
+ console.log(t(resolveKey('farewell', ctx)))
165
+ }
166
+ })
167
+
168
+ await cli(process.argv.slice(2), command, {
169
+ name: 'greet-cli',
170
+ version: '1.0.0',
171
+ plugins: [
172
+ i18n({
173
+ locale: process.env.LANG || 'en-US'
174
+ })
175
+ ]
176
+ })
177
+ ```
178
+
179
+ <!-- eslint-disable markdown/no-missing-label-refs -->
180
+
181
+ > [!NOTE]
182
+ > Plugin IDs use namespacing to prevent conflicts and identify ownership. Official Gunshi plugins use the `g:` prefix (e.g., `g:i18n`, `g:completion`). When developing your own plugins, use your organization's namespace (e.g., `myorg:logger`) or scoped package format (e.g., `@company/auth`). For detailed naming conventions and guidelines, see the [Plugin ID Guidelines](../plugin/guidelines.md#plugin-ids).
183
+
184
+ <!-- eslint-enable markdown/no-missing-label-refs -->
185
+
186
+ Key benefits:
187
+
188
+ - The `defineI18n` helper simplifies i18n setup for commands
189
+ - Automatic locale detection from system settings
190
+ - Simple interpolation syntax for dynamic values
191
+ - Fallback to default locale when translation is missing
192
+ - Plugin functionality is accessible via `ctx.extensions` in your command runners
193
+
194
+ <!-- eslint-disable markdown/no-missing-label-refs -->
195
+
196
+ > [!NOTE]
197
+ > The `ctx.extensions` object is how plugins extend your command context with additional functionality. The i18n plugin adds translation capabilities through `ctx.extensions['g:i18n']`. To learn more about working with plugin extensions and best practices for accessing them, see the [Context Extensions guide](../advanced/context-extensions.md).
198
+
199
+ <!-- eslint-enable markdown/no-missing-label-refs -->
200
+
201
+ <!-- eslint-disable markdown/no-missing-label-refs -->
202
+
203
+ > [!TIP]
204
+ > This example demonstrates basic internationalization setup. For comprehensive coverage including external resource files, TypeScript support, dynamic locale switching, and production deployment strategies, see the [Advanced Internationalization Guide](../advanced/internationalization.md).
205
+
206
+ <!-- eslint-enable markdown/no-missing-label-refs -->
207
+
208
+ ### Shell Completion
209
+
210
+ Enable tab completion across different shells:
211
+
212
+ ::: code-group
213
+
214
+ ```sh [npm]
215
+ npm install --save @gunshi/plugin-completion
216
+ ```
217
+
218
+ ```sh [pnpm]
219
+ pnpm add @gunshi/plugin-completion
220
+ ```
221
+
222
+ ```sh [yarn]
223
+ yarn add @gunshi/plugin-completion
224
+ ```
225
+
226
+ :::
227
+
228
+ <!-- eslint-disable markdown/no-missing-label-refs -->
229
+
230
+ > [!IMPORTANT]
231
+ > Shell completion currently requires Node.js. The completion feature is not available when running your CLI with Deno or Bun runtimes.
232
+
233
+ <!-- eslint-enable markdown/no-missing-label-refs -->
234
+
235
+ Here's how to add completion support:
236
+
237
+ ```js
238
+ import { cli, define } from 'gunshi'
239
+ import completion from '@gunshi/plugin-completion'
240
+
241
+ const command = define({
242
+ name: 'deploy',
243
+ args: {
244
+ environment: {
245
+ type: 'string',
246
+ required: true,
247
+ description: 'Target environment'
248
+ }
249
+ },
250
+ run: ctx => {
251
+ console.log(`Deploying to ${ctx.values.environment}`)
252
+ }
253
+ })
254
+
255
+ await cli(process.argv.slice(2), command, {
256
+ name: 'deploy-cli',
257
+ version: '1.0.0',
258
+ plugins: [
259
+ completion({
260
+ config: {
261
+ entry: {
262
+ args: {
263
+ environment: {
264
+ handler: () => [
265
+ { value: 'production', description: 'Production' },
266
+ { value: 'staging', description: 'Staging' },
267
+ { value: 'development', description: 'Development' }
268
+ ]
269
+ }
270
+ }
271
+ }
272
+ }
273
+ })
274
+ ]
275
+ })
276
+ ```
277
+
278
+ The completion plugin adds a special `complete` command to your CLI that generates shell-specific completion scripts.
279
+
280
+ ### Installing Completion for End Users
281
+
282
+ Once you've added the completion plugin to your CLI, your users need to perform a one-time setup to enable tab completion on their system.
283
+
284
+ #### Basic Setup Example (Bash)
285
+
286
+ Users generate a completion script for their shell and add it to their shell configuration:
287
+
288
+ ```sh
289
+ # Generate completion script and save it
290
+ deploy-cli complete bash > ~/.local/share/bash-completion/completions/deploy-cli
291
+
292
+ # Reload your shell configuration
293
+ source ~/.bashrc
294
+
295
+ # Now tab completion works!
296
+ deploy-cli dep<TAB> # Completes to: deploy-cli deploy
297
+ ```
298
+
299
+ <!-- eslint-disable markdown/no-missing-label-refs -->
300
+
301
+ > [!TIP]
302
+ > For detailed setup instructions for all supported shells (Bash, Zsh, Fish, PowerShell), including directory creation and configuration steps, see the [@gunshi/plugin-completion README](https://github.com/kazupon/gunshi/tree/main/packages/plugin-completion#shell-completion-setup).
303
+
304
+ <!-- eslint-enable markdown/no-missing-label-refs -->
305
+
306
+ #### How It Works
307
+
308
+ The completion plugin adds a special `complete` command to your CLI that generates shell-specific completion scripts.
309
+
310
+ Users run this command once to generate the script for their shell, then source it in their shell configuration to enable tab completion.
311
+
312
+ ## Combining Plugins
313
+
314
+ Plugins work seamlessly together. Here's an example using both i18n and completion:
315
+
316
+ ```js
317
+ import { cli } from 'gunshi'
318
+ import i18n, { defineI18n, resolveKey } from '@gunshi/plugin-i18n'
319
+ import completion from '@gunshi/plugin-completion'
320
+
321
+ // Define your resources
322
+ const resources = {
323
+ 'en-US': {
324
+ start: 'Starting build for {$mode} mode...',
325
+ success: 'Build completed successfully!'
326
+ },
327
+ 'ja-JP': {
328
+ start: '{$mode}モードでビルドを開始しています...',
329
+ success: 'ビルドが正常に完了しました!'
330
+ }
331
+ }
332
+
333
+ const buildCommand = defineI18n({
334
+ name: 'build',
335
+ description: 'Build the project',
336
+ resource: async ctx => {
337
+ const locale = ctx.extensions['g:i18n'].locale
338
+ return resources[locale] || resources['en-US']
339
+ },
340
+ args: {
341
+ mode: {
342
+ type: 'string',
343
+ default: 'development',
344
+ description: 'Build mode'
345
+ }
346
+ },
347
+ run: ctx => {
348
+ const t = ctx.extensions['g:i18n'].translate
349
+ console.log(t(resolveKey('start', ctx), { mode: ctx.values.mode }))
350
+ // Build logic here
351
+ console.log(t(resolveKey('success', ctx)))
352
+ }
353
+ })
354
+
355
+ await cli(process.argv.slice(2), buildCommand, {
356
+ name: 'build-tool',
357
+ version: '2.0.0',
358
+ plugins: [
359
+ i18n({
360
+ locale: process.env.LANG || 'en-US'
361
+ }),
362
+ completion({
363
+ config: {
364
+ entry: {
365
+ args: {
366
+ mode: {
367
+ handler: () => [
368
+ { value: 'development', description: 'Development build' },
369
+ { value: 'production', description: 'Production build' }
370
+ ]
371
+ }
372
+ }
373
+ }
374
+ }
375
+ })
376
+ ]
377
+ })
378
+ ```
379
+
380
+ Both plugins enhance your CLI without interfering with each other - i18n handles translations while completion provides tab suggestions.
381
+
382
+ ## Plugin Configuration
383
+
384
+ Configure plugins based on your environment or user preferences.
385
+
386
+ ### Environment-based Configuration
387
+
388
+ Load plugins conditionally:
389
+
390
+ ```js
391
+ import { cli } from 'gunshi'
392
+
393
+ const plugins = []
394
+
395
+ // Add completion in development only
396
+ if (process.env.NODE_ENV === 'development') {
397
+ const completion = await import('@gunshi/plugin-completion')
398
+ plugins.push(completion.default())
399
+ }
400
+
401
+ // Add i18n if locale is set
402
+ if (process.env.LANG) {
403
+ const i18n = await import('@gunshi/plugin-i18n')
404
+ plugins.push(i18n.default({ locale: process.env.LANG }))
405
+ }
406
+
407
+ await cli(process.argv.slice(2), command, {
408
+ name: 'my-cli',
409
+ plugins
410
+ })
411
+ ```
412
+
413
+ This approach keeps your production builds lean while providing developer features during development.
414
+
415
+ ## Minimal Setup
416
+
417
+ If you need precise control over your CLI's functionality and bundle size, you can use `@gunshi/bone` - Gunshi's bare-bones foundation package.
418
+
419
+ Unlike the standard `cli()` function which includes plugins automatically, `@gunshi/bone` starts with zero plugins, letting you add only what you need:
420
+
421
+ ::: code-group
422
+
423
+ ```sh [npm]
424
+ npm install --save @gunshi/bone @gunshi/plugin-global @gunshi/plugin-renderer
425
+ ```
426
+
427
+ ```sh [pnpm]
428
+ pnpm add @gunshi/bone @gunshi/plugin-global @gunshi/plugin-renderer
429
+ ```
430
+
431
+ ```sh [yarn]
432
+ yarn add @gunshi/bone @gunshi/plugin-global @gunshi/plugin-renderer
433
+ ```
434
+
435
+ :::
436
+
437
+ ```js
438
+ import { cli } from '@gunshi/bone'
439
+ import global from '@gunshi/plugin-global'
440
+ import renderer from '@gunshi/plugin-renderer'
441
+
442
+ // Only includes plugins you explicitly add
443
+ await cli(process.argv.slice(2), command, {
444
+ name: 'minimal-cli',
445
+ plugins: [
446
+ global(), // Adds --help and --version options
447
+ renderer() // Adds help text formatting
448
+ ]
449
+ })
450
+ ```
451
+
452
+ This approach gives you explicit control over every aspect of your CLI, making it ideal for applications where bundle size or specific feature control is critical.
453
+
454
+ Common use cases for `@gunshi/bone`:
455
+
456
+ - Embedded CLIs with size constraints
457
+ - Custom implementations of help or version handling
458
+ - Testing plugin interactions in isolation
459
+ - Applications requiring precise control over all CLI behavior
460
+
461
+ ## Next Steps
462
+
463
+ Now that you understand the plugin system basics, you can explore more advanced topics and start building with Gunshi's plugin ecosystem.
464
+
465
+ To deepen your understanding of the plugin system:
466
+
467
+ - **TypeScript Support**: Explore type-safe plugin usage in the [Type System Guide](../advanced/type-system.md)
468
+ - **Context Extensions**: Learn how plugins extend functionality through [Context Extensions](../advanced/context-extensions.md)
469
+
470
+ Ready to create your own plugins?
471
+
472
+ - **Plugin Development**: Build custom plugins with the [Plugin Development Guide](../plugin/introduction.md)
@@ -0,0 +1,154 @@
1
+ # Type Safe
2
+
3
+ In the previous chapter, we learned how to create commands using declarative configuration with plain JavaScript objects.
4
+
5
+ While this approach works well, TypeScript users can benefit from enhanced type safety and better development experience using Gunshi's `define` function.
6
+
7
+ The `define` function wraps your command configuration and provides automatic type inference, ensuring that your command handlers receive properly typed context objects without manual type annotations.
8
+
9
+ ## Benefits of Type Safety
10
+
11
+ Using TypeScript with Gunshi's `define` function provides CLI-specific advantages:
12
+
13
+ - **Autocompletion for command options**: IDE suggests available options when accessing `ctx.values`
14
+ - **Prevent runtime errors**: Catch typos in option names before your CLI ships
15
+ - **Self-documenting commands**: Types show exactly what arguments your command accepts
16
+ - **Safe refactoring**: Rename options across your codebase with confidence
17
+
18
+ ## Type Safety Levels in Gunshi
19
+
20
+ Gunshi provides different levels of type safety to match your needs:
21
+
22
+ 1. **Basic type inference** (covered in this chapter): Automatic typing of command arguments
23
+ 2. **Plugin extension typing**: Type-safe access to plugin functionality
24
+ 3. **Full type parameters**: Complete control over all types using `GunshiParams`
25
+
26
+ This chapter focuses on the first level, which covers most common use cases. Advanced patterns are available when you need them.
27
+
28
+ ## Using `define` for Type Safety
29
+
30
+ The `define` function transforms your command configuration to provide:
31
+
32
+ - **Automatic type inference**: No need to manually type `ctx` parameters
33
+ - **IDE autocompletion**: Get suggestions for `ctx.values` properties
34
+ - **Compile-time validation**: TypeScript catches typos and type mismatches before runtime
35
+ - **Simplified imports**: No need to import type definitions like `Command` or `CommandContext`
36
+
37
+ Let's transform the greeting command from the previous chapter to use `define` for full type safety.
38
+
39
+ The `define` function is a simple wrapper that preserves your command's type information, enabling TypeScript to automatically infer types for your command options and provide IDE autocompletion:
40
+
41
+ ```ts [cli.ts]
42
+ import { cli, define } from 'gunshi'
43
+
44
+ // Define a command using the `define` function
45
+ const command = define({
46
+ name: 'greet',
47
+ args: {
48
+ // Define a string option 'name' with a short alias 'n'
49
+ name: {
50
+ type: 'string',
51
+ short: 'n',
52
+ description: 'Your name'
53
+ },
54
+ // Define a number option 'age' with a default value
55
+ age: {
56
+ type: 'number',
57
+ short: 'a',
58
+ description: 'Your age',
59
+ default: 30
60
+ },
61
+ // Define a boolean flag 'verbose'
62
+ verbose: {
63
+ type: 'boolean',
64
+ short: 'V',
65
+ description: 'Enable verbose output'
66
+ }
67
+ },
68
+ // The 'ctx' parameter is automatically typed based on the args
69
+ run: ctx => {
70
+ // `ctx.values` is fully typed!
71
+ const { name, age, verbose } = ctx.values
72
+
73
+ // TypeScript knows the types:
74
+ // - name: string | undefined (undefined if not provided)
75
+ // - age: number (always a number due to the default)
76
+ // - verbose: boolean | undefined (undefined if not provided, true if --verbose flag is used)
77
+
78
+ let greeting = `Hello, ${name || 'stranger'}!`
79
+ // age always has a value due to the default
80
+ greeting += ` You are ${age} years old.`
81
+
82
+ console.log(greeting)
83
+
84
+ if (verbose) {
85
+ console.log('Verbose mode enabled.')
86
+ console.log('Parsed values:', ctx.values)
87
+ }
88
+ }
89
+ })
90
+
91
+ // Execute the command
92
+ await cli(process.argv.slice(2), command)
93
+ ```
94
+
95
+ <!-- eslint-disable markdown/no-missing-label-refs -->
96
+
97
+ > [!TIP]
98
+ > The example fully code is [here](https://github.com/kazupon/gunshi/tree/main/playground/essentials/type-safe).
99
+
100
+ <!-- eslint-enable markdown/no-missing-label-refs -->
101
+
102
+ With `define`:
103
+
104
+ - You don't need to import types like `Command` or `CommandContext`.
105
+ - The `ctx` parameter in the `run` function automatically gets the correct type, derived from the `args` definition.
106
+ - Accessing `ctx.values.optionName` provides type safety and autocompletion based on the option's `type` and whether it has a `default`.
107
+ - Options without a `default` (like `name`) are typed as `T | undefined`.
108
+ - Options with a `default` (like `age`) are typed simply as `T`.
109
+ - Boolean flags without a `default` (like `verbose`) are typed as `boolean | undefined`.
110
+
111
+ <!-- eslint-disable markdown/no-missing-label-refs -->
112
+
113
+ > [!NOTE]
114
+ > For boolean options that need both positive and negative forms (e.g., `--verbose` and `--no-verbose`), see the [Negatable Boolean Options](./declarative.md#negatable-boolean-options) section in the declarative configuration guide.
115
+
116
+ <!-- eslint-enable markdown/no-missing-label-refs -->
117
+
118
+ This approach significantly simplifies creating type-safe CLIs with Gunshi.
119
+
120
+ ## When to Use `define`
121
+
122
+ Use the `define` function when:
123
+
124
+ - You're writing TypeScript and want automatic type inference
125
+ - You need IDE autocompletion for command context
126
+ - You want to catch type-related errors at compile time
127
+
128
+ Use plain objects (as shown in the previous chapter) when:
129
+
130
+ - You're writing plain JavaScript
131
+ - You prefer explicit type annotations
132
+ - You're integrating with existing type definitions
133
+
134
+ ## Advanced Type Parameters
135
+
136
+ While the examples above show the simplest form of the `define` function, Gunshi provides more advanced type parameter patterns for complex scenarios:
137
+
138
+ - **Plugin extensions**: Type-safe access to plugin-provided functionality
139
+ - **Explicit argument types**: Fine-grained control over type inference
140
+ - **GunshiParams utility**: Combined typing of arguments and extensions
141
+
142
+ These advanced patterns are covered in detail in the [Advanced Type System](../advanced/type-system.md) documentation.
143
+
144
+ For most commands, the basic `define` usage shown above provides sufficient type safety.
145
+
146
+ ## Next Steps
147
+
148
+ Now that you understand how to create type-safe commands with `define`, you're ready to explore more advanced features:
149
+
150
+ - **Composable Sub-commands**: Learn how type safety extends to multi-command CLIs
151
+ - **Plugin System**: Discover how plugins maintain type safety across extensions
152
+ - **Advanced Type System**: For complex scenarios, Gunshi offers additional type parameters and patterns (covered in the [Advanced Type System](../advanced/type-system.md) documentation)
153
+
154
+ In the next chapter, we'll explore how to create [composable sub-commands](./composable.md) while maintaining the type safety we've established here.
@@ -0,0 +1,68 @@
1
+ # Setup
2
+
3
+ Gunshi can be installed in various JavaScript environments. Choose the installation method that matches your project setup.
4
+
5
+ ## Install
6
+
7
+ ### Stable
8
+
9
+ ::: code-group
10
+
11
+ ```sh [npm]
12
+ npm install --save gunshi
13
+ ```
14
+
15
+ ```sh [pnpm]
16
+ pnpm add gunshi
17
+ ```
18
+
19
+ ```sh [yarn]
20
+ yarn add gunshi
21
+ ```
22
+
23
+ ```sh [deno]
24
+ # For deno projects, you can add Gunshi from JSR:
25
+ deno add jsr:@gunshi/gunshi
26
+ ```
27
+
28
+ ```sh [bun]
29
+ bun add gunshi
30
+ ```
31
+
32
+ :::
33
+
34
+ ### v0.27 Beta
35
+
36
+ ::: code-group
37
+
38
+ ```sh [npm]
39
+ npm install --save gunshi@beta
40
+ ```
41
+
42
+ ```sh [pnpm]
43
+ pnpm add gunshi@beta
44
+ ```
45
+
46
+ ```sh [yarn]
47
+ yarn add gunshi@beta
48
+ ```
49
+
50
+ ```sh [deno]
51
+ ## you can specify version with `@`
52
+ deno add jsr:@gunshi/gunshi@0.27.2
53
+ ```
54
+
55
+ ```sh [bun]
56
+ bun add gunshi@beta
57
+ ```
58
+
59
+ ## Requirements
60
+
61
+ Gunshi requires:
62
+
63
+ - **JavaScript Runtime**:
64
+ - **Node.js**: v20 or later
65
+ - **Deno**: v2 or later
66
+ - **Bun**: v1.1 or later
67
+ - **ES Modules**: `"type": "module"` in `package.json` (if using Node.js and Bun)
68
+ - **TypeScript**: Version 5.0 or higher (if using TypeScript)