Skip to main content

Writing a Podman Desktop extension

To write a Podman Desktop extension, start a Node.js or TypeScript project calling the Podman Desktop API, and ensure all runtime dependencies are inside the final binary.

Initializing a Podman Desktop extension

Write the Podman Desktop extension Node.js package metadata.

Prerequisites

  • JavaScript or TypeScript

Procedure

  1. Create and edit a package.json file.

    {}
  2. Add TypeScript and Podman Desktop API to the development dependencies:

     "devDependencies": {
    "@podman-desktop/api": "latest",
    "typescript": "latest"
    },
  3. Add the required metadata:

      "name": "my-extension",
    "displayName": "My Hello World extension",
    "description": "How to write my first extension",
    "version": "0.0.1",
    "icon": "icon.png",
    "publisher": "benoitf",
  4. Add the Podman Desktop version that might run this extension:

      "engines": {
    "podman-desktop": "latest"
    },
  5. Add the main entry point:

     "main": "./dist/extension.js"
  6. Add a Hello World command contribution

      "contributes": {
    "commands": [
    {
    "command": "my.first.command",
    "title": "My First Extension: Hello World"
    }
    ]
    }
  7. Add an icon.png file to the project.

Verification

  • Full package.json example:

    {
    "devDependencies": {
    "@podman-desktop/api": "latest",
    "typescript": "latest"
    },
    "name": "my-extension",
    "displayName": "My Hello World extension",
    "description": "How to write my first extension",
    "version": "0.0.1",
    "icon": "icon.png",
    "publisher": "benoitf",
    "engines": {
    "podman-desktop": "latest"
    },
    "main": "./dist/extension.js",
    "contributes": {
    "commands": [
    {
    "command": "my.first.command",
    "title": "My First Extension: Hello World"
    }
    ]
    }
    }

Writing a Podman Desktop extension entry point

Write the extension features.

Prerequisites

  • JavaScript or TypeScript

Procedure

  1. Create and edit a dist/extension.js file.

  2. Import the Podman Desktop API

    import * as podmanDesktopAPI from '@podman-desktop/api';
  3. Expose the activate function to call on activation.

    The signature of the function can be:

    • Synchronous

      export function activate(): void;
    • Asynchronous

      export async function activate(): Promise<void>;
  4. (Optional) Add an extension context to the activate function enabling the extension to register disposable resources:

    export async function activate(extensionContext: podmanDesktopAPI.ExtensionContext): Promise<void> {}
  5. Register the command and the callback

    import * as podmanDesktopAPI from '@podman-desktop/api';
    export async function activate(extensionContext: podmanDesktopAPI.ExtensionContext): Promise<void> {
    // register the command referenced in package.json file
    const myFirstCommand = podmanDesktopAPI.commands.registerCommand('my.first.command', async () => {
    // display a choice to the user for selecting some values
    const result = await podmanDesktopAPI.window.showQuickPick(['un', 'deux', 'trois'], {
    canPickMany: true, // user can select more than one choice
    });

    // display an information message with the user choice
    await podmanDesktopAPI.window.showInformationMessage(`The choice was: ${result}`);
    });

    // create an item in the status bar to run our command
    // it will stick on the left of the status bar
    const item = podmanDesktopAPI.window.createStatusBarItem(podmanDesktopAPI.StatusBarAlignLeft, 100);
    item.text = 'My first command';
    item.command = 'my.first.command';
    item.show();

    // register disposable resources to it's removed when we deactivte the extension
    extensionContext.subscriptions.push(myFirstCommand);
    extensionContext.subscriptions.push(item);
    }
  6. (Optional) Expose the deactivate function to call on deactivation.

    The signature of the function can be:

    • Synchronous

      export function deactivate(): void;
    • Asynchronous

      export async function deactivate(): Promise<void>;

Verification

  • The extension compiles and produces the output in the dist folder.

  • All runtime dependencies are inside the final binary.

Additional resources

  • Consider a packer such as Rollup or Webpack to shrink the size of the artifact.

Next steps