Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tuist/tuist/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The tuist plugin command provides tools for plugin development and management. Plugins extend Tuist’s functionality with custom tasks and integrations.

Usage

tuist plugin [subcommand] [options]

Subcommands

tuist plugin archive

Archives a plugin into a NameOfPlugin.tuist-plugin.zip file for distribution.
tuist plugin archive [options]

tuist plugin build

Builds a plugin.
tuist plugin build [options]

tuist plugin run

Runs a plugin task.
tuist plugin run [options] <task> [arguments...]

tuist plugin test

Tests a plugin.
tuist plugin test [options]

Common Options

--path
string
default:"."
The path to the directory that contains the definition of the plugin.
-p
string
Short form of --path.
--configuration
string
default:"debug"
Choose configuration: debug or release.
-c
string
Short form of --configuration.

Options (for plugin archive)

--path
string
default:"."
The path to the directory that contains the definition of the plugin.
-p
string
Short form of --path.

Options (for plugin build)

--build-tests
boolean
default:"false"
Build both source and test targets.
--show-bin-path
boolean
default:"false"
Print the binary output path.
--targets
string[]
Build the specified targets.
--products
string[]
Build the specified products.

Options (for plugin run)

--build-tests
boolean
default:"false"
Build both source and test targets.
--skip-build
boolean
default:"false"
Skip building the plugin before running.

Arguments (for plugin run)

task
string
required
The plugin task to run.
arguments
string[]
The arguments to pass to the plugin task.

Options (for plugin test)

--build-tests
boolean
default:"false"
Build both source and test targets.
--test-products
string[]
Test the specified products.

Examples

Build a plugin

tuist plugin build
Builds the plugin in debug configuration.

Build plugin in release mode

tuist plugin build --configuration release
Builds an optimized release version of the plugin.

Build specific targets

tuist plugin build --targets MyTask AnotherTask
Builds only the specified plugin targets.

Run a plugin task

tuist plugin run my-task --arg1 value1 --arg2 value2
Executes the my-task plugin task with arguments.

Run without building

tuist plugin run my-task --skip-build
Runs the task without rebuilding the plugin first.

Test a plugin

tuist plugin test
Runs all tests for the plugin.

Test specific products

tuist plugin test --test-products MyTaskTests
Runs tests only for the specified test products.

Archive a plugin

tuist plugin archive
Creates a distributable .tuist-plugin.zip archive.

Archive from specific path

tuist plugin archive --path path/to/plugin
Archives a plugin located in a specific directory.

Plugin development workflow

1. Create a plugin

Plugins are Swift packages that define custom tasks:
import ProjectAutomation

let plugin = Plugin(
    name: "MyPlugin",
    products: [
        .task(name: "my-task", target: "MyTask")
    ],
    targets: [
        .target(
            name: "MyTask",
            dependencies: [.product(name: "ProjectAutomation", package: "tuist")]
        )
    ]
)

2. Implement tasks

Create executable targets for your tasks:
import Foundation
import ProjectAutomation

@main
struct MyTask {
    static func main() async throws {
        // Your task logic here
        print("Running custom task")
    }
}

3. Build and test

Develop your plugin iteratively:
# Build the plugin
tuist plugin build

# Test the plugin
tuist plugin test

# Run the plugin task
tuist plugin run my-task

4. Archive and distribute

When ready to share:
tuist plugin archive
This creates a .tuist-plugin.zip file you can distribute.

Plugin types

Task plugins

Executable tasks that extend Tuist functionality:
.task(name: "format", target: "FormatTask")

Helper plugins

Libraries that provide reusable code:
.library(name: "HelperKit", target: "HelperKit")

Using plugins

Reference plugins in your Tuist.swift or Project.swift:
import ProjectDescription

let config = Config(
    plugins: [
        .git(url: "https://github.com/org/plugin", tag: "1.0.0"),
        .local(path: "../MyLocalPlugin")
    ]
)

Configuration options

Debug vs. Release

  • Debug: Faster builds, includes debug symbols
  • Release: Optimized builds, smaller binaries
tuist plugin build --configuration release

Build tests

Include test targets in the build:
tuist plugin build --build-tests

Show binary path

Useful for integrating with other tools:
tuist plugin build --show-bin-path

Best practices

Small, focused tasks

Create plugins for specific, reusable tasks rather than monolithic tools.

Test thoroughly

Use tuist plugin test to ensure reliability before distribution.

Version plugins

Use semantic versioning and git tags for plugin releases.

Document tasks

Provide clear documentation for task arguments and usage.

Common plugin use cases

Code generation

Generate boilerplate code, models, or templates:
tuist plugin run generate-model --name User --fields "name:String,age:Int"

Code formatting

Format code using custom rules:
tuist plugin run format

Integration with tools

Integrate third-party tools into your workflow:
tuist plugin run analyze --tool swiftlint

Custom validations

Validate project structure or conventions:
tuist plugin run validate-architecture

Plugin development tips

Access project information

Use ProjectAutomation framework to access project data:
import ProjectAutomation

let project = try await Project.load(at: path)
print("Project: \(project.name)")

Handle arguments

Parse task arguments using Swift’s ArgumentParser:
import ArgumentParser
import ProjectAutomation

@main
struct MyTask: AsyncParsableCommand {
    @Option(help: "The name to use")
    var name: String
    
    func run() async throws {
        print("Hello, \(name)!")
    }
}

Error handling

Provide clear error messages:
enum PluginError: Error {
    case invalidConfiguration(String)
    case taskFailed(String)
}

throw PluginError.invalidConfiguration("Missing required field")

Build docs developers (and LLMs) love