# Packages

Packages in dex allow you to install and reuse pre-built transformations, macros, tests, and configurations from other projects. They enable modular development and help your team avoid reinventing the wheel by sharing business logic, analytics standards, and utilities across teams and projects.

Packages are especially useful for:

* Centralizing logic used across multiple projects
* Importing open-source utilities (like testing libraries or macros)
* Keeping your main project codebase clean and focused

Packages are installed using a `packages.yml` file at the root of your project.

### Installing a Package

To install a package in dex:

1. Open or create a file called `packages.yml` at the root of your repository
2. Add the package name, version, and source (typically a GitHub URL or the dbt Hub registry)
3. Save and commit your changes
4. dex will automatically install and resolve the packages the next time you run or build

#### Example using an open-source package

```yaml
packages:
  - package: calogica/dbt_expectations
    version: 0.9.0
```

This installs the `dbt_expectations` package, giving you access to expressive testing macros inspired by Great Expectations.

### Using a Package

Once installed, you can use any of the macros, tests, or seeds defined in the package as if they were part of your own project.

#### Example usage of a macro from a package:

```sql
{{ dbt_expectations.expect_column_values_to_be_between(
    model=ref('orders'),
    column='order_value',
    min_value=0,
    max_value=10000
) }}

```

Packages also allow you to override macros or variables locally if needed.

### Managing Package Versions

You should always pin a specific version of a package using the `version:` key to ensure reproducibility.

To upgrade a package:

* Change the version in `packages.yml`
* Save and commit
* dex will install the new version on your next run or build

### Creating Your Own Package

You can also turn any dex project into a reusable package. This is useful if your organization wants to standardize logic across teams.

To make a project installable as a package:

* Publish the project to a Git repository
* Ensure it has a valid `dbt_project.yml` and `packages.yml`
* Reference it from another project like this:

```yaml
packages:
  - git: "https://github.com/my-org/dex-core-package.git"
    revision: main
```

You can use any Git revision format: `main`, a tag, or a commit hash.

### Example Project Structure

```
├── models/
├── macros/
├── packages.yml      ← Defines installed packages
├── dbt_project.yml
└── snapshots/
```

### Best Practices

* Use packages to separate shared logic from domain-specific transformations
* Always pin versions in `packages.yml`
* Document what each package is used for and link to its source
* Avoid modifying installed package code directly—override via macros or variables instead
* Keep custom packages lean and focused
