oclif CLI Framework

website·Indexed 35 days ago

https://oclif.io/docs/

A framework for building command-line interfaces (CLIs) in Node.js. It provides tools for managing commands, flags, plugin resolution, and themes, with official support for ESM and CJS interoperability in @oclif/core version 3.0.0.

Tokens
22.2K
Snippets
124
Records
174
Agent score
72%

What's inside oclif

  1. Overview of the oclif CLI framework

    oclif is an open-source framework for building command line interfaces (CLIs) using Node.js and TypeScript. It supports everything from simple CLIs with a few flags to advanced CLIs with complex subcommand structures. The framework provides built-in functionality for argument parsing, command testing, and automatic documentation of CLI features. It also supports a plugin system, allowing developers and users to extend CLI functionality through modular, shareable plugins.
  2. Access CLI metadata and environment via this.config

    Inside an oclif command, this.config provides access to the Config class. This object contains metadata about the CLI, environment paths, and utility methods for managing scoped environment variables.
    // Example of accessing config properties within a command
    async run() {
      const version = this.config.version;
      const cacheDir = this.config.cacheDir;
      const platform = this.config.platform;
    }
  3. Understand CLI parameters: Arguments, Short Flags, and Long Flags

    When designing or using a CLI with oclif, parameters are data passed to the right of the command. There are three primary types based on GNU-style conventions:

    1. Arguments: Any value to the right of a command that is not a flag. They can appear before or after flags.
    2. Long Flags: Represented by two dashes (--) followed by multiple characters (e.g., --all). They are more readable and ideal for documentation.
    3. Short Flags: Represented by a single dash (-) followed by a single letter (e.g., -a). They are quicker to type and can be 'stacked' together (e.g., -la).
    # Argument
    ls .
    
    # Long Flag
    ls --all
    
    # Short Flag
    ls -a
    
    # Stacked Short Flags
    ls -la
  4. Generate a manifest for JIT plugins

    For JIT plugins to work, your build process must generate a manifest using the oclif manifest command. This manifest contains information about commands owned by JIT plugins, enabling users to run --help on those commands even before the plugin is installed. The generated manifest must be packed with the CLI distribution for the feature to function.
    oclif manifest
  5. Implement custom user experiences in oclif

    oclif follows a philosophy of minimal UX prescription, allowing developers to design their own user experiences. To achieve this, oclif provides hooks for common events (such as when a command is not found) and allows developers to override default error handling behavior. For basic UX needs, @oclif/core exports a ux module containing a set of utility tools.
  6. Understand ESM and CJS interoperability in oclif

    Starting with @oclif/core version 3.0.0, oclif officially supports ESM plugin development and CJS/ESM interoperability. This allows a root plugin written in CJS to use plugins written in ESM, and vice versa. Both ESM and CJS root plugins can install and link CJS and ESM plugins. However, for linked ESM plugins using ts-node as a dev dependency, auto-compilation is not supported; you must compile the plugin manually before execution. To enable runtime auto-compilation for linked ESM plugins, replace ts-node with tsx in your dev dependencies.
  7. Customize error handling with error delegation

    oclif supports custom error delegation, which allows developers to overwrite or interject in the default error handling process to change how errors are thrown and handled.
  8. Extend oclif CLI functionality using Plugins and Hooks

    oclif provides two primary extensibility mechanisms:

    1. Plugins: Used to add new functionality, modularize the CLI, or share functionality across multiple CLIs.
    2. Hooks: Lifecycle hooks that run functionality when the CLI starts or on custom triggers, allowing shared custom functionality across various CLI components.
  9. Generate auto-documentation for oclif commands

    oclif automatically generates help information (including flag options and argument details) when a user passes the --help flag to a command. This information is also automatically added to the project's README when the npm package is published.
  10. Develop oclif CLIs with TypeScript or JavaScript

    oclif supports both TypeScript and plain JavaScript. The CLI generator can scaffold either version. When using plugins, oclif utilizes ts-node to run TypeScript plugins with minimal boilerplate.
  11. Create and reuse custom shared flags

    For large CLIs, you can define a custom flag using Flags.custom<T>() in a separate file. This allows you to share the flag definition, including complex default logic or type casting, across multiple commands. When using the custom flag in a command, you can still override or add specific properties like required.
    // src/flags.ts
    import {Flags} from '@oclif/core'
    
    class Team {
      public name: string;
    }
    
    function getTeam(): Promise<Team> {
      return new Team();
    }
    
    export const team = Flags.custom<Team>({
      char: 't',
      description: 'team to use',
      default: async () => getTeam(),
    })
    
    // src/commands/mycommand.ts
    import {team} from '../flags'
    import {Command} from '@oclif/core'
    
    export class MyCLI extends Command {
      static flags = {
        team: team({
          required: true,
        }),
      }
    
      async run() {
        const {flags} = await this.parse(MyCLI)
        if (flags.team) console.log(`--team is ${flags.team.name}`)
      }
    }