meta_desc: "Learn how to create a Pulumi Package: create a Native Provider, author a Component, or bridge a Terraform provider into the Pulumi ecosystem."
This how-to guide will take you step-by-step through the tasks required to author and publish a Pulumi Package. You can use this guide to create any [type of Pulumi Package](/docs/guides/pulumi-packages#types-of-pulumi-packages): a Native Provider, a provider bridged from an existing Terraform provider, or a Component. This guide assumes you're using GitHub to host your package's source code and GitHub Actions to publish various parts of your package.
- Pulumi Packages are multi-language: you can write your package once in either Go, Python, or TypeScript/JavaScript and then make it available to all Pulumi users, even if they use another language. To develop them, you need to have Git, Go, .NET, Python, and TypeScript installed on your system.
- To follow the whole guide, you need a GitHub account. However, using GitHub is not a requirement; you may still find this guide useful even if you use another system to store your source code.
## Create a repository
To get started, create a repository for your Pulumi Package. We recommend hosting your Pulumi Package in a public repository on GitHub. We also recommend following the naming conventions below to help the community find the source code for your packages.
### Select a template
To get started, click the link for the boilerplate repository template that you want to use, then click "Use this template" to make a copy of it.
- Author a **Native Provider** with [`pulumi/pulumi-provider-boilerplate`](https://github.com/pulumi/pulumi-provider-boilerplate)
- Author a **Bridged Provider** with [`pulumi/pulumi-tf-provider-boilerplate`](https://github.com/pulumi/pulumi-tf-provider-boilerplate)
- The name should start with `pulumi-`, like our [`pulumi-aws-native`](/registry/packages/aws-native) AWS Native Provider and our [`pulumi-eks`](/registry/packages/eks) Component for AWS Elastic Kubernetes Service (EKS)
- If you're naming a **native provider**, use the cloud provider's name and the suffix `-native`, like our [`pulumi-azure-native`](/registry/packages/azure-native) Azure Native Provider
- If you're naming a **component**, name your package using both the cloud provider whose resources you're building on top of and the resources, like our [`pulumi-aws-apigateway`](/registry/packages/aws-apigateway) Component for AWS API Gateway
We recommend authoring documentation to help others in the Pulumi community use your package. In your repository, there should be a `docs/` folder with a few template pages you can use that correspond to the various tabs on a package page in Pulumi Registry (like the [AWS Native](/registry/packages/aws-native/) package). Use the guidance in the following sections to author content in these pages.
1.`_index.md`, which will be shown on the Overview tab for your package. The title of this page should match the package display name and is the heading shown on the package detail page. The Overview is a great place to include a description of what your package does, a simple example, and any other details that you want prospective users of your package to know to be successful.
1.`installation-configuration.md`, which will be shown on your package's Installation & Configuration tab. Use this page to describe how to set up your package, including authenticating to a cloud provider, and to list the configuration options that can be used with your package. The title of this page should be in the form `<Package display name> Installation & Configuration`.
Metadata for your package is generated from the [`schema.json`](/docs/using-pulumi/pulumi-packages/schema) in your repository. To make sure your package looks great in Pulumi Registry, ensure you add metadata like:
-`displayName`: the friendly name for your package displayed on the Registry's browse page; this name should match the title of the `_index.md` file.
-`description`: a short description of your package; it should include the package name
-`logoUrl`: a web-accessible URL to a logo for your package (ideally an SVG); we recommend using the githubrawcontent.com URL for a logo stored in your package's repository; all surrounding whitespace should be removed from the logo, and wordmarks are preferred
-`pluginDownloadURL`: a web-accessible URL that contains the compiled binary plugin associated with your package; for more information see [Publish your package](#publish-your-package)
{{% notes %}}
Pulumi will interpolate `${VERSION}`, `${OS}` and `${ARCH}` with their respective values if found in `pluginDownloadURL`.
API docs for your package are automatically generated from the `schema.json` in your repository. Many Pulumi users learn to use a Pulumi Package via the API docs, since they appear automatically in many IDEs' auto-complete and inline documentation features, like Visual Studio Code's IntelliSense feature. Investing in API docs for your package is one of the best ways to improve its usability. Check out the [`pulumi-eks` schema](https://github.com/pulumi/pulumi-eks/blob/master/provider/cmd/pulumi-resource-eks/schema.json) and how it translates to [Pulumi Registry](/registry/packages/eks/api-docs/) for an example of great API docs.
You can also create how-to guides for your packages by contributing them to the [`pulumi/examples`](https://github.com/pulumi/examples) repository on GitHub.
## Publish your package
Once you've authored and tested your package locally, you can publish it to make it available to the Pulumi community. You must publish several artifacts:
- The npm, NuGet, Java, and Python SDK packages to the [npm Registry](https://npmjs.com), the [NuGet Gallery](https://nuget.org), [Maven Central](https://central.sonatype.com) and the [Python Package Index](https://pypi.org)
- If your package is hosted on GitHub, you may choose to use our [custom Action for publishing Pulumi packages](https://github.com/pulumi/pulumi-package-publisher)
- The [package documentation](#publish-the-documentation) - overview, installation & configuration, API docs, and how-to guides to [Pulumi Registry](/registry/)
Since [release 3.35.3](https://github.com/pulumi/pulumi/releases/tag/v3.35.3), Pulumi understands a special form of `pluginDownloadURL` to download plugins via GitHub releases
```
github://${github api host}/{organization}[/{repository}]
```
-`github api host`: the address of a GitHub API, for `github.com` this is `api.github.com`
-`organization`: the GitHub organization to use
-`repository`: the GitHub repository to use, this defaults to `pulumi-${package name}`
For example the [Pulumiverse Astra](https://github.com/pulumiverse/pulumi-astra) package would specify `github://api.github.com/pulumiverse`.
Since [release 3.56.0](https://github.com/pulumi/pulumi/releases/tag/v3.56.0), Pulumi understands a special form of `pluginDownloadURL` to download plugins via Gitlab releases
```
gitlab://${gitlab api host}/{<project_id>}
```
-`gitlab api host`: the address of a Gitlab API, for Gitlab SaaS this is `gitlab.com`
-`project_id`: the Gitlab project ID to use. The project ID can be found right below the project name on the project page.
All package documentation on Pulumi Registry is published via the [`pulumi/registry` repository on GitHub](https://github.com/pulumi/registry). To publish your package on Pulumi Registry:
1. Fork and clone the [`pulumi/registry` repository](https://github.com/pulumi/registry).
1. Add your package to [the community package list](https://github.com/pulumi/registry/blob/master/community-packages/package-list.json)
1. Add your package's GitHub repo slug, e.g. `"checkly/pulumi-checkly"`
1. Add the path to your package's `schema.json` file from the root of your provider repository, e.g. `"provider/cmd/pulumi-resource-checkly/schema.json"`
1. Open a pull request with the above changes and await review from a Pulumi team member.
API docs for your package will be automatically generated at the time of building the registry site. You do not need to take any action to generate API docs other than make sure your package repository has the right `schema.json` (or `.yaml`).