---
title: Projects
url: /docs/iac/concepts/projects/
---
A Pulumi project is any folder that contains a `Pulumi.yaml` project file. At runtime, the nearest parent folder containing a `Pulumi.yaml` file determines the current project. Projects are created with the [`pulumi new`](/docs/iac/cli/commands/pulumi_new/) command.

## The project file (Pulumi.yaml) {#pulumi-yaml}

The project file specifies which runtime to use and determines where to look for the program that should be executed during deployments. Supported runtimes are `nodejs`, `python`, `dotnet`, `go`, `java`, and `yaml`.

Project files also contain metadata about your project. The project file must begin with a capital `P`, although either `.yml` or `.yaml` extension will work.

A typical `Pulumi.yaml` file looks like the following:

```yaml
name: webserver
runtime: nodejs
description: A minimal JavaScript Pulumi program.
```

In addition, when using JavaScript or TypeScript, the working directory for the project should contain a `package.json` file that points to an entrypoint such as `index.js`. In Python, the presence of a `__main__.py` or `setup.py` file defines the entrypoint.

The following are other examples of `Pulumi.yaml` files that define project configurations for other use cases:

* A `Pulumi.yaml` file for a Node.js program that uses JavaScript rather than TypeScript:

```yaml
    name: my-project
    runtime:
      name: nodejs
      options:
        typescript: false
    ```

* A `Pulumi.yaml` file for a Go program that uses a pre-built executable named `mybinary`:

```yaml
    name: my-project
    description: A precompiled Go Pulumi program.
    runtime:
      name: go
      options:
        binary: mybinary
    ```

* A `Pulumi.yaml` file for a .NET program that uses a pre-built assembly named `MyInfra.dll` in the `bin` directory:

```yaml
    name: my-project
    description: A precompiled .NET Pulumi program.
    runtime:
      name: dotnet
      options:
        binary: bin/MyInfra.dll

    ```

* A `Pulumi.yaml` file for a Java program that uses a pre-built JAR file:

```yaml
    name: my-project
    description: A precompiled Java Pulumi program.
    runtime:
        name: java
        options:
            binary: target/my-project-1.0-SNAPSHOT-jar-with-dependencies.jar
    ```

* A `Pulumi.yaml` file for a `YAML` program that includes its resources inline:

```yaml
    name: my-project
    runtime: yaml
    resources:
      bucket:
        type: aws:s3:Bucket
    ```

For more information on valid Pulumi project metadata, see the [Pulumi.yaml reference](/docs/reference/pulumi-yaml/).

## Project-relative paths

When your Pulumi program refers to resources in the local filesystem, paths are always relative to the working directory. In the following example, the `aws.ecr.Image` resource refers to a subfolder of the working directory named `app` that contains a `Dockerfile`:

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
import * as pulumi from "@pulumi/pulumi";
import * as awsx from "@pulumi/awsx";

const repository = new awsx.ecr.Repository("repository", {
    forceDelete: true,
});

const image = new awsx.ecr.Image("image", {
    repositoryUrl: repository.url,
    context: "./app",
    platform: "linux/amd64",
});

export const url = repository.url;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-ecr-image-typescript)

<!-- /option -->

<!-- option: python -->

```python
import pulumi
import pulumi_awsx as awsx

repository = awsx.ecr.Repository("repository", force_delete=True)

image = awsx.ecr.Image(
    "image",
    repository_url=repository.url,
    context="./app",
    platform="linux/amd64",
)

pulumi.export("url", repository.url)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-ecr-image-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"github.com/pulumi/pulumi-awsx/sdk/v3/go/awsx/ecr"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		repository, err := ecr.NewRepository(ctx, "repository", &ecr.RepositoryArgs{
			ForceDelete: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}

		_, err = ecr.NewImage(ctx, "image", &ecr.ImageArgs{
			RepositoryUrl: repository.Url,
			Context:       pulumi.String("./app"),
			Platform:      pulumi.String("linux/amd64"),
		})
		if err != nil {
			return err
		}

		ctx.Export("url", repository.Url)
		return nil
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-ecr-image-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿using System.Collections.Generic;
using Pulumi;
using Awsx = Pulumi.Awsx;

return await Deployment.RunAsync(() =>
{
    var repository = new Awsx.Ecr.Repository("repository", new()
    {
        ForceDelete = true,
    });

    var image = new Awsx.Ecr.Image("image", new()
    {
        RepositoryUrl = repository.Url,
        Context = "./app",
        Platform = "linux/amd64",
    });

    return new Dictionary<string, object?>
    {
        ["url"] = repository.Url,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-ecr-image-csharp)

<!-- /option -->

<!-- option: java -->

```java
package myproject;

import com.pulumi.Context;
import com.pulumi.Pulumi;
import com.pulumi.awsx.ecr.Repository;
import com.pulumi.awsx.ecr.RepositoryArgs;
import com.pulumi.awsx.ecr.Image;
import com.pulumi.awsx.ecr.ImageArgs;

public class App {
    public static void main(String[] args) {
        Pulumi.run(App::stack);
    }

    public static void stack(Context ctx) {
        var repository = new Repository("repository", RepositoryArgs.builder()
            .forceDelete(true)
            .build());

        var image = new Image("image", ImageArgs.builder()
            .repositoryUrl(repository.url())
            .context("./app")
            .platform("linux/amd64")
            .build());

        ctx.export("url", repository.url());
    }
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-ecr-image-java)

<!-- /option -->

<!-- option: yaml -->

```yaml
name: awsx-ecr-image-yaml
runtime: yaml

resources:
  repository:
    type: awsx:ecr:Repository
    properties:
      forceDelete: true

image:
  type: awsx:ecr:Image
  properties:
    repositoryUrl: ${repository.url}
    context: "./app"
    platform: "linux/amd64"

outputs:
  url: ${repository.url}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-ecr-image-yaml)

<!-- /option -->

<!-- /chooser -->

## Root-relative paths

You can get the directory containing the `Pulumi.yaml` file, which may differ from your working directory if it specified a `main` option (see [main attribute](/docs/reference/pulumi-yaml/#attributes)), with the `ProjectDirectory` function.

The path returned is an absolute path. When using this in resource properties, ensure it's relative to the working directory. This prevents diffs from running the project on multiple machines with different roots.

<!-- chooser: language -->

<!-- option: typescript -->

```typescript
import * as awsx from "@pulumi/awsx";
import * as pulumi from "@pulumi/pulumi";
import { join, relative } from "path";

const root = pulumi.getRootDirectory();
const cwd = process.cwd();
const appPath = join(root, "app");
const relativePath = relative(cwd, appPath);

const repository = new awsx.ecr.Repository("repository", {
    forceDelete: true,
});

const image = new awsx.ecr.Image("image", {
    repositoryUrl: repository.url,
    context: relativePath,
    platform: "linux/amd64",
});

export const url = repository.url;

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-root-directory-typescript)

<!-- /option -->

<!-- option: python -->

```python
import pulumi
import pulumi_awsx as awsx
import os

root = pulumi.get_root_directory()
cwd = os.getcwd()
app_path = os.path.join(root, "app")
relative_path = os.path.relpath(app_path, cwd)

repository = awsx.ecr.Repository("repository", force_delete=True)

image = awsx.ecr.Image(
    "image",
    repository_url=repository.url,
    context=relative_path,
    platform="linux/amd64",
)

pulumi.export("url", repository.url)

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-root-directory-python)

<!-- /option -->

<!-- option: go -->

```go
package main

import (
	"os"
	"path/filepath"

	"github.com/pulumi/pulumi-awsx/sdk/v3/go/awsx/ecr"
	"github.com/pulumi/pulumi/sdk/v3/go/pulumi"
)

func main() {
	pulumi.Run(func(ctx *pulumi.Context) error {
		root := ctx.RootDirectory()
		cwd, err := os.Getwd()
		if err != nil {
			return err
		}
		path := filepath.Join(root, "app")
		path, err = filepath.Rel(cwd, path)
		if err != nil {
			return err
		}

		repository, err := ecr.NewRepository(ctx, "repository", &ecr.RepositoryArgs{
			ForceDelete: pulumi.Bool(true),
		})
		if err != nil {
			return err
		}

		_, err = ecr.NewImage(ctx, "image", &ecr.ImageArgs{
			RepositoryUrl: repository.Url,
			Context:       pulumi.String(path),
			Platform:      pulumi.String("linux/amd64"),
		})
		if err != nil {
			return err
		}

		ctx.Export("url", repository.Url)
		return nil
	})
}

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-root-directory-go)

<!-- /option -->

<!-- option: csharp -->

```csharp
﻿using System.Collections.Generic;
using System.IO;
using Pulumi;
using Awsx = Pulumi.Awsx;

return await Deployment.RunAsync(() =>
{
    var root = Pulumi.Deployment.Instance.RootDirectory;
    var cwd = Directory.GetCurrentDirectory();
    var appPath = Path.Combine(root, "app");
    var relativePath = Path.GetRelativePath(cwd, appPath);

    var repository = new Awsx.Ecr.Repository("repository", new()
    {
        ForceDelete = true,
    });

    var image = new Awsx.Ecr.Image("image", new()
    {
        RepositoryUrl = repository.Url,
        Context = relativePath,
        Platform = "linux/amd64",
    });

    return new Dictionary<string, object?>
    {
        ["url"] = repository.Url,
    };
});

```

[View full example on GitHub](https://github.com/pulumi/docs/tree/master/static/programs/awsx-root-directory-csharp)

<!-- /option -->

<!-- /chooser -->

## Getting the current project programmatically

The <!-- chooser: language -->
<!-- option: javascript -->
[`getProject`](/docs/reference/pkg/nodejs/pulumi/pulumi#getProject)
<!-- /option -->
<!-- option: typescript -->
[`getProject`](/docs/reference/pkg/nodejs/pulumi/pulumi#getProject)
<!-- /option -->
<!-- option: python -->
[`get_project`](/docs/reference/pkg/python/pulumi/#pulumi.get_project)
<!-- /option -->
<!-- option: go -->
[`context.Project`](https://godoc.org/github.com/pulumi/pulumi/sdk/v3/go/pulumi#Context.Project)
<!-- /option -->
<!-- option: csharp -->
[`Deployment.Instance.ProjectName`](/docs/reference/pkg/dotnet/pulumi/pulumi.deploymentinstance.html#Pulumi_DeploymentInstance_ProjectName)
<!-- /option -->
<!-- option: java -->
`context.projectName()`
<!-- /option -->
<!-- option: yaml -->
[`pulumi.project`](/docs/languages-sdks/yaml/yaml-language-reference/#built-in-variables)
<!-- /option -->
<!-- /chooser -->
 function returns the name of the currently deploying project. This can be useful for naming or tagging resources.

<!-- chooser: language -->

<!-- option: typescript -->
```typescript
const project = pulumi.getProject();

```

<!-- /option -->

<!-- option: python -->
```python
project = pulumi.get_project()

```

<!-- /option -->

<!-- option: go -->
```go
project := ctx.Project()

```

<!-- /option -->

<!-- option: csharp -->
```csharp
var project = Deployment.Instance.ProjectName;

```

<!-- /option -->

<!-- option: java -->
```java
var project = ctx.projectName();

```

<!-- /option -->

<!-- option: yaml -->
```yaml
variables:
  project: ${pulumi.project}

```

<!-- /option -->

<!-- /chooser -->

## Stack settings files {#stack-settings-file}

Each stack that is created in a project will have a file named `Pulumi.<stackname>.yaml` that contains the configuration specific to this stack. This file typically resides in the root of the project directory.

For stacks that are actively developed by multiple members of a team, the recommended practice is to check them into source control as a means of collaboration. Since secret values are encrypted, it is safe to check in these stack settings. When using ephemeral stacks, the stack settings are typically not checked into source control.

For more information about configuration and how to manage these files on the command line and programmatically, refer to the [Configuration](/docs/concepts/config/) and [Secrets](/docs/concepts/secrets/) documentation.
